Java学习笔记(No.19)

Java之GUI编程(No.19)

GUI(Graphical User Interface,图形用户界面),是指采用图形方式显示的计算机操作用户界面

GUI的核心技术:“AWT"与"Swing”

  • GUI缺点
    • 1、界面不美观
    • 2、依赖JRE环境
  • 学习GUI目的
    • 1、可以写出自定义的一些小工具
    • 2、可能会维护Swing界面(极小概率)
    • 3、了解MVC架构,了解监听

1、AWT(Abstract Window Toolkit,抽象窗口工具包)

1.1、组件和容器(Component And Container)

1.1.1、示意图

GUI组件和容器示意图

1.1.2、Frame(框架窗口)
1.1.2.1、显示单个窗口(Show Single Window)
  • 1.1.2.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui;
    import java.awt.*;
    /**
     * GUI(图像用户界面)窗口:显示单个Frame窗口
     */
    public class ShowSingleFrameWindow {
        public static void main(String[] args) {
            //创建Frame窗口
            Frame frame=new Frame("显示单个Frame窗口");
            //设置窗口可见性
            frame.setVisible(true);
            //设置窗口大小
            frame.setSize(300,300);
            //设置背景颜色
            frame.setBackground(new Color(33, 65, 130));
            //弹出的初始位置
            frame.setLocation(150,150);
            //设置窗体大小的固定性
            frame.setResizable(false);
        }
    }
    
  • 1.1.2.1.2、运行结果(Run Result)

    其运行结果,如下图所示

    Frame单个窗口运行结果

1.1.2.2、显示多个窗口(Show Multiple Window)
  • 1.1.2.2.1、示例代码(Sample Code)

其示例代码,如下所示

package com.xueshanxuehai.gui;
import java.awt.*;
/**
 * GUI(图像用户界面)窗口:显示多个Frame窗口
 */
public class ShowMultipleFrameWindow {
    public static void main(String[] args) {
        //创建Frame窗口
        new InheritFrame(300,200,300,200,Color.red);
        new InheritFrame(600,200,300,200,Color.green);
        new InheritFrame(300,400,300,200,Color.blue);
        new InheritFrame(600,400,300,200,Color.yellow);
    }
}
//自定义继承Frame类的InheritFrame类
class InheritFrame extends Frame{
    static int frameID=0;//Frame窗口ID
    public InheritFrame(int x,int y,int width,int height,Color color){
        super("Frame窗口"+(++frameID));//使用父类构造方法设置窗口标题名称
        this.setBackground(color);//设置窗口背景颜色
        this.setBounds(x,y,width,height);//设置窗口初始位置以及大小
        this.setVisible(true);//设置窗口可见性
    }
}
  • 1.1.2.2.2、运行结果(Run Result)

其运行结果,如下图所示

Frame多个窗口运行结果

1.1.3、Panel(面板)

使用Panel(面板)时,其无法单独显示,必须添加到某个容器中

  • 1.1.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.componentandcontainer.panel;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * Panel(面板):无法单独显示,必须添加到某个容器中。
     */
    public class ShowPanel {
        public static void main(String[] args) {
            //创建窗口
            Frame frame = new Frame("添加Panel(面板容器)至Frame(窗口容器)中显示");
            //创建面板
            Panel panel=new Panel();
            //设置窗口布局
            frame.setLayout(null);//默认流式布局
            //设置窗口坐标与宽高
            frame.setBounds(200,200,400,400);
            //设置窗口背景颜色
            frame.setBackground(new Color(134, 37, 59));
            //设置面板坐标与宽高
            panel.setBounds(100,100,200,200);
            //设置面板背景颜色
            panel.setBackground(new Color(18, 82, 18));
            //窗口添加面板,即,将面板添加窗口容器中显示
            frame.add(panel);
            //设置窗口可视性
            frame.setVisible(true);
            //设置窗口固定性
            frame.setResizable(false);
            //监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(new WindowAdapter())”
            frame.addWindowListener(new WindowAdapter() {
                //窗口点击关闭时触发事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//结束程序
                }
            });
        }
    }
    
  • 1.1.3.2、运行结果(Run Result)

    其运行结果,如下图所示

    Panel面板运行结果

1.2、三种布局管理器(Three Layout Managers)

1.2.1、流程式布局(Flow Layout)
  • 1.2.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.layout;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.UnsupportedEncodingException;
    /**
     * 流程式布局(即,流式布局)
     */
    public class ShowFlowLayout {
        public static void main(String[] args) throws UnsupportedEncodingException {
            //创建窗口
            Frame frame=new Frame("流程式布局(即,流式布局)");
            //创建按钮
            Button button1=new Button("button1");
            Button button2=new Button("button2");
            Button button3=new Button("button3");
            Button button4=new Button("button4");
            Button button5=new Button("button5");
            Button button6=new Button("button6");
            //设置窗口布局为“流程式布局”
            frame.setLayout(new FlowLayout());
            //设置窗口坐标与宽高
            frame.setBounds(100,100,300,300);
            //窗口添加按钮,即,将按钮添加窗口容器中显示
            frame.add(button1);
            frame.add(button2);
            frame.add(button3);
            frame.add(button4);
            frame.add(button5);
            frame.add(button6);
            //设置窗口可视性
            frame.setVisible(true);
            //设置窗口固定性
            frame.setResizable(false);
            //监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
            frame.addWindowListener(new WindowAdapter() {
                //窗口点击关闭时触发事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//结束程序
                }
            });
        }
    }
    
  • 1.2.1.2、运行结果(Run Result)

    其运行结果,如下图所示

    流程式布局运行结果

1.2.2、边框式布局(Border Layout)
  • 1.2.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.layout;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 边框式布局
     */
    public class ShowBorderLayout {
        public static void main(String[] args) {
            //创建窗口
            Frame frame=new Frame("边框式布局");
            //创建按钮
            Button button1=new Button("button1");
            Button button2=new Button("button2");
            Button button3=new Button("button3");
            Button button4=new Button("button4");
            Button button5=new Button("button5");
            //设置窗口布局为“边框式布局”
            frame.setLayout(new BorderLayout());
            //设置窗口坐标与宽高
            frame.setBounds(100,100,300,300);
            //窗口添加按钮,即,将按钮添加窗口容器中显示
            frame.add(button1,BorderLayout.NORTH);
            frame.add(button2,BorderLayout.WEST);
            frame.add(button3,BorderLayout.CENTER);
            frame.add(button4,BorderLayout.EAST);
            frame.add(button5,BorderLayout.SOUTH);
            //设置窗口可视性
            frame.setVisible(true);
            //设置窗口固定性
            frame.setResizable(false);
            //监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
            frame.addWindowListener(new WindowAdapter() {
                //窗口点击关闭时触发事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//结束程序
                }
            });
        }
    }
    
  • 1.2.2.2、运行结果(Run Result)

    其运行结果,如下图所示

    边框式布局运行结果

1.2.3、网格式布局(Grid Layout)
  • 1.2.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.layout;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 网格式布局
     */
    public class ShowGridLayout {
        public static void main(String[] args) {
            //创建窗口
            Frame frame=new Frame("网格式布局");
            //创建按钮
            Button button1=new Button("button1");
            Button button2=new Button("button2");
            Button button3=new Button("button3");
            Button button4=new Button("button4");
            //设置窗口布局为“边框式布局”
            frame.setLayout(new GridLayout(2,2));
            //窗口添加按钮,即,将按钮添加窗口容器中显示
            frame.add(button1);
            frame.add(button2);
            frame.add(button3);
            frame.add(button4);
    //        //使此窗口的大小适合其子组件的首选大小和布局
    //        frame.pack();
            //设置窗口坐标与宽高
            frame.setBounds(100,100,300,300);
            //设置窗口可视性
            frame.setVisible(true);
            //设置窗口固定性
            frame.setResizable(false);
            //监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
            frame.addWindowListener(new WindowAdapter() {
                //窗口点击关闭时触发事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//结束程序
                }
            });
        }
    }
    
  • 1.2.3.2、运行结果(Run Result)

    其运行结果,如下图所示

    网格式布局运行结果

1.3、练习:嵌套布局组件(Exercise:Nest Layout Component)

  • 1.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.exercise;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 练习题:嵌套布局组件(如“Frame、Panel等”)
     */
    public class NestLayoutComponent {
        public static void main(String[] args) {
            //创建窗口
            Frame frame=new Frame("嵌套布局组件");
            //设置窗口布局为“边框式布局”
            frame.setLayout(new GridLayout(2,1));//网格式布局
            //设置窗口坐标与宽高
            frame.setBounds(200,200,400,400);
            //设置窗口背景颜色
            frame.setBackground(new Color(35, 139, 139));
            //设置窗口可视性
            frame.setVisible(true);
            //设置窗口固定性
            frame.setResizable(false);
            //监听事件:监听窗口关闭事件(addWindowListener),且参数为“适配器模式(WindowAdapter)”
            frame.addWindowListener(new WindowAdapter() {
                //窗口点击关闭时触发事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//结束程序
                }
            });
            //创建4个面板
            Panel panel1=new Panel(new BorderLayout());//边框式布局
            Panel panel2=new Panel(new GridLayout(2,1));//网格式布局
            Panel panel3=new Panel(new BorderLayout());//边框式布局
            Panel panel4=new Panel(new GridLayout(2,2));//网格式布局
            //添加按钮至面板
            panel1.add(new Button("WEST-1"),BorderLayout.WEST);
            panel1.add(new Button("EAST-1"),BorderLayout.EAST);
            for (int i = 0; i < 2; i++) {
                panel2.add(new Button("CENTER-1-"+(i+1)));
            }
            panel1.add(panel2,BorderLayout.CENTER);
            panel3.add(new Button("WEST-2"),BorderLayout.WEST);
            panel3.add(new Button("EAST-2"),BorderLayout.EAST);
            for (int i = 0; i < 4; i++) {
                panel4.add(new Button("CENTER-2-"+(i+1)));
            }
            panel3.add(panel4,BorderLayout.CENTER);
            //添加面板至窗口
            frame.add(panel1);
            frame.add(panel3);
        }
    }
    
  • 1.3.2、运行结果(Run Result)

    其运行结果,如下图所示

    嵌套布局组件运行结果

1.4、按钮事件监听(Button Event Listener)

  • 1.4.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.listenerevent;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 事件监听:按钮事件监听
     * 实现两个按钮“开始”与“停止”的同一个事件监听
     */
    public class ButtonEventListener {
        public static void main(String[] args) {
            //创建窗口
            Frame frame = new Frame("实现两个按钮“开始”与“结束”的同一个事件监听");
            //创建按钮
            Button button1 = new Button("Start");
            Button button2 = new Button("Stop");
            /**
             * 事件监听:即,实现ActionListener接口类
             * 可以显示定义触发会返回的命令,若不显示定义,则会返回默认值
             * 多个按钮可以共用同一个监听类
             */
            button2.setActionCommand("停止");//设置此按钮触发的操作事件的命令名称
            //监听按钮事件
            ImplementActionListener implementActionListener = new ImplementActionListener();
            button1.addActionListener(implementActionListener);
            button2.addActionListener(implementActionListener);
            //设置窗口布局为“边框式布局”
            frame.setLayout(new BorderLayout());
            //设置窗口坐标与宽高
            frame.setBounds(100, 100, 500, 500);
            //窗口添加按钮,即,将按钮添加窗口容器中显示
            frame.add(button1, BorderLayout.NORTH);
            frame.add(button2, BorderLayout.SOUTH);
            //设置窗口可视性
            frame.setVisible(true);
    //        //设置窗口固定性
    //        frame.setResizable(false);
            //关闭窗口
            closeWindow(frame);
        }
        //关闭窗口
        private static void closeWindow(Frame frame) {
            //监听窗口关闭事件
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    //事件监听类
    class ImplementActionListener implements ActionListener {
        //重写ActionListener接口actionPerformed方法
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("当前点击了" + e.getActionCommand() + "按钮");
        }
    }
    
  • 1.4.2、运行结果(Run Result)

    其运行结果,如下图所示

按钮事件监听运行结果

1.5、单行文本输入框事件监听(TextField Event Listener)

  • 1.5.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.listenerevent;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 事件监听:单行文本输入框事件监听
     */
    public class TextFieldEventListener {
        public static void main(String[] args) {
            //创建启动类对象:一般建议使用此方式。
            new StartUpFrame();
        }
    }
    //启动类
    class StartUpFrame extends Frame{
        //无参构造方法
        public StartUpFrame(){
            //设置窗口标题名称
            super("单行文本输入框事件监听");
            //创建单行文本输入框
            TextField textField = new TextField();
            //添加单行文本输入框至窗口
            add(textField);
            //监听单行文本输入框事件:键盘按下Enter键时,就会触发单行文本输入框事件
            textField.addActionListener(new ImplementTextFieldEventListener());
            //设置替换编码字符
            textField.setEchoChar('*');
            //设置窗口坐标与宽高
            setBounds(100, 100, 500, 500);
            //设置窗口可视性
            setVisible(true);
            //关闭窗口
            closeWindow(this);
        }
        //关闭窗口
        private void closeWindow(Frame frame) {
            //监听窗口关闭事件
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    //单行文本输入框事件监听类
    class ImplementTextFieldEventListener implements ActionListener{
        //重写ActionListener接口actionPerformed方法
        @Override
        public void actionPerformed(ActionEvent e) {
            TextField textField= (TextField) e.getSource();//获取事件最初发生的对象
            System.out.println(textField.getText());//获取单行文本输入框的输入文本信息
            textField.setText("");//设置单行文本输入框的输入文本信息为空字符串,即,“清空单行文本输入框”
        }
    }
    
  • 1.5.2、运行结果(Run Result)

    其运行结果,如下图所示

单行文本输入框事件监听运行结果

1.6、练习:简易计算器(Exercise:Simple Calculator)

1.6.1、使用普通类实现(Use Common Class Implementation)

其类似于面向过程的编程思想

  • 1.6.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.exercise.calculator;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 使用普通类实现简易计算器
     */
    public class UseCommonClassImplementation {
        public static void main(String[] args) {
            new Calculator();//创建启动类对象
        }
    }
    //计算器类
    class Calculator extends Frame{
        public Calculator(){
            //设置窗口标题名称
            super("使用普通类实现简易计算器");
            //3个文本输入框
            TextField textField1=new TextField(10);//被加数
            TextField textField2=new TextField(10);//加数
            TextField textField3=new TextField(20);//和
            //1个按钮
            Button button = new Button("=");//等号
            //监听按钮事件
            button.addActionListener(new CalculatorActionListener(textField1,textField2,textField3));
            //1个标签
            Label label = new Label("+");//加号
            //设置窗口布局
            setLayout(new FlowLayout());//流式布局
            //添加组件
            add(textField1);
            add(label);
            add(textField2);
            add(button);
            add(textField3);
            //设置窗口组件自适应大小
            pack();
            //设置窗口可见性
            setVisible(true);
            //关闭窗口
            closeWindow(this);
        }
        //关闭窗口
        private void closeWindow(Frame frame){
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    //监听器类
    class CalculatorActionListener implements ActionListener{
        //属性
        private TextField textField1,textField2,textField3;
    
        public CalculatorActionListener(TextField textField1, TextField textField2, TextField textField3) {
            this.textField1 = textField1;
            this.textField2 = textField2;
            this.textField3 = textField3;
        }
        @Override
        public void actionPerformed(ActionEvent e) {
    
            int add1=Integer.parseInt(textField1.getText());//被加数
            int add2=Integer.parseInt(textField2.getText());//加数
            textField3.setText(""+(add1+add2));//和
            textField1.setText("");//清空被加数
            textField2.setText("");//清空加数
        }
    }
    
  • 1.6.1.2、运行结果(Run Result)

    其运行结果,如下图所示

使用普通类实现简易计算器运行结果

1.6.2、使用组合类实现(Use Composite Class Implementation)

面向对象,且组合类要优于继承类

  • 1.6.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.exercise.calculator;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 使用组合类实现简易计算器
     */
    public class UseCompositeClassImplementation {
        public static void main(String[] args) {
            new Calculator1();//创建启动类对象
        }
    }
    //计算器类
    class Calculator1 extends Frame {
        //属性
        TextField textField1,textField2,textField3;
        //构造方法
        public Calculator1(){
            //设置窗口标题名称
            super("使用组合类实现简易计算器");
            startUpFrame();//调用启动方法
        }
        //启动方法
        public void startUpFrame(){
            //3个文本输入框
            textField1=new TextField(10);//被加数
            textField2=new TextField(10);//加数
            textField3=new TextField(20);//和
            //1个按钮
            Button button = new Button("=");//等号
            //监听按钮事件
            button.addActionListener(new CalculatorActionListener(this));
            //1个标签
            Label label = new Label("+");//加号
            //设置窗口布局
            setLayout(new FlowLayout());//流式布局
            //添加组件
            add(textField1);
            add(label);
            add(textField2);
            add(button);
            add(textField3);
            //设置窗口组件自适应大小
            pack();
            //设置窗口可见性
            setVisible(true);
            //关闭窗口
            closeWindow(this);
        }
        //关闭窗口
        private void closeWindow(Frame frame){
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    //监听器类
    class CalculatorActionListenerimplements ActionListener {
        //组合类:即,在一个类中组合另一个类
        Calculator1 calculator=null;
        //构造方法
        public CalculatorActionListener(Calculator1 calculator) {
            this.calculator = calculator;
        }
        //重写ActionListener接口actionPerformed方法
        @Override
        public void actionPerformed(ActionEvent e) {
            int add1=Integer.parseInt(calculator.textField1.getText());//被加数
            int add2=Integer.parseInt(calculator.textField2.getText());//加数
            calculator.textField3.setText(""+(add1+add2));//和
            calculator.textField1.setText("");//清空被加数
            calculator.textField2.setText("");//清空加数
        }
    }
    
  • 1.6.2.2、运行结果(Run Result)

    其运行结果,如下图所示

使用组合类实现简易计算器运行结果

1.6.3、使用内部类实现(Use Internal Class Implementation)

面向对象,且内部类要优于组合类,其最大好处为“可以任意访问外部类的属性与方法”

  • 1.6.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.exercise.calculator;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 使用内部类实现简易计算器
     */
    public class UseInternalClassImplementation {
        public static void main(String[] args) {
            new Calculator2();//创建启动类对象
        }
    }
    //计算器类
    class Calculator2 extends Frame {
        //属性
        TextField textField1,textField2,textField3;
        //构造方法
        public Calculator2(){
            //设置窗口标题名称
            super("使用内部类实现简易计算器");
            startUpFrame();//调用启动方法
        }
        //启动方法
        public void startUpFrame(){
            //3个文本输入框
            textField1=new TextField(10);//被加数
            textField2=new TextField(10);//加数
            textField3=new TextField(20);//和
            //1个按钮
            Button button = new Button("=");//等号
            //监听按钮事件
            button.addActionListener(new CalculatorActionListener());
            //1个标签
            Label label = new Label("+");//加号
            //设置窗口布局
            setLayout(new FlowLayout());//流式布局
            //添加组件
            add(textField1);
            add(label);
            add(textField2);
            add(button);
            add(textField3);
            //设置窗口组件自适应大小
            pack();
            //设置窗口可见性
            setVisible(true);
            //关闭窗口
            closeWindow(this);
        }
        //关闭窗口
        private void closeWindow(Frame frame){
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
        //监听器类:即,内部类,可以更好的包装,其最大好处为“可以任意访问外部类的属性与方法”。
        private class CalculatorActionListenerimplements ActionListener {
            //重写ActionListener接口actionPerformed方法
            @Override
            public void actionPerformed(ActionEvent e) {
                int add1=Integer.parseInt(textField1.getText());//被加数
                int add2=Integer.parseInt(textField2.getText());//加数
                textField3.setText(""+(add1+add2));//和
                textField1.setText("");//清空被加数
                textField2.setText("");//清空加数
            }
        }
    }
    
  • 1.6.3.2、运行结果(Run Result)

    其运行结果,如下图所示

使用内部类实现简易计算器运行结果

1.7、画笔(Paint Brush)

  • 1.7.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.componentandcontainer.frame;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 画笔
     */
    public class PaintBrush {
        public static void main(String[] args) {
            new PaintClass();//创建启动类对象
        }
    }
    //画笔类
    class PaintClass extends Frame {
        public PaintClass() {
            super("画笔");
            startUpFrame();
        }
        public void startUpFrame() {
            setBounds(100, 100, 500, 500);
            setVisible(true);
            closeWindow(this);//关闭窗口
        }
        /**
         * 重写Frame类paint方法
         * 绘制组件:即,画笔.
         *
         * @param g
         */
        @Override
        public void paint(Graphics g) {
            //画笔:需要有颜色,且可以绘画。
            g.setColor(Color.BLUE);//蓝色颜色
            g.draw3DRect(100, 100, 300, 300, true);//绘制一个3D的空心矩形
            g.setColor(Color.GRAY);//灰色画笔
            g.drawPolygon(new int[]{100, 250, 400,250}, new int[]{250, 100, 250,400}, 4);//绘制一个空心四边形(即,菱形)
            g.setColor(Color.GREEN);//绿色画笔
            g.drawOval(150, 150, 200, 200);//绘制一个空心园
            g.setColor(Color.RED);//红色画笔
            g.fillOval(200, 200, 100, 100);//绘制一个实心园
            //画笔用完后,建议还原为最初的颜色。
            g.setColor(Color.BLACK);//默认画笔颜色为黑色
        }
        //关闭窗口
        private void closeWindow(Frame frame) {
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    
  • 1.7.2、运行结果(Run Result)

    其运行结果,如下图所示

画笔运行结果

1.8、鼠标事件监听(Mouse Event Listener)

模拟画图工具

  • 1.8.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.listenerevent;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.util.ArrayList;
    import java.util.Iterator;
    /**
     * 鼠标事件监听:模拟画图工具
     * 1、使用画笔
     * 2、监听鼠标当前位置坐标
     * 3、使用集合列表存储所有的监听鼠标位置坐标
     * 4、重新绘制组件
     */
    public class MouseEventListener {
        public static void main(String[] args) {
            new PaintListenerMousePosition("模拟画图工具");//创建启动类对象
        }
    }
    //画笔监听鼠标位置类
    class PaintListenerMousePosition extends Frame{
        //存储所有的监听鼠标位置坐标的集合列表
        ArrayList mousePositionList;
        public PaintListenerMousePosition(String title){
            super(title);//设置窗口标题
            mousePositionList=new ArrayList<>();
            setBounds(100,100,500,500);//设置窗口位置与大小
            setVisible(true);//设置窗口可见
            this.addMouseListener(new MouseActionListener());//添加鼠标事件监听
            closeWindow(this);//关闭窗口
        }
        //重写Frame类paint方法
        @Override
        public void paint(Graphics g) {
            //画笔:即,绘制组件
            Iterator iterator=mousePositionList.iterator();
            while(iterator.hasNext()){
                Point point= (Point) iterator.next();
                g.setColor(Color.RED);
                g.fillOval(point.x, point.y, 20,20);
            }
        }
        //添加鼠标位置坐标至集合列表
        public void addMousePositionList(Point point){
            mousePositionList.add(point);
        }
        //适配器模式
        private class MouseActionListener extends MouseAdapter{
            //鼠标按下
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("当前鼠标按下");
            }
            //鼠标按下不放
            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("当前鼠标按下不放");
                PaintListenerMousePosition pLMP= (PaintListenerMousePosition) e.getSource();
                pLMP.addMousePositionList(new Point(e.getX(),e.getY()));//添加当前鼠标坐标
                pLMP.repaint();//重新绘制组件
            }
            //鼠标释放
            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println("当前鼠标释放");
            }
        }
        //关闭窗口
        private void closeWindow(Frame frame){
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
        }
    }
    
  • 1.8.2、运行结果(Run Result)

    其运行结果,如下图所示

鼠标监听事件运行结果

1.9、窗口事件监听(Window Event Listener)

分别使用内部类(Internal Class)与匿名内部类(Anonymous Internal Class)来实现,并且匿名内部类要比内部类更简洁方便”

  • 1.9.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.listenerevent;
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 窗口事件监听:使用内部类或匿名内部类实现窗口事件监听,匿名内部类比内部类更简捷方便,一般建议使用匿名内部类。
     * 局部内部类和匿名内部类最大的不同之处:局部内部类可以返回不止一个内部类的对象。
     */
    public class WindowEventListener {
        public static void main(String[] args) {
            new WindowFrame1("使用内部类实现窗口事件监听");//创建启动类对象
            new WindowFrame2("使用匿名内部类实现窗口事件监听");//创建启动类对象
        }
    }
    //外部类
    class WindowFrame1 extends Frame{
        public WindowFrame1(String title){
            super(title);//设置窗口标题
            setBounds(100,100,400,300);//设置窗口坐标及大小
            setVisible(true);//设置窗口可见
            addWindowListener(new WindowActionListener());//添加窗口事件监听
        }
        //添加窗口事件监听:即,使用内部类实现
        private class WindowActionListener extends WindowAdapter{
            //窗口关闭事件
            @Override
            public void windowClosing(WindowEvent e) {
                //setVisible(false);//设置窗口隐藏
                System.exit(0);//关闭程序,正常退出
            }
        }
    }
    //外部类
    class WindowFrame2 extends Frame{
        public WindowFrame2(String title){
            super(title);//设置窗口标题
            setBounds(100,100,400,300);//设置窗口坐标及大小
            setVisible(true);//设置窗口可见
            //添加窗口事件监听:即,使用匿名内部类实现
            addWindowListener(new WindowAdapter() {
                //窗口关闭事件
                @Override
                public void windowClosing(WindowEvent e) {
                    //setVisible(false);//设置窗口隐藏
                    System.exit(0);//关闭程序,正常退出
                }
                //窗口激活事件
                @Override
                public void windowActivated(WindowEvent e) {
                    WindowFrame2 windowFrame2= (WindowFrame2) e.getSource();
                    windowFrame2.setTitle("使用匿名内部类实现窗口事件监听:窗口激活");
                    System.out.println("使用匿名内部类实现窗口事件监听:窗口激活");
                }
            });
        }
    }
    
  • 1.9.2、运行结果(Run Result)

    其运行结果,如下图所示

使用内部类或匿名内部类实现窗口事件监听运行结果

1.10、键盘事件监听(Keyboard Event Listener)

  • 1.10.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.listenerevent;
    import java.awt.*;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    /**
     * 键盘事件监听
     */
    public class KeyboardEventListener {
        public static void main(String[] args) {
            new KeyboardFrame("键盘事件监听");//创建启动类对象
        }
    }
    //外部类
    class KeyboardFrame extends Frame {
        public KeyboardFrame(String title) {
            super(title);
            setBounds(100,100,300,300);
            setVisible(true);
            //添加窗口事件监听:即,使用匿名内部类实现
            addWindowListener(new WindowAdapter() {
                //窗口关闭事件
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);//关闭程序
                }
            });
            //添加键盘事件监听:即,使用匿名内部类实现
            addKeyListener(new KeyAdapter() {
                //键盘按下不放事件
                @Override
                public void keyPressed(KeyEvent e) {
                    int keyCode=e.getKeyCode();//按键数值
                    int extendedKeyCode=e.getExtendedKeyCode();//按键扩展密钥代码
                    char keyChar=e.getKeyChar();//按键字符
                    int keyLocation=e.getKeyLocation();//按键位置
                    String keyText=KeyEvent.getKeyText(keyCode);//按键描述
                    System.out.println("按键字符("+keyChar+")按键数值("+keyCode+")按键位置("+keyLocation+")按键描述("+keyText+")按键扩展密钥代码("+extendedKeyCode+")");
                }
            });
        }
    }
    
  • 1.10.2、运行结果(Run Result)

    其运行结果,如下图所示

键盘监听事件运行结果

2、Swing

Swing是一个用于开发Java应用程序用户界面的开发工具包

Swing是以抽象窗口工具包(AWT)为基础 使跨平台应用程序可以使用任何可插拔的外观风格。Swing开发人员只用很少的代码就可以利用Swing丰富、灵活的功能和模块化组件来创建优雅的用户界面

2.1、JFrame窗口(JFrame Window)

  • 2.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * JFrame窗口
     */
    public class JFrameWindow {
        public static void main(String[] args) {
            new StartUpJFrame("JFrame窗口");//创建启动类对象
        }
    }
    class StartUpJFrame extends JFrame{
        public StartUpJFrame(String title){
            super(title);//设置窗口标题
            init();//调用启动方法
        }
        public void init(){
            setBounds(100,100,300,300);//设置窗口坐标及大小
            setVisible(true);//设置窗口可见
            JLabel jLabel=new JLabel("JLabel标签");//新增标签
            this.add(jLabel);//添加标签至窗口
            jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
            Container container=this.getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
    }
    
  • 2.1.2、运行结果(Run Result)

    其运行结果,如下图所示

JFrame窗口运行结果

2.2、JDialog弹出窗口(JDialog Popup Window)

  • 2.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    /**
     * JDialog弹出窗口
     */
    public class JDialogPopupWindow {
        public static void main(String[] args) {
            new MainWindow("JDialog主窗口");//创建启动类对象
        }
    }
    //主窗口类
    class MainWindow extends JFrame{
        public MainWindow(String title){
            super(title);//设置窗口标题
            init();//调用启动方法
        }
        private void init(){
            setBounds(100,100,300,300);//设置窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
            Container container=this.getContentPane();//获取此窗口的容器
            container.setLayout(null);//默认布局:即,绝对布局
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            JButton jButton=new JButton("弹出窗口按钮");//新增按钮
            jButton.setBounds(50,50,150,100);//设置按钮坐标及大小
            jButton.setHorizontalAlignment(SwingConstants.CENTER);//设置按钮水平居中对齐
            //添加按钮事件监听
            jButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new PopupDialog("JDialog弹出窗口");//弹出窗口
                }
            });
            this.add(jButton);//添加按钮至窗口
        }
    }
    //弹出窗口类
    class PopupDialog extends JDialog{
        public PopupDialog(String title){
            setTitle(title);//设置弹出窗口标题
            init();//调用启动方法
        }
        private void init(){
            setBounds(400,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置弹出窗口可见
            //setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭弹出窗口:无需设置此功能,否则异常
            Container container=this.getContentPane();//获取此弹出窗口的容器
            container.setLayout(null);//默认布局:即,绝对布局
            container.setBackground(Color.GREEN);获取此弹出窗口容器的背景颜色
            JLabel jLabel=new JLabel("JDialog弹出窗口的JLabel标签");//新增标签
            jLabel.setBounds(50,50,200,100);//设置标签坐标及大小
            jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
            container.add(jLabel);//添加标签至容器
        }
    }
    
  • 2.2.2、运行结果(Run Result)

    其运行结果,如下图所示

JDialog弹出窗口运行结果

2.3、Icon与ImageIcon标签(Icon And ImageIcon Label)

2.3.1、Icon标签(Icon Label)
  • 2.3.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * Icon:图标
     * 1、继承JFrame类
     * 2、实现Icon接口
     * 特别注意:设置JFrame窗口为Container容器后,再设置JFrame窗口的参数(如坐标、大小、可见性等)才有效。
     */
    public class IconLabel extends JFrame implements Icon {
        private int width;//图标宽度
        private int height;//图标高度
        //无参构造方法
        public IconLabel(){
        }
        //有参构造方法
        public IconLabel(int width, int height){
            super("Icon(图标)");
            this.width = width;
            this.height = height;
        }
        //主方法
        public static void main(String[] args) {
            new IconLabel(20,20).init();//调用启动方法
        }
        //启动方法
        public void init(){
            IconLabel iconLabel=new IconLabel(this.width,this.height);//设置图标宽高
            //将图标放到标签上(也可以把图标放到按钮上)
            JLabel jLabel=new JLabel("图标标签",iconLabel,SwingConstants.CENTER);
            Container container=getContentPane();//获取此窗口的容器
            //container.setLayout(null);//默认布局:即,绝对布局
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            container.add(jLabel);//添加标签至容器
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
            System.out.println("图标名称""+getTitle()+"",图标宽度""+getIconWidth()+"",图标高度""+getIconHeight()+""");
        }
        //重写Icon接口的paintIcon方法
        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            g.setColor(Color.GREEN);//绿色画笔
            g.fillOval(x,y,this.width,this.height);//填充绘制一个圆形图标
        }
        //重写Icon接口的getIconWidth方法
        @Override
        public int getIconWidth() {
            return this.width;//返回图标宽度
        }
        //重写Icon接口的getIconHeight方法
        @Override
        public int getIconHeight() {
            return this.height;//返回图标高度
        }
    }
    
  • 2.3.1.2、运行结果(Run Result)

    其运行结果,如下图所示

Icon标签运行结果

2.3.2、ImageIcon标签(ImageIcon Label)
  • 2.3.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    import java.net.URL;
    /**
     * ImageIcon:图像图标
     * 1、继承JFrame类
     * 特别注意:设置JFrame窗口为Container容器后,再设置JFrame窗口的参数(如坐标、大小、可见性等)才有效。
     */
    public class ImageIconLabel extends JFrame {
        private int width;//图标宽度
        private int height;//图标高度
        //无参构造方法
        public ImageIconLabel(){
            super("ImageIcon(图像图标)");
        }
        //主方法
        public static void main(String[] args) {
            new ImageIconLabel().init();//调用启动方法
        }
        //启动方法
        public void init(){
            JLabel jLabel=new JLabel("图像图标标签");//新增标签
            URL url=this.getClass().getResource("URLTest.jpg");//获取图像图标地址(URL)
            ImageIcon imageIcon=new ImageIcon(url);//新增图像图标
            jLabel.setIcon(imageIcon);//添加图像图标到标签
            jLabel.setHorizontalAlignment(SwingConstants.CENTER);//设置标签水平居中对齐
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            //container.setLayout(null);//默认布局:即,绝对布局
            container.add(jLabel);//添加标签至容器
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
    }
    
  • 2.3.2.2、运行结果(Run Result)

    其运行结果,如下图所示

ImageIcon标签运行结果

2.4、按钮与面板、文本域与滚动面板(Button And Panel,Text Area And Scroll Panel)

2.4.1、按钮与面板(Button And Panel)
  • 2.4.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 按钮与面板
     */
    public class ButtonAndPanel extends JFrame {
        public ButtonAndPanel(){
            super("按钮与面板");
            init();
        }
        public void init(){
            JPanel jPanel=new JPanel(new GridLayout(5,2,10,10));//新增面板,2行2列的网格布局,且上下左右间距为10
            //新增按钮
            jPanel.add(new JButton("按钮1"));
            jPanel.add(new JButton("按钮2"));
            jPanel.add(new JButton("按钮3"));
            jPanel.add(new JButton("按钮4"));
            jPanel.add(new JButton("按钮5"));
            jPanel.add(new JButton("按钮6"));
            jPanel.add(new JButton("按钮7"));
            jPanel.add(new JButton("按钮8"));
            jPanel.add(new JButton("按钮9"));
            jPanel.add(new JButton("按钮10"));
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            container.setLayout(new GridLayout(2,2,20,20));//新增容器,2行2列的网格布局,且上下左右间距为20
            container.add(jPanel);//添加面板至容器
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new ButtonAndPanel();//创建启动类对象
        }
    }
    
  • 2.4.1.2、运行结果(Run Result)

    其运行结果,如下图所示

按钮与面板运行结果

2.4.2、文本域与滚动面板(Text Area And Scroll Panel)
  • 2.4.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 文本域与滚动面板
     */
    public class TextAreaAndScrollPanel extends JFrame {
        public TextAreaAndScrollPanel(String title){
            super(title);
            init();
        }
        public void init(){
            //新增文本域
            JTextArea jTextArea=new JTextArea("文本域",30,30);
            jTextArea.setText("文本域信息");//设置文本域信息
            jTextArea.setToolTipText("文本域提示信息");//设置文本域提示信息
            //新增滚动面板,且添加文本域到滚动面板
            JScrollPane jScrollPane=new JScrollPane(jTextArea);
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            container.add(jScrollPane);//添加滚动面板至容器
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new TextAreaAndScrollPanel("文本域与滚动面板");//创建启动类对象
        }
    }
    
  • 2.4.2.2、运行结果(Run Result)

    其运行结果,如下图所示

文本域与滚动面板运行结果

2.5、图像按钮、单选框按钮、复选框按钮(Image Button,Radio Box Button,Check Box Button)

2.5.1、图像按钮(Image Button)
  • 2.5.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    import java.net.URL;
    /**
     * 图像按钮
     */
    public class ImageButton extends JFrame{
        public ImageButton(String title){
            super(title);
            init();
        }
        public void init(){
            URL url=this.getClass().getResource("URLTest.jpg");//获取图像图标地址(URL)
            Icon icon=new ImageIcon(url);//设置图像图标
            JButton jButton=new JButton();//新增按钮
            jButton.setIcon(icon);//添加图像图标到按钮
            //jButton.setText("图像按钮");//设置按钮文本信息
            jButton.setToolTipText("图像按钮");//设置按钮提示信息
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);获取此窗口容器的背景颜色
            container.add(jButton);//添加按钮至容器
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new ImageButton("图像按钮");//创建启动类对象
        }
    }
    
  • 2.5.1.2、运行结果(Run Result)

    其运行结果,如下图所示

图像按钮运行结果

2.5.2、单选框按钮(Radio Box Button)
  • 2.5.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 单选框按钮
     */
    public class RadioBoxButton extends JFrame{
        public RadioBoxButton(String title){
            super(title);
            init();
        }
        public void init(){
            //新增单选框按钮
            JRadioButton jRadioButton1=new JRadioButton("单选框按钮1");
            JRadioButton jRadioButton2=new JRadioButton("单选框按钮2");
            JRadioButton jRadioButton3=new JRadioButton("单选框按钮3");
            //新增按钮组
            ButtonGroup buttonGroup=new ButtonGroup();
            //添加单选框按钮至按钮组:确保一组单选框按钮每次只能选择一个单选框按钮
            buttonGroup.add(jRadioButton1);
            buttonGroup.add(jRadioButton2);
            buttonGroup.add(jRadioButton3);
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//获取此窗口容器的背景颜色
            container.setLayout(new FlowLayout(FlowLayout.CENTER));//获取此窗口容器的布局
            //添加单选框按钮至容器
            container.add(jRadioButton1);
            container.add(jRadioButton2);
            container.add(jRadioButton3);
            setBounds(100,100,400,100);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new RadioBoxButton("单选框按钮");//创建启动类对象
        }
    }
    
  • 2.5.2.2、运行结果(Run Result)

    其运行结果,如下图所示

单选框按钮运行结果

2.5.3、复选框按钮(Check Box Button)
  • 2.5.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 复选框按钮
     */
    public class CheckBoxButton extends JFrame{
        public CheckBoxButton(String title){
            super(title);
            init();
        }
        public void init(){
            //新增复选框按钮
            JCheckBox jCheckBox1=new JCheckBox("复选框按钮1");
            JCheckBox jCheckBox2=new JCheckBox("复选框按钮2");
            JCheckBox jCheckBox3=new JCheckBox("复选框按钮3");
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//获取此窗口容器的背景颜色
            container.setLayout(new FlowLayout(FlowLayout.CENTER));//获取此窗口容器的布局
            //添加复选框按钮至容器
            container.add(jCheckBox1);
            container.add(jCheckBox2);
            container.add(jCheckBox3);
            setBounds(100,100,400,100);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new CheckBoxButton("复选框按钮");//创建启动类对象
        }
    }
    
  • 2.5.3.2、运行结果(Run Result)

    其运行结果,如下图所示

复选框按钮运行结果

2.6、组合框、列表框(Combo Box,List Box)

2.6.1、组合框(Combo Box)
  • 2.6.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 组合框
     */
    public class ComboBoxContainer extends JFrame {
        public ComboBoxContainer(String title){
            super(title);
            init();
        }
        public void init(){
            //新增组合框
            JComboBox jComboBox=new JComboBox();
            jComboBox.addItem(null);
            jComboBox.addItem("优秀");
            jComboBox.addItem("良好");
            jComboBox.addItem("及格");
            jComboBox.addItem("不及格");
            jComboBox.setBounds(50,50,200,100);//设置组合框坐标及大小
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//设置此窗口容器的背景颜色
            container.setLayout(null);//设置此窗口容器的布局
            //添加组合框至容器
            container.add(jComboBox);
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new ComboBoxContainer("组合框");//创建启动类对象
        }
    }
    
  • 2.6.1.2、运行结果(Run Result)

    其运行结果,如下图所示

组合框运行结果

2.6.2、列表框(List Box)
  • 2.6.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    import java.util.Vector;
    /**
     * 下拉框
     */
    public class ListBoxContainer extends JFrame {
        public ListBoxContainer(String title){
            super(title);
            init();
        }
        public void init(){
            //新增下拉框
            JList jList1=new JList(new String[]{"","优秀","良好","及格","不及格"});
            jList1.setBounds(30,50,100,100);//设置下拉框坐标及大小
            Vector vector=new Vector();//可扩展的对象数组
            JList jList2=new JList(vector);
            jList2.setBounds(160,50,100,100);//设置下拉框坐标及大小
            vector.add("");
            vector.add("1");
            vector.add("2");
            vector.add("3");
            vector.add("4");
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//设置此窗口容器的背景颜色
            container.setLayout(null);//设置此窗口容器的布局
            //添加下拉框至容器
            container.add(jList1);
            container.add(jList2);
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new ListBoxContainer("下拉框");//创建启动类对象
        }
    }
    
  • 2.6.2.2、运行结果(Run Result)

    其运行结果,如下图所示

列表框运行结果

2.7、文本框、密码框、文本域(Text Field,Password Field,Text Area)

2.7.1、文本框(Text Field)
  • 2.7.1.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 文本框
     */
    public class TextFieldContainer extends JFrame {
        public TextFieldContainer(String title){
            super(title);
            init();
        }
        public void init(){
            //新增文本框
            JTextField jTextField1=new JTextField("文本框1");
            JTextField jTextField2=new JTextField("文本框2");
            jTextField1.setBounds(30,50,100,100);//设置文本框坐标及大小
            jTextField2.setBounds(150,50,100,100);//设置文本框坐标及大小
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//设置此窗口容器的背景颜色
            container.setLayout(null);//设置此窗口容器的布局
            //添加文本框至容器
            container.add(jTextField1);
            container.add(jTextField2);
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new TextFieldContainer("文本框");//创建启动类对象
        }
    }
    
  • 2.7.1.2、运行结果(Run Result)

    其运行结果,如下图所示

文本框运行结果

2.7.2、密码框(Password Field)
  • 2.7.2.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 密码框
     */
    public class PasswordFieldContainer extends JFrame {
        public PasswordFieldContainer(String title){
            super(title);
            init();
        }
        public void init(){
            //新增密码框
            JPasswordField jPasswordField=new JPasswordField();
            jPasswordField.setEchoChar('*');//
            jPasswordField.setBounds(30,50,100,100);//设置密码框坐标及大小
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//设置此窗口容器的背景颜色
            container.setLayout(null);//设置此窗口容器的布局
            //添加密码框至容器
            container.add(jPasswordField);
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new PasswordFieldContainer("密码框");//创建启动类对象
        }
    }
    
  • 2.7.2.2、运行结果(Run Result)

    其运行结果,如下图所示

密码框运行结果

2.7.3、文本域(Text Area)
  • 2.7.3.1、示例代码(Sample Code)

    其示例代码,如下所示

    package com.xueshanxuehai.gui.swing;
    import javax.swing.*;
    import java.awt.*;
    /**
     * 文本域
     */
    public class TextAreaContainer extends JFrame{
        public TextAreaContainer(String title){
            super(title);
            init();
        }
        public void init(){
            //新增文本域
            JTextArea jTextArea1=new JTextArea("文本域1",20,20);
            JTextArea jTextArea2=new JTextArea("文本域2",20,20);
            //新增滚动面板,且添加文本域到滚动面板
            JScrollPane jScrollPane1=new JScrollPane(jTextArea1);
            JScrollPane jScrollPane2=new JScrollPane(jTextArea2);
            //设置滚动面板坐标及大小
            jScrollPane1.setBounds(30,50,100,100);
            jScrollPane2.setBounds(150,50,100,100);
            Container container=getContentPane();//获取此窗口的容器
            container.setBackground(Color.RED);//设置此窗口容器的背景颜色
            container.setLayout(null);//设置此窗口容器的布局
            //添加滚动面板至容器
            container.add(jScrollPane1);
            container.add(jScrollPane2);
            setBounds(100,100,300,300);//设置弹出窗口坐标及大小
            setVisible(true);//设置窗口可见
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        }
        public static void main(String[] args) {
            new TextAreaContainer("文本域");//创建启动类对象
        }
    }
    
  • 2.7.3.2、运行结果(Run Result)

    其运行结果,如下图所示

文本域运行结果

3、练习:实现“贪吃蛇”游戏(Exercise:Realize The “Greedy Snake” Game)

3.1、游戏需求(Game Demand)

  • 3.1.1、按空格键开始或暂停游戏
  • 3.1.2、按上、下、左、右键控制贪吃蛇的移动方向
  • 3.1.3、实时计算贪吃蛇的当前长度和当前积分

3.2、示例代码(Sample Code)

  • 3.2.1、游戏的启动类

GameStart类,其代码如下所示

package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
/**
 * 游戏的启动类
 */
public class GameStart {
    public static void main(String[] args) {
        JFrame jFrame=new JFrame();//创建窗口对象
        jFrame.setBounds(10,10,915,730);//设置窗口坐标及大小
        jFrame.setResizable(false);//设置窗口固定
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭窗口
        jFrame.add(new GamePanel());//添加游戏面板至窗口
        jFrame.setVisible(true);//设置窗口可见
    }
}
  • 3.2.2、游戏的面板类

GamePanel类,其代码如下所示

package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
/**
 * 游戏的面板类
 * 1、继承JPanel类
 * 2、实现KeyListener接口
 * 3、实现ActionListener接口
 */
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    //定义蛇的数据结构
    int length;//蛇的长度
    int[] snakeX = new int[600];//蛇的X坐标(25*25)
    int[] snakeY = new int[600];//蛇的Y坐标(25*25)
    String snakeDirection;//蛇的方向
    boolean gameState = false;//游戏的状态(默认为停止)
    Timer timer = new Timer(100, this);//定时器,每100毫秒执行一次,且被事件监听
    int foodX;//食物的X坐标(25*25)
    int foodY;//食物的Y坐标(25*25)
    Random random=new Random();//随机数:随机食物的坐标基数
    boolean gameIsFail=false;//游戏是否失败,默认为成功
    int score;//成绩积分
    //无参构造方法
    public GamePanel() {
        init();//调用初始化方法
        setFocusable(true);//获得焦点
        addKeyListener(this);//获得键盘监听事件
        timer.start();//开启定时器,即”开始游戏“
    }
    //初始化方法
    public void init() {
        length = 3;//蛇的初始长度
        snakeX[0] = 100;//蛇头的X坐标
        snakeY[0] = 100;//蛇头的Y坐标
        snakeX[1] = 75;//蛇身1的X坐标
        snakeY[1] = 100;//蛇身1的Y坐标
        snakeX[2] = 50;//蛇身2的X坐标
        snakeY[2] = 100;//蛇身2的Y坐标
        snakeDirection = "RIGHT";//蛇的初始方向,默认为蛇头向右
        foodX=25+25*random.nextInt(((int)(850/25)-1));//随机食物的X坐标(25*25)
        foodY=75+25*random.nextInt(((int)(600/25)-1));//随机食物的Y坐标(25*25)
        score=0;//初始成绩积分
    }
    //绘制面板:游戏中的所有东西都由此方法此画笔来绘制
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        //绘制静态的游戏面板
        setBackground(Color.WHITE);//白色背景
        GameResource.header.paintIcon(this, g, 25, 15);//绘制头部广告栏图片按钮
        g.fillRect(25, 75, 850, 600);//绘制默认的矩形游戏界面
        //绘制成绩积分
        g.setColor(Color.GREEN);//绿色背景
        g.setFont(new Font("宋体", Font.BOLD, 20));//设置字体
        g.drawString("当前长度"+length, 750, 37);//绘制当前长度文本提示信息及大小
        g.drawString("当前积分"+score, 750, 57);//绘制成绩积分文本提示信息及大小
        //绘制食物
        GameResource.food.paintIcon(this,g,foodX,foodY);//绘制食物
        //绘制蛇头
        if (snakeDirection.equals("RIGHT")) {
            GameResource.right.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向右的蛇头
        } else if (snakeDirection.equals("LEFT")) {
            GameResource.left.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向左的蛇头
        } else if (snakeDirection.equals("UP")) {
            GameResource.up.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向上的蛇头
        } else if (snakeDirection.equals("DOWN")) {
            GameResource.down.paintIcon(this, g, snakeX[0], snakeY[0]);//绘制向下的蛇头
        }
        //绘制蛇身
        for (int i = 1; i < length; i++) {
            GameResource.body.paintIcon(this, g, snakeX[i], snakeY[i]);//绘制蛇身
        }
        //绘制游戏状态
        if (!gameState) {
            g.setColor(Color.WHITE);//白色背景
            g.setFont(new Font("宋体", Font.BOLD, 30));//设置字体
            g.drawString("请按下空格开始游戏", 200, 200);//绘制游戏状态文本提示信息及大小
        }
        //绘制游戏失败
        if(gameIsFail){
            g.setColor(Color.RED);//红色背景
            g.setFont(new Font("宋体", Font.BOLD, 30));//设置字体
            g.drawString("游戏失败,请按下空格重新开始游戏", 200, 200);//绘制游戏失败文本提示信息及大小
        }
    }
    //键盘按下不放监听事件
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();//获取按键值
        if (keyCode == KeyEvent.VK_SPACE) {//按下空格键
            if(gameIsFail){//游戏失败
                gameIsFail=false;//重新开始游戏
                init();//重新初始化
            }else{
                gameState = !gameState;//取反
            }
            repaint();//重绘
        } else if (keyCode == KeyEvent.VK_RIGHT) {//按下向右键
            snakeDirection = "RIGHT";
            repaint();//重绘
        } else if (keyCode == KeyEvent.VK_LEFT) {//按下向左键
            snakeDirection = "LEFT";
            repaint();//重绘
        } else if (keyCode == KeyEvent.VK_UP) {//按下向上键
            snakeDirection = "UP";
            repaint();//重绘
        } else if (keyCode == KeyEvent.VK_DOWN) {//按下向下键
            snakeDirection = "DOWN";
            repaint();//重绘
        }
    }
    //事件监听:即,通过监听定时器事件来刷新
    @Override
    public void actionPerformed(ActionEvent e) {
        if (gameState && !gameIsFail) {//若游戏为开始状态,且游戏未失败,则让蛇移动起来
            //蛇吃食物
            if(snakeX[0]==foodX && snakeY[0]==foodY){
                length++;//蛇的长度加1
                score+=10;//成绩积分加10
                foodX=25+25*random.nextInt(((int)(850/25)-1));//随机食物的X坐标(25*25)
                foodY=75+25*random.nextInt(((int)(600/25)-1));//随机食物的Y坐标(25*25)
            }
            //绘制移动蛇身坐标:后一个坐标移动到前一个坐标
            for (int i = length - 1; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }
            if (snakeDirection.equals("RIGHT")) {
                snakeX[0] += 25;//绘制移动蛇头坐标
                if (snakeX[0] > 850) {
                    snakeX[0] = 25;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
                }
            } else if (snakeDirection.equals("LEFT")) {
                snakeX[0] -= 25;//绘制移动蛇头坐标
                if (snakeX[0] < 25) {
                    snakeX[0] = 850;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
                }
            } else if (snakeDirection.equals("UP")) {
                snakeY[0] -= 25;//绘制移动蛇头坐标
                if (snakeY[0] < 75) {
                    snakeY[0] = 650;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
                }
            } else if (snakeDirection.equals("DOWN")) {
                snakeY[0] += 25;//绘制移动蛇头坐标
                if (snakeY[0] > 650) {
                    snakeY[0] = 75;//边界判定,若超过边界,则从当前方向起始坐标重新开始移动
                }
            }
            //游戏失败判定:即,撞到自身就算游戏失败
            for (int i = 1; i < length; i++) {
                if(snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
                    gameIsFail=true;//游戏失败
                }
            }
            repaint();//重绘
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }
}
  • 3.2.3、游戏的资源类

GameResource类,其代码如下所示

package com.xueshanxuehai.gui.swing.exercise.GreedySnake;
import javax.swing.*;
import java.net.URL;
/**
 * 游戏的资源类
 */
public class GameResource {
    public static URL headerURL=GameResource.class.getResource("images/header.png");//获取头部广告栏图片URL地址
    public static ImageIcon header=new ImageIcon(headerURL);//新增头部广告栏图片按钮
    public static URL upURL=GameResource.class.getResource("images/up.png");//获取蛇头向上图片URL地址
    public static ImageIcon up=new ImageIcon(upURL);//新增蛇头向上图片按钮
    public static URL downURL=GameResource.class.getResource("images/down.png");//获取蛇头向下图片URL地址
    public static ImageIcon down=new ImageIcon(downURL);//新增蛇头向下图片按钮
    public static URL leftURL=GameResource.class.getResource("images/left.png");//获取蛇头向左图片URL地址
    public static ImageIcon left=new ImageIcon(leftURL);//新增蛇头向左图片按钮
    public static URL rightURL=GameResource.class.getResource("images/right.png");//获取蛇头向右图片URL地址
    public static ImageIcon right=new ImageIcon(rightURL);//新增蛇头向右图片按钮
    public static URL bodyURL=GameResource.class.getResource("images/body.png");//获取蛇身体图片URL地址
    public static ImageIcon body=new ImageIcon(bodyURL);//新增蛇身体图片按钮
    public static URL foodURL=GameResource.class.getResource("images/food.png");//获取食物图片URL地址
    public static ImageIcon food=new ImageIcon(foodURL);//新增食物图片按钮
}

3.3、运行结果(Run Result)

其运行结果,如下图所示

“贪吃蛇”游戏运行结果

参考资料(Reference Data):GUISwing

学习网站地址(即"学习网址",Learning Website Address):Java之GUI编程

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值