Bootstrap

java 窗口制作

入口

package com.enter;
class window

package com.enter;

import com.frame.enterFrame;

/**
 * 程序入口
 */
public class window {
    public static void main(String[] args) {
        //创建窗口
        new enterFrame();
    }
}


单个窗口

开发文档

  1. 窗口初始化
  • 设置标题
  • 窗口大小
  • 窗口坐标
  • 窗口事件的监听
    关闭窗口事件的处理

package com.frame;
class enterFrame

package com.frame;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

//静态导入常量类
import static com.data.Constant.*;

/**
 * 窗口
 * 窗口无法通过代码直接实现,所以从Java中继承已有窗口类
 */
public class enterFrame extends Frame {
    //对窗口初始化
    public enterFrame() {
        initFrame();
        initEventListner();
    }

    //对窗口属性初始化
    private void initFrame() {
        /**
         * 设置窗口标题(左上角内容)
         * setTitle("窗口界面");可以直接使用常量,但是不推荐。因为不利于后期更改
         * 所以创建一个常量类来管理所有常量,然后静态调用
         */
        setTitle(WINDOW_TITLE);

        //设置窗口大小
        setSize(FRAME_WIDTH,FRAME_HEIGHT);
        //固定窗口大小,使其不可改变
        setResizable(false);

        /**
         * 设置窗口左上角位置
         * 使得窗口打开时出现在屏幕中间
         */
        setLocation(FRAME_X,FRAME_Y);
        //也可以使用 setLocationRelativeTo(null); 直接实现居中显示


        /**
         * 使得窗口可见
         * 如果没有setVisible就只有代码,而不会出现窗口页面
         */
        setVisible(true);

        //调用update()绘制窗口的内容
        repaint();
    }
     /**
     * 初始化窗口的事件监听
     * 上面的代码都是对窗口属性的修改,而关闭按钮等都属于事件,所以单独作为方法
     */
    private void initEventListner() {
        //注册监听事件
        //WindowAdapter()是JDK提供的类
        addWindowListener(new WindowAdapter() {
            //点击关闭按钮时,windowClosing()方法会被自动调用
            @Override
            public void windowClosing(WindowEvent e) {
                //关闭窗口事件处理
                //结束虚拟机
                System.exit(0);
            }
        });
    }

有关常量
package com.data
class Constant

/**
* 储存常量的类
* 所有的游戏都放在该类中进行维护和管理
*/
public class Constant {
 /*****************************关于窗口初始化**************************************/
 //窗口标题
 public static final String WINDOW_TITLE = "窗口window";

 //窗口大小
 public static final int FRAME_WIDTH = 900;
 public static final int FRAME_HEIGHT = 700;

 //窗口位置
 //用左上角坐标定位
 //1920,1024为屏幕当前分辨率     >>1是二进制右移一位,相当于除2
 public static final int FRAME_X = 1920 - FRAME_WIDTH>>1;
 public static final int FRAME_Y = 1024 - FRAME_HEIGHT>>1;

不同窗口间跳转

开发文档
2. 不同窗口的链接
从一个窗口跳转到其他窗口

  • 主窗口
    菜单中上下移动
  • 内容
    显示
  • 作者
    显示

主窗口按键
package com.frame;
class enterFrame

//添加窗口内容按键的事件监听
        addKeyListener(new KeyAdapter() {
            //按键按下时回调的方法
            @Override
            public void keyPressed(KeyEvent e) {
                //记录用户按键操作
                int keyCode = e.getKeyCode();
                switch (WINDOW_State) {
                    case STATE_MAIN:
                        keyEventmain(keyCode);
                        break;
                }
            }
        });
    }
    //主窗口下的按键处理
    private void keyEventmain(int keyCode) {
        switch (keyCode) {
            case KeyEvent.VK_UP:
            case KeyEvent.VK_W:
                menuIndex--;
                if (menuIndex < 0) {
                    menuIndex = STATE.length - 1;
                }
                break;
            case KeyEvent.VK_DOWN:
            case KeyEvent.VK_S:
                menuIndex++;
                if (menuIndex > STATE.length - 1) {
                    menuIndex = 0;
                }
                break;
            case KeyEvent.VK_ENTER:
                newWindow();
                break;
        }
    }

    /**
     * 开始新窗口
     */
    private void newWindow() {
        WINDOW_State = STATE_CONTENT;
    }

窗口内容绘制
package com.frame;
class enterFrame

修改重绘机制

开发文档
3. 修改重绘机制

  • 单独启动一个线程用于窗口的重绘

有关常量
package com.data
class Constant

 //窗口刷新率
    public static final int REPAINT_INTERVAL = 100;

package com.frame;
class enterFrame

//public class enterFrame extends Frame implements Runnable

    @Override
    public void run() {
        //死循环来控制不断刷新
        while (true) {
            repaint();
            try {
                Thread.sleep(REPAINT_INTERVAL);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

   启动线程
   //public enterFrame() {
   //     initFrame();
   //     initEventListner();
   //     //启动用于刷新窗口的线程
   //     new Thread(this).start();
    }

原代码

在这里插入图片描述

整个程序的入口处
package com.enter;

import com.frame.enterFrame;

/**
 * 程序入口
 */
public class window {
    public static void main(String[] args) {
        //创建窗口
        new enterFrame();
    }
}
窗口
package com.frame;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

//静态导入常量类
import static com.data.Constant.*;

/**
 * 窗口
 * 窗口无法通过代码直接实现,所以从Java中继承已有窗口类
 */
public class enterFrame extends Frame implements Runnable{
    //对窗口初始化
    public enterFrame() {
        initFrame();
        initEventListner();
        //启动用于刷新窗口的线程
        new Thread(this).start();
    }

    //对窗口属性初始化
    private void initFrame() {
        /**
         * 设置窗口标题(左上角内容)
         * setTitle("窗口界面");可以直接使用常量,但是不推荐。因为不利于后期更改
         * 所以创建一个常量类来管理所有常量,然后静态调用
         */
        setTitle(WINDOW_TITLE);

        //设置窗口大小
        setSize(FRAME_WIDTH,FRAME_HEIGHT);
        //固定窗口大小,使其不可改变
        setResizable(false);

        /**
         * 设置窗口左上角位置
         * 使得窗口打开时出现在屏幕中间
         */
        setLocation(FRAME_X,FRAME_Y);
        //也可以使用 setLocationRelativeTo(null); 直接实现居中显示


        /**
         * 使得窗口可见
         * 如果没有setVisible就只有代码,而不会出现窗口页面
         */
        setVisible(true);

        //调用update()绘制窗口的内容
        repaint();
    }






    /**
     * 初始化窗口的事件监听
     * 上面的代码都是对窗口属性的修改,而关闭按钮等都属于事件,所以单独作为方法
     */
    private void initEventListner() {
        //注册监听事件
        //WindowAdapter()是JDK提供的类
        addWindowListener(new WindowAdapter() {
            //点击关闭按钮时,windowClosing()方法会被自动调用
            @Override
            public void windowClosing(WindowEvent e) {
                //关闭窗口事件处理
                //结束虚拟机
                System.exit(0);
            }
        });

        //添加窗口内容按键的事件监听
        addKeyListener(new KeyAdapter() {
            //按键按下时回调的方法
            @Override
            public void keyPressed(KeyEvent e) {
                //记录用户按键操作
                int keyCode = e.getKeyCode();
                switch (WINDOW_State) {
                    case STATE_MAIN:
                        keyEventmain(keyCode);
                        break;
                }
            }
        });
    }
    //主窗口下的按键处理
    private void keyEventmain(int keyCode) {
        switch (keyCode) {
            case KeyEvent.VK_UP:
            case KeyEvent.VK_W:
                menuIndex--;
                if (menuIndex < 0) {
                    menuIndex = STATE.length - 1;
                }
                break;
            case KeyEvent.VK_DOWN:
            case KeyEvent.VK_S:
                menuIndex++;
                if (menuIndex > STATE.length - 1) {
                    menuIndex = 0;
                }
                break;
            case KeyEvent.VK_ENTER:
                newWindow();
                break;
        }
    }

    /**
     * 开始新窗口
     */
    private void newWindow() {
        WINDOW_State = STATE_CONTENT;
    }










    //保存当前页面状态---应对有多个窗口的情况
    //静态方便调用
    public static int WINDOW_State;
    /**
     * 窗口跳转状态初始化
     */
    private void initState() {
        //刚创建窗口时,默认进入主界面
        WINDOW_State = STATE_MAIN;
    }


    /**
     * update负责绘制所以需要在屏幕中显示的内容
     * update是从Frame类继承的方法
     * 该方法不能主动调用,要借助repaint()回调
     */
    @Override
    public void update(Graphics g) {
        //设置字体
        g.setFont(ALL_FONT);

        switch (WINDOW_State) {
            case STATE_MAIN:
                drawMain(g);
                break;
            case STATE_CONTENT:
                drawContent(g);
                break;
            case STATE_AUTHOR:
                drawAuthor(g);
                break;
        }
    }

    /**
     * 绘制主窗口状态
     */
    //Graphics 绘制用的画笔,系统提供
    private void drawMain(Graphics g) {
        /**
         * 绘制背景
         * setColor(Color.PINK);获得粉色笔
         * fillRect(起点x坐标,起点y坐标,填充宽度,填充高度);填充颜色
         */
        g.setColor(Color.PINK);
        g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGHT);

        /**
         * 绘制菜单内容
         */
        //局部使用,所以这些常量不放入常量类
        final int STR_WIDTH = 100;//菜单字符的宽度
        int x = FRAME_WIDTH - STR_WIDTH >>1;//菜单的X坐标
        int y = FRAME_HEIGHT / 3;//菜单的Y坐标,从页面的三分之一高开始
        final int DIS = 100;//菜单内容的行间距
        for (int i = 0; i < STATE.length; i++) {
            //当前选中项用不同颜色标记
            if (i == menuIndex) {
                g.setColor(Color.CYAN);
            }else {
                g.setColor(Color.WHITE);
            }
            //y + DIS * i 0: y为起始坐标,每多一项y就留出一段行间距
            g.drawString(STATE[i],x,y + DIS * i );
        }
    }


    /**
     * 绘制内容窗口状态
     */
    private void drawContent(Graphics g) {
        //绘制背景
        g.setColor(Color.CYAN);
        g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGHT);

        //绘制内容
        final int STR_WIDTH = 200;
        int x = FRAME_WIDTH - STR_WIDTH >>1;
        int y = FRAME_HEIGHT / 2;
        final int DIS = 40;
        g.setColor(Color.WHITE);
        for (int i = 0; i < STATE_Content.length; i++) {
            //y + DIS * i 0: y为起始坐标,每多一项y就留出一段行间距
            g.drawString(STATE_Content[i],x,y + DIS * i );
        }
    }

    //菜单目前选中对象----定义在class Frame中
    private static int menuIndex;

    /**
     * 绘制作者窗口状态
     */
    private void drawAuthor(Graphics g) {
        //绘制背景
        g.setColor(Color.CYAN);
        g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGHT);

        //绘制内容
        final int STR_WIDTH = 200;
        int x = FRAME_WIDTH - STR_WIDTH >>1;
        int y = FRAME_HEIGHT / 2;
        final int DIS = 50;
        g.setColor(Color.WHITE);
        for (int i = 0; i < STATE_Content.length; i++) {
            //y + DIS * i 0: y为起始坐标,每多一项y就留出一段行间距
            g.drawString(STATE_Content[i],x,y + DIS * i );
        }
    }

    @Override
    public void run() {
        //死循环来控制不断刷新
        while (true) {
            repaint();
            try {
                Thread.sleep(REPAINT_INTERVAL);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
常量池
package com.data;

import java.awt.*;

/**
 * 储存常量的类
 * 所有的游戏都放在该类中进行维护和管理
 */
public class Constant {
    /*****************************关于窗口初始化**************************************/
    //窗口标题
    public static final String WINDOW_TITLE = "窗口window";

    //窗口大小
    public static final int FRAME_WIDTH = 900;
    public static final int FRAME_HEIGHT = 700;

    //窗口位置
    //用左上角坐标定位
    //1920,1024为屏幕当前分辨率     >>1是二进制右移一位,相当于除2
    public static final int FRAME_X = 1920 - FRAME_WIDTH>>1;
    public static final int FRAME_Y = 1024 - FRAME_HEIGHT>>1;

    /*****************************关于窗口间的跳转**************************************/
    public static final int STATE_MAIN = 0;//记录主窗口
    public static final int STATE_CONTENT = 1;//记录 内容 窗口
    public static final int STATE_AUTHOR = 2;//记录 作者 窗口

    public static final String[] STATE = {
            "内容",
            "作者",
    };

    public static final String[] STATE_Content = {
            "Java 窗口制作",
            "山外野夫子"
    };


    //字体
    public static final Font ALL_FONT = new Font("华文彩云",Font.BOLD,30);



    //窗口刷新率
    public static final int REPAINT_INTERVAL = 100;

}


;