第十七章、GUI编程

GUI编程

1. GUI(图形用户界面)

  • GUI:Graphical User Interface(图形用户接口)。
    • 用图形的方式,来显示计算机操作的界面,这样使得界面更加美观
  • CLI:Command line User Interface (命令行用户接口)
    • 常用的是Dos命令行操作,需要记忆一些常用的命令,操作不方便
  • 举例
    • 创建文件夹,删除文件夹等

2. AWT和swing包的概述

  • AWT:Abstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能,属重量级控件。
    • 控件:窗口、弹窗、面板、文本框、列表框、按钮、图片、监听事件、鼠标监听、键盘监听
  • Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。增强了移植性,属轻量级控件
    • 控件:窗口、弹窗、面板、文本框、列表框、按钮、图片、监听事件、鼠标监听、键盘监听

3. GUI继承体系图

img

4. AWT包

4.1 Frame窗体

  • setVisible(boolean b):设置窗体可见与否

  • setSize(int x,int y):设置窗体大小

  • setLocation((int x,int y):设置窗体在屏幕上显示的位置

  • setBackground(Color color):设置窗体背景颜色

  • setTitle(String title):设置窗体的名称

  • setBounds(int x, int y, int width, int height):设置窗体大小、和屏幕上显示的位置

  • pack():窗体自动适应屏幕

  • setLayout():设置窗体的布局样式

  • setResizable(boolean b):设置窗口大小固定

  • 示例代码

    package FrameDemo;
    
    import java.awt.Color;
    import java.awt.Frame;
    
    public class TestFrame {
    	public static void main(String[] args) {
    
    		Frame frame = new Frame("我的第一个Java图形界面");
    		
            // 设置窗体的名称
            frame.setTitle("我的第一个Java图形界面");
            
    		// 要设置可见 true false
    		frame.setVisible(true);
    
    		// 设置窗口大小
    		frame.setSize(400, 400);
    		// 弹框的初始位置
    		frame.setLocation(200, 200);
            // 上述两个方法相当于下面这个方法
            frame.setBouns(200,200,400,400);
            
    		// 设置窗口背景颜色
    		frame.setBackground(Color.BLUE);
    	}
    }
    
    
  • 效果图

    image-20201221193429320

4.2 面板Panel

  • setSize(int x,int y):设置面板大小,相对于窗体来说的

  • setLocation((int x,int y):设置面板在屏幕上显示的位置,相对于窗体来说的

  • setBackground(Color color):设置面板背景颜色

  • setBounds(int x, int y, int width, int height):设置面板大小、和屏幕上显示的位置,相对于窗体来说的

  • setLayout():设置面板的布局样式

  • 示例代码

    package PanelDemo;
    
    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Panel;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    // Panel可以看做一个空间,但是不能单独使用
    public class TestPanel {
    	public static void main(String[] args) {
    		Frame frame = new Frame("我的第一个Java图像化界面");
    		// Panel布局的概念
    		Panel panel = new Panel();
    		// frame设置布局
    		frame.setLayout(null);
    		
    		frame.setBounds(300, 300, 500, 500);
    		frame.setBackground(new Color(40,161,35));
    		
    		// Panel社会自己坐标,相对于frame 
    		panel.setBounds(50, 50, 400, 400);
    		panel.setBackground(Color.red);
    		panel.setVisible(true);
    		
    		frame.add(panel);
    		frame.setVisible(true);
           
    		// 监听事件,监听窗口关闭事件  System.exit(0)
    		// 适配器模式
    		frame.addWindowListener(new WindowAdapter() {
    			
    			// 窗口点击关闭的时候需要做的是事情
    			@Override
    			public void windowClosing(WindowEvent e) {
    				System.exit(0);
    			}
    		});
    	}
    }
    
  • 效果图

    image-20201221193547302

4.3 布局管理器Layout

  1. 流式布局FLowLayout

    • 布局规则:将容器中的组件按照加入的先后顺序从左向右排列,如果一行排满转下一行继续,每行均采取居中排列。

    • 代码示例

      package LayoutDemo;
      
      import java.awt.Button;
      import java.awt.Color;
      import java.awt.FlowLayout;
      import java.awt.Frame;
      
      public class TestFlowLayout {
      	public static void main(String[] args) {
      		Frame frame = new Frame();
      		Button button1 = new Button("按钮一");
      		Button button2 = new Button("按钮二");
      		Button button3 = new Button("按钮三");
      		Button button4 = new Button("按钮一");
      		Button button5 = new Button("按钮二");
      		Button button6 = new Button("按钮三");
      		Button button7 = new Button("按钮一");
      		Button button8 = new Button("按钮二");
      		Button button9 = new Button("按钮三");
      		frame.setLayout(new FlowLayout(FlowLayout.LEFT));
      		
      		frame.setBounds(100, 100, 200, 200);
      		
      		frame.setBackground(Color.blue);
      		
      		frame.add(button1);
      		frame.add(button2);
      		frame.add(button3);
      		frame.add(button4);
      		frame.add(button5);
      		frame.add(button6);
      		frame.add(button7);
      		frame.add(button8);
      		frame.add(button9);
      		frame.setVisible(true);
      	}
      }
      
    • 效果图

      image-20201221193737461
  2. 边界式布局BorderLayout

    • 布局规则:把容器内的空间划分为东(EAST)、西(WEST)、南(SOUTH)、北(NORTH)、中(CENTER)5个区域分别用英文的East、 West、 South、 North、Center表示,向容器中加入每个组件都要指明在容器的区域。

    • 示例代码

      package LayoutDemo;
      
      import java.awt.BorderLayout;
      import java.awt.Button;
      import java.awt.Color;
      import java.awt.Frame;
      
      public class TestBorderLayout {
      	public static void main(String[] args) {
      		Frame frame = new Frame();
      		
      		Button east = new Button("East");
      		Button west = new Button("Wast");
      		Button south = new Button("South");
      		Button north = new Button("North");
      		Button center = new Button("Center");
      		
      		frame.setLayout(new BorderLayout());
      		frame.setBounds(100, 100, 500, 500);
      		
      		frame.setBackground(Color.BLUE);
      		
      		frame.add(east,BorderLayout.EAST);		
      		frame.add(west,BorderLayout.WEST);		
      		frame.add(south,BorderLayout.SOUTH);		
      		frame.add(north,BorderLayout.NORTH);		
      		frame.add(center,BorderLayout.CENTER);
      		
      		frame.setVisible(true);
      	}
      }
      
    • 效果图

      image-20201221194003371

  3. 方格式布局GridLayout

    • 布局规则:把容器划分成若干行乘若干列的网格区域,组件就位于这些划分出来的小格中。

    • 示例代码

      package LayoutDemo;
      
      import java.awt.Button;
      import java.awt.Frame;
      import java.awt.GridLayout;
      
      public class TestGridLayout {
      	public static void main(String[] args) {
      		Frame frame = new Frame();
      		
      		Button btn1 = new Button("btn1");
      		Button btn2 = new Button("btn2");
      		Button btn3 = new Button("btn3");
      		Button btn4 = new Button("btn4");
      		Button btn5 = new Button("btn5");
      		Button btn6 = new Button("btn6");
      		
      		frame.setLayout(new GridLayout(3,2));
      		
      		frame.add(btn1);
      		frame.add(btn2);
      		frame.add(btn3);
      		frame.add(btn4);
      		frame.add(btn5);
      		frame.add(btn6);
      		
      		frame.pack();
      		frame.setVisible(true);
      	}
      }
      
    • 效果图

      image-20201221194331659

  4. 作业:实现下列布局

    • 操作一:

      • 效果图

      image-20201221194831780

      • 示例代码

        package LayoutDemo;
        
        import java.awt.BorderLayout;
        import java.awt.Button;
        import java.awt.Frame;
        import java.awt.GridLayout;
        import java.awt.Panel;
        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        
        /*实现下面的布局:
         * 		-----------------------------
         * 		|	|					|	|
         * 		|	|-------------------|	|
         * 		|	|					|	|
         * 		|---------------------------|
         * 		|	|		 |    		|	|
         * 		|   ---------------------   |
         * 		|	|		 |    		|	|
         * 		-----------------------------
         * 
         */
        public class HomeWork {
        	public static void main(String[] args) {
        		// 创建一个窗口
        		Frame frame = new Frame();
        		// 设置窗口的长宽
        		frame.setSize(400, 300);
        		// 设置窗口的位置
        		frame.setLocation(200, 200);
        		// 设置窗口的布局样式----->东西南北中布局
        		frame.setLayout(new GridLayout(2,1));
        		// 设置窗口可见
        		frame.setVisible(true);
        		
        		// 创建四个面板   
        		// p1、p3---->frame中的面板
        		// p2、p4---->分别为p1、p3中的面板
        		Panel p1 = new Panel(new BorderLayout());
        		Panel p2 = new Panel(new GridLayout(2,1));
        		Panel p3 = new Panel(new BorderLayout());
        		Panel p4 = new Panel(new GridLayout(2,2));
        		
        		// p1中左边的按钮
        		p1.add(new Button("btn-west-1"),BorderLayout.WEST);
        		// p1中右边的按钮
        		p1.add(new Button("btn-east-1"),BorderLayout.EAST);
        		// p1中的中间的面板p2
        		p1.add(p2,BorderLayout.CENTER);
        		// p2中上面的按钮
        		p2.add(new Button("p2-center-top"),BorderLayout.NORTH);
        		// p2中下面的按钮
        		p2.add(new Button("p2-center-bottom"),BorderLayout.SOUTH);
        
        		
        		
        		// p3中左边的按钮
        		p3.add(new Button("btn-west-2"),BorderLayout.WEST);
        		// p3中右边的按钮
        		p3.add(new Button("btn-east-2"),BorderLayout.EAST);
        		// p3中的中间的面板p4
        		p3.add(p4,BorderLayout.CENTER);
        		// 循环向p4中添加按钮
        		for (int i = 0; i < 4; i++) {
        			p4.add(new Button("p4-"+i));
        		}
        		
        		// 将p1、p3添加到frame中
        		frame.add(p1);
        		frame.add(p3);
        		
        		// 设置监听
        		frame.addWindowListener(new WindowAdapter() {
        			@Override
        			public void windowClosing(WindowEvent e) {
        				System.exit(0);
        			}
        		});
        	}
        }
        
    • 操作二:

      • 效果图

        image-20201221195854802

      • 示例代码

        package TextFieldDemo;
        
        import java.awt.BorderLayout;
        import java.awt.Button;
        import java.awt.Frame;
        import java.awt.GridLayout;
        import java.awt.Panel;
        import java.awt.TextField;
        import java.awt.event.ActionEvent;
        import java.awt.event.ActionListener;
        import java.awt.event.WindowAdapter;
        import java.awt.event.WindowEvent;
        
        public class HomeWorkDemo {
        	public static void main(String[] args) {
        		Frame frame = new Frame("简易计算器");
        		frame.setLayout(new BorderLayout(3,1));
        		
        		TextField textField = new TextField();
        		Panel panel = new Panel(new GridLayout(4,4));
        		
        		// 创建ActionListener对象
        		MyActionListener1 myActionListener1 = new MyActionListener1(textField);
        		
        		
        		// 创建计算器的按钮
        		Button btn_1 = new Button("1");
        		Button btn_2 = new Button("2");
        		Button btn_3 = new Button("3");
        		Button btn_4 = new Button("4");
        		Button btn_5 = new Button("5");
        		Button btn_6 = new Button("6");
        		Button btn_7 = new Button("7");
        		Button btn_8 = new Button("8");
        		Button btn_9 = new Button("9");
        		Button btn_0 = new Button("0");
        		Button btn_jia = new Button("+");
        		Button btn_jian = new Button("-");
        		Button btn_chen = new Button("*");
        		Button btn_chu = new Button("/");
        		Button btn_deng = new Button("=");
        		Button btn_dian = new Button(".");
        		
        		// 将计算器的按钮添加到panel面板中
        		panel.add(btn_1);
        		panel.add(btn_2);
        		panel.add(btn_3);
        		panel.add(btn_jia);
        		panel.add(btn_4);
        		panel.add(btn_5);
        		panel.add(btn_6);
        		panel.add(btn_jian);
        		panel.add(btn_7);
        		panel.add(btn_8);
        		panel.add(btn_9);
        		panel.add(btn_chen);
        		panel.add(btn_dian);
        		panel.add(btn_0);
        		panel.add(btn_deng);
        		panel.add(btn_chu);
        		
        		// 给按钮绑定点击事件
        		btn_1.addActionListener(myActionListener1);
        		btn_2.addActionListener(myActionListener1);
        		btn_3.addActionListener(myActionListener1);
        		btn_4.addActionListener(myActionListener1);
        		btn_5.addActionListener(myActionListener1);
        		btn_6.addActionListener(myActionListener1);
        		btn_7.addActionListener(myActionListener1);
        		btn_8.addActionListener(myActionListener1);
        		btn_9.addActionListener(myActionListener1);
        		btn_0.addActionListener(myActionListener1);
        		btn_jia.addActionListener(myActionListener1);
        		btn_jian.addActionListener(myActionListener1);
        		btn_chen.addActionListener(myActionListener1);
        		btn_chu.addActionListener(myActionListener1);
        		btn_deng.addActionListener(myActionListener1);
        		btn_dian.addActionListener(myActionListener1);
        		
        		
        		frame.add(textField,BorderLayout.NORTH);
        		frame.add(panel,BorderLayout.SOUTH);
        		
        		frame.pack();
        		ActionClose(frame);
        		frame.setVisible(true);
        		
        	}
        	
        	// 监听关闭窗口事件
        	private static void ActionClose(Frame frame){
        		frame.addWindowListener(new WindowAdapter() {
        
        			@Override
        			public void windowClosing(WindowEvent e) {
        				System.exit(0);
        			}
        		});
        	}
        }
        }
        

4.4 上述总结

  • Frame是一个顶级窗口。

  • Panel无法单独显示,必须添加到某个容器中。

  • 布局管理器

    • 流式布局
    • 边界式布局
    • 方格式布局
  • 大小,定位,背景颜色,定位,监听。

4.5 画笔Paint

package PaintDemo;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;

public class TestPaint {
	public static void main(String[] args) {
		new MyPaint().loadFrame();
	}
}

class MyPaint extends Frame{
	public void loadFrame(){
		setBounds(200,200,600,500);
		setVisible(true);
	}
	// 画笔
	@Override
	public void paint(Graphics g) {
		// 画笔,需要有颜色,画笔可以画画
		g.setColor(Color.red);
		g.drawOval(100, 100, 100, 100);
		
		g.fillOval(100, 100, 100, 100); // 实心的圆
		
		g.setColor(Color.GREEN);
		g.fillRect(150,200, 200, 200);
		
		// 养成习惯,画笔用完,将他还原到最初的颜色
		g.setColor(Color.BLACK);
	}	
}

image-20201221204508064

4.6 事件监听ActionListener

4.6.1 事件监听:当某个时候,触发器被触发而做出的反应

package ActionDemo;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestActionEvent {
	public static void main(String[] args) {
		// 按下按钮,触发一些事件
		Frame frame = new Frame();
		Button button = new Button();
		// 因为,addActionListener()需要一个ActionListener对象,所以我们需要构架一个ActionListener的实现类(ActionListener是一个接口)
		MyActionListener myActionListener = new MyActionListener();
		
		button.addActionListener(myActionListener);
		
		frame.add(button,BorderLayout.CENTER);
		frame.pack();
		
		WindowClose(frame); // 关闭窗口
		frame.setVisible(true);
	}
	
	// 关闭窗口事件
	private static void WindowClose(Frame frame){
		frame.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				System.exit(0);
			}
			
		});
	}
}

// 事件监听
class MyActionListener implements ActionListener{

	@Override
	public void actionPerformed(ActionEvent e) {
		System.out.println("aaa");
	}
}

image-20201221201046749

4.6.2 多个按钮共用一个监听器

package ActionDemo;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class TestActionEvent2 {
	public static void main(String[] args) {
		// 两个按钮,实现同一个监听
		// 开始      停止
		Frame frame = new Frame();
		frame.setLayout(new BorderLayout(3,1));
		Button button1 = new Button("start");
		Button button2 = new Button("stop");
		
		MyActionListener1 myActionListener1 = new MyActionListener1();
		
		button1.addActionListener(myActionListener1);
		button2.addActionListener(myActionListener1);
		
		// button1.setActionCommand("btn_one");
		
		frame.add(button1,BorderLayout.NORTH);
		frame.add(button2,BorderLayout.SOUTH);
		
		frame.pack();
		
		WindowClose(frame); // 关闭窗口
		frame.setVisible(true);
	}
	
	// 关闭窗口事件
	private static void WindowClose(Frame frame){
		frame.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				System.exit(0);
			}
		});
	}
}

// 事件监听
class MyActionListener1 implements ActionListener{
	@Override
	public void actionPerformed(ActionEvent e) {
		// 功能实现的关键
        if(e.getActionCommand().equals("start")){
			System.out.println("开始啦!");
		}else {
			System.out.println("结束啦!");
			System.exit(0);
		}
	}
}

image-20201221201438130

按下stop键,窗口就会消失

4.6.3 输入框监听TextField

package TextFieldDemo;

import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestTextField {
	public static void main(String[] args) {
		// 开启窗口 
		new MyFrame();
	}
}
class MyFrame extends Frame{
	public MyFrame(){
		TextField textField = new TextField();
		add(textField);
		// 监听这个文本框输入的内容
		MyActionListener myActionListener = new MyActionListener();
		// 按下enter 就会触发这个输入框的事件
		textField.addActionListener(myActionListener);
		
		// 设置替换代码,将文本框中输入的文字替换成*
		textField.setEchoChar('*');
		pack();
		setVisible(true);
		
	}
}
class MyActionListener implements ActionListener{
	@Override
	public void actionPerformed(ActionEvent e) {
		// 获得一些资源,返回的是该调用者的对象
		TextField textField = (TextField) e.getSource();
		// 获得输入框中的文本
		System.out.println(textField.getText());
		// 下次再次输入,文框中的文字就会消失
		textField.setText("");
	}
}

image-20201221201627544

4.6.4 作业:简易计算器

image-20201221202108941

  1. 面条版代码

    package TextFieldDemo;
    
    import java.awt.Button;
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    /*
     * 改进版的计算器
     * 	效果图:
     *	     -----	   -----     -----------
     *	   	|  1  | + |  2  | = |     3     |
     *	  	 -----     -----     -----------
     */
    public class HomeWorkPlusOne {
    	public static void main(String[] args) {
    		
    		new Calculator();
    		
    	}
    }
    
    // 简易计算器类
    class Calculator extends Frame{
    	public Calculator(){
    		// 三个文本框 1、2、3
    		TextField textField1 = new TextField(10);
    		TextField textField2 = new TextField(10);
    		TextField textField3 = new TextField(20);
    		// 一个标签 +
    		Label label = new Label("+");
    		// 一个按钮 =
    		Button button = new Button("=");
    		button.addActionListener(new MyCalculatorListener1(textField1, textField2, textField3));
    		
    		setLayout(new FlowLayout());
    		add(textField1);
    		add(label);
    		add(textField2);
    		add(button);
    		add(textField3);
    
    		pack();		
    		setVisible(true);
    		
    		WindowClosed(this);
    	}
    	
    	public static void WindowClosed(Calculator calculator){
    		calculator.addWindowListener(new WindowAdapter() {
    			@Override
    			public void windowClosing(WindowEvent e) {
    				System.exit(0);
    			}
    		});
    	}
    }
    
    // 监听器类
    class MyCalculatorListener1 implements ActionListener{
    	// 获取三个变量
    	private TextField textField1,textField2,textField3;
    
    	public MyCalculatorListener1(TextField textField1,TextField textField2,TextField textField3) {
    		this.textField1 = textField1;
    		this.textField2 = textField2;
    		this.textField3 = textField3;
    	}
    	
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		// 1.获取加数和被加数
    		int num1 = Integer.parseInt(textField1.getText());
    		int num2 = Integer.parseInt(textField2.getText());
    		
    		// 2.将加数和被加数进行+法运算后,放到第三个框中
    		textField3.setText(""+(num1+num2));
    		
    		// 3.清除前两个框中的数据
    		textField1.setText("");
    		textField2.setText("");
    	}
    }
    
  2. 面向对象版

    package TextFieldDemo;
    
    import java.awt.Button;
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    /*
     * 全部面向对象版
     * 	效果图:
     *	     -----	   -----     -----------
     *	   	|  1  | + |  2  | = |     3     |
     *	  	 -----     -----     -----------
     */
    
    // 简易计算器
    public class HomeWorkPlusTwo {
    	public static void main(String[] args) {
    		new Calculator().loadFrame();
    	}
    }
    
    // 简易计算器类
    class Calculator extends Frame{
    	
    	TextField textField1,textField2,textField3;
    
    	public void loadFrame(){
    		
    		textField1 = new TextField(10);
    		textField2 = new TextField(10);
    		textField3 = new TextField(20);
    		
    		Label label = new Label("+");
    		Button button = new Button("=");
    		button.addActionListener(new MyCalculatorListener2(this));
    		
    		setLayout(new FlowLayout());
    		add(textField1);
    		add(label);
    		add(textField2);
    		add(button);
    		add(textField3);
    
    		pack();		
    		setVisible(true);
    		
    		WindowClosed(this);
    	}
    	
    	public static void WindowClosed(Calculator calculator){
    		calculator.addWindowListener(new WindowAdapter() {
    			@Override
    			public void windowClosing(WindowEvent e) {
    				System.exit(0);
    			}
    		});
    	}
    }
    
    //监听器类
    class MyCalculatorListener2 implements ActionListener{
    	private Calculator calculator = null;
    
    	public MyCalculatorListener2(Calculator calculator) {
    		this.calculator = calculator;
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		// 1.获取加数和被加数
    		int num1 = Integer.parseInt(calculator.textField1.getText());
    		int num2 = Integer.parseInt(calculator.textField2.getText());
    		
    		// 2.将加数和被加数进行+法运算后,放到第三个框中
    		calculator.textField3.setText(""+(num1+num2));
    		
    		// 3.清除前两个框中的数据
    		calculator.textField1.setText("");
    		calculator.textField2.setText("");
    	}
    }
    
  3. 内部类版

    package TextFieldDemo;
    
    import java.awt.Button;
    import java.awt.FlowLayout;
    import java.awt.Frame;
    import java.awt.Label;
    import java.awt.TextField;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    /*
     * 内部类版
     * 	效果图:
     *	     -----	   -----     -----------
     *	   	|  1  | + |  2  | = |     3     |
     *	  	 -----     -----     -----------
     */
    
    // 简易计算器
    public class HomeWorkPlusThree {
    	public static void main(String[] args) {
    		new Calculator().loadFrame();
    	}
    }
    
    // 简易计算器类
    class Calculator extends Frame{
    	// 属性
    	TextField textField1,textField2,textField3;
    	// 方法
    	public void loadFrame(){
    		
    		textField1 = new TextField(10); // 字符数 
    		textField2 = new TextField(10); // 字符数
    		textField3 = new TextField(20); // 字符数
    		
    		Label label = new Label("+");
    		Button button = new Button("=");
    		button.addActionListener(new MyCalculatorListener3());
    		
    		setLayout(new FlowLayout());
    		add(textField1);
    		add(label);
    		add(textField2);
    		add(button);
    		add(textField3);
    
    		pack();		
    		setVisible(true);
    		
    		WindowClosed(this);
    	}
    	// 关闭窗口监听事件
    	public static void WindowClosed(Calculator calculator){
    		calculator.addWindowListener(new WindowAdapter() {
    			@Override
    			public void windowClosing(WindowEvent e) {
    				System.exit(0);
    			}
    		});
    	}
    	// 内部类--->监听器类
    	class MyCalculatorListener3 implements ActionListener{
    		@Override
    		public void actionPerformed(ActionEvent e) {
    			// 1.获取加数和被加数
    			int num1 = Integer.parseInt(textField1.getText());
    			int num2 = Integer.parseInt(textField2.getText());
    			
    			// 2.将加数和被加数进行+法运算后,放到第三个框中
    			textField3.setText(""+(num1+num2));
    			
    			// 3.清除前两个框中的数据
    			textField1.setText("");
    			textField2.setText("");
    		}
    	}
    }
    

image-20201221202428443

image-20201221202511404

image-20201221202539380

4.7 窗口监听Window

package ListenerDemo;

import java.awt.Color;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/*
 * 窗口监听事件
 */
public class TestWindowListener {
	public static void main(String[] args) {
		new MyWindowFrame();
	}
}
class MyWindowFrame extends Frame{
	public MyWindowFrame(){
		setBounds(100, 100, 300, 300);
		setBackground(Color.blue);
		setVisible(true);
		// 匿名内部类版
		this.addWindowListener(new WindowAdapter() {
			// 关闭窗口事件
			@Override
			public void windowClosing(WindowEvent e) {
				MyWindowFrame frame = (MyWindowFrame) e.getSource();
				// frame.setVisible(false); // 设置窗口隐藏
				System.out.println("窗口关闭了");
				System.exit(0);
			}
			// 窗口激活事件
			@Override
			public void windowActivated(WindowEvent e) {
				MyWindowFrame frame = (MyWindowFrame) e.getSource();
				frame.setTitle("窗口激活了");
			}
		});
	}
}
// 内部类版
class MyWindowListener extends WindowAdapter{
	// 关闭窗口事件
	@Override
	public void windowClosing(WindowEvent e) {
		MyWindowFrame frame = (MyWindowFrame) e.getSource();
		// frame.setVisible(false);
		System.out.println("窗口关闭了");
		System.exit(0);
	}
	// 激活窗口事件
	@Override
	public void windowActivated(WindowEvent e) {
		MyWindowFrame frame = (MyWindowFrame) e.getSource();
		frame.setTitle("窗口激活了");
	}
}

初始状态

image-20201221203718437

触发后状态

image-20201221203837783

4.8 键盘监听Key

package ListenerDemo;

import java.awt.Frame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class TestKeyListener {
	public static void main(String[] args) {
		new KeyFrame();
	}
}

class KeyFrame extends Frame{
	public KeyFrame(){
		setBounds(100,100,400,400);
		setVisible(true);
		this.addKeyListener(new KeyAdapter() {
			// 键盘按下监听事件
			@Override
			public void keyPressed(KeyEvent e) {
				// 获得键盘按下的键是一个
				int keyCode = e.getKeyCode();
				System.out.println(e.getKeyCode());
				if(keyCode == KeyEvent.VK_UP){
					System.out.println("你按下了上键");
				}
			}
		});
	}
}

image-20201221204135571

4.9 鼠标监听Mouse

package ListenerDemo;

import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 鼠标监听事件
 */
public class TestMouseListener {
	public static void main(String[] args) {
		new MyFrame("画图");
	}
}

// 自己的类
class MyFrame extends Frame{
	// 画画需要画笔,需要监听鼠标当前的位置,需要集合来存储这个点
	private ArrayList points;
	
	public MyFrame(String name){
		super(name);
		setBounds(100, 100, 500, 400);
		// 存鼠标点击的点
		points = new ArrayList<>();
		
		setVisible(true);
		// 鼠标监听器,针对当前这个窗口
		this.addMouseListener(new MyMouseListener());
	}
	
	@Override
	public void paint(Graphics g) {
		// 画画,监听鼠标的事件
		Iterator iterator = points.iterator();
		while(iterator.hasNext()){
			Point point = (Point) iterator.next();
			g.setColor(Color.BLUE);
			g.fillOval(point.x, point.y, 10, 10);
		}
	}
	
	// 添加一个点到界面上
	public void addPoint(Point point){
		points.add(point);
	}
	
	// 适配器模式
	private class MyMouseListener extends MouseAdapter{
		// 鼠标按下、弹起、按住不放
		@Override
		public void mousePressed(MouseEvent e) {
			MyFrame frame = (MyFrame) e.getSource();
			// 我们点击的时候,就会在页面上产生一个点
			// 这个点就是鼠标的点
			frame.addPoint(new Point(e.getX(),e.getY()));
			
			// 每次点击鼠标都需要重新画一遍
			frame.repaint(); // 刷新
		}
	}
}

repaint():在类Container及其子类(如:Frame,Panel)的对象需要重绘repaint时,JVM会自动调用它的public void paint(Graphics g)方法。

image-20201221204254681

代码思路

image-20201222110632124

5.Swing包

5.1 窗口JFrame

  • 概念:java的GUI程序的基本思路是以JFrame为基础,它是屏幕上window的对象,能够最大化、最小化、关闭。

  • 代码实现1

    package JFrameDemo;
    
    import java.awt.Color;
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.WindowConstants;
    
    public class JFrameDemoOne {
    	// 初始化
    	private void init() {
    		// JFrame是一个顶级窗口
    		JFrame jf = new JFrame("这是一个JFrame窗口");
    		jf.setVisible(true);
    		jf.setBounds(100,100,400,400);
    
    		jf.setBackground(Color.BLUE); // 这样设置不生效
    		// 获得该窗口容器,只有给该窗口容器才能设置背景色    container包含JFrame
    		Container container = jf.getContentPane();
    		container.setBackground(Color.CYAN);
    
    		// 设置文字JLabel
    		JLabel label = new JLabel("欢迎来到GUI编程之Swing");
    		
    		jf.add(label);
    
    		// 关闭窗口事件
    		jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		// 建立一个窗口
    		new JFrameDemoOne().init();
    	}
    }
    
  • 效果图1

    image-20201223105923796

  • 代码实现2:文本居中,窗口背景

    package JFrameDemo;
    
    import java.awt.Color;
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingConstants;
    import javax.swing.WindowConstants;
    
    public class JFrameDemoTwo {
    	public static void main(String[] args) {
    		new MyJFrame().init();
    	}
    }
    class MyJFrame extends JFrame{
    	public void init(){
    		// 设置窗口大小位置
    		this.setBounds(100,100,400,400);
    		// 获取该窗口容器,并设置背景色
    		Container container = this.getContentPane();
    		container.setBackground(Color.cyan);
    		// 设置窗口可见
    		this.setVisible(true);
    		// 关闭窗口事件。直接使用JFrame封装好的
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		
    		JLabel jlabel = new JLabel("欢迎来到GUI编程之Swing");
    		// 设置文本标签居中SwingConstants
    		jlabel.setHorizontalAlignment(SwingConstants.CENTER);
    	
    		this.add(jlabel);
    	}
    }
    
  • 效果图2

    image-20201223110120728

5.2 弹窗JDialog

  • 概念:JDialog,用来弹出窗口(报错界面等等)

  • 注意:其自带关闭事件(不需要在写关闭事件)

  • 代码实现

    package DialogDemo;
    
    import java.awt.Container;
    import java.awt.Label;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.WindowConstants;
    
    public class DialogDemoOne extends JFrame{
    	public DialogDemoOne(){
    		
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		
    		// JFrame  放东西,容器
    		Container container = this.getContentPane();
    		// 绝对布局
    		container.setLayout(null);
    		
    		// 创建按钮
    		JButton button = new JButton("点击弹出一个对话框");
    		button.setBounds(30,30,200,50);
    	
    		// 点击这个按钮的时候,踏出一个对话框
    		button.addActionListener(new ActionListener() { // 监听器
    			
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				// 弹窗
    				new MyDialog();
    			}
    		});
    	
    		container.add(button);
    	}
    	public static void main(String[] args) {
    		new DialogDemoOne();
    	}
    }
    // 弹窗的窗口
    class MyDialog extends JDialog{
    	public MyDialog(){
    		this.setVisible(true);
    		this.setBounds(100,100,500,500);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		
    		Container container = this.getContentPane();
    		container.setLayout(null);
    		container.add(new Label("小骚老师带你学java"));
    	}
    }
    
  • 效果图

    image-20201223110410513

    image-20201223110556555

5.3 面板JPanel

  • 概念:Java图形用户界面(GUI)工具包swing中的面板容器类,包含在javax.swing 包中,可以进行嵌套,功能是对窗体中具有相同逻辑功能的组件进行组合,是一种轻量级容器,可以加入到JFrame窗体中。

  • 代码实现(普通面板)

    package JPanelDemo;
    
    import java.awt.Button;
    import java.awt.Container;
    import java.awt.GridLayout;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.WindowConstants;
    
    /*
     * 普通面板
     */
    public class JPanelDemoOne extends JFrame{
    	public JPanelDemoOne(){
    		Container container = this.getContentPane();
    		
    		container.setLayout(new GridLayout(2,1,10,10)); // 后面的参数的意思是,间距
    		
    		JPanel panel1 = new JPanel(new GridLayout(1,3));
    		JPanel panel2 = new JPanel(new GridLayout(2,1));
    		JPanel panel3 = new JPanel(new GridLayout(2,2));
    		JPanel panel4 = new JPanel(new GridLayout(3,2));
    
    		panel1.add(new Button("1"));
    		panel1.add(new Button("1"));
    		panel1.add(new Button("1"));
    		panel2.add(new Button("2"));
    		panel2.add(new Button("2"));
    		panel3.add(new Button("3"));
    		panel3.add(new Button("3"));
    		panel3.add(new Button("3"));
    		panel3.add(new Button("3"));
    		panel4.add(new Button("4"));
    		panel4.add(new Button("4"));
    		panel4.add(new Button("4"));
    		panel4.add(new Button("4"));
    		panel4.add(new Button("4"));
    		panel4.add(new Button("4"));
    		
    		container.add(panel1);
    		container.add(panel2);
    		container.add(panel3);
    		container.add(panel4);
    		
    		this.setVisible(true);
    		this.setSize(500,500);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		new JPanelDemoOne();
    	}
    }
    
  • 效果图(普通面板)

    image-20201223170202493

  • 代码示例(滚动面板)JScrollPane

    package JPanelDemo;
    
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.WindowConstants;
    
    /*
     * 滚动面板
     */
    public class JPanelDemoTwo extends JFrame{
    	
    	public JPanelDemoTwo(){
    		Container container = this.getContentPane();
    		
    		// 文本域
    		JTextArea textArea = new JTextArea(20,50);
    		textArea.setText("欢迎学习GUI之Swing编程");
    		
    		// Scroll面板
    		JScrollPane scrollPane = new JScrollPane(textArea);
    		container.add(scrollPane);
    		
    		this.setVisible(true);
    		this.setBounds(100,100,300,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		new JPanelDemoTwo();
    	}
    }
    
  • 效果图(滚动面板)

    image-20201223170327415

5.4 按钮JButton

  • 概念: JButton 类的实例。用于创建按钮类似实例中的 "Login"。

5.4.1 图片按钮ImageIcon

  • 代码示例

    package JButtonDemo;
    
    import java.awt.Container;
    import java.net.URL;
    
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.WindowConstants;
    
    /*
     * 图片按钮
     */
    public class JButtonDemoOne extends JFrame{
    	public JButtonDemoOne(){
    		Container container = this.getContentPane();
    		
    		// 讲一个图片变成图标
    		URL url = JButtonDemoOne.class.getResource("头像.png");
    		ImageIcon icon = new ImageIcon(url);
    		
    		// 把这个图标放在按钮上
    		JButton button = new JButton();
    		button.setIcon(icon);
    		// 鼠标悬浮上去显示的提示信息
    		button.setToolTipText("图片按钮");
    		// 向容器中添加按钮
    		container.add(button);
    	
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
    	}
    	
    	public static void main(String[] args) {
    		new JButtonDemoOne();
    	}
    }
    
  • 效果图

    image-20201223170558689

5.4.2 单选框JRadioButton

  • 示例代码

    package JButtonDemo;
    
    import java.awt.BorderLayout;
    import java.awt.Container;
    
    import javax.swing.ButtonGroup;
    import javax.swing.JFrame;
    import javax.swing.JRadioButton;
    import javax.swing.WindowConstants;
    
    public class JButtonDemoTwo extends JFrame{
    	public JButtonDemoTwo(){
    		Container container = this.getContentPane();
    		
    		// 单选框
    		JRadioButton radiobutton1 = new JRadioButton("radiobutton1");
    		JRadioButton radiobutton2 = new JRadioButton("radiobutton2");
    		JRadioButton radiobutton3 = new JRadioButton("radiobutton3");
    		
    		// 由于单选框只能选择一个,所以需要给按钮分组
    		ButtonGroup group = new ButtonGroup();
    		group.add(radiobutton1);
    		group.add(radiobutton2);
    		group.add(radiobutton3);
    		
    		// 向容器中添加单选框按钮
    		container.add(radiobutton1,BorderLayout.NORTH);
    		container.add(radiobutton2,BorderLayout.CENTER);
    		container.add(radiobutton3,BorderLayout.SOUTH);
    
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
        
    	public static void main(String[] args) {
    		new JButtonDemoTwo();
    	}
    }
    
  • 效果图

    image-20201223170739117

5.4.3 多选框Checkbox

  • 示例代码

    package JButtonDemo;
    
    import java.awt.BorderLayout;
    import java.awt.Checkbox;
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.WindowConstants;
    
    public class JButtonDemoThree extends JFrame{
    	public JButtonDemoThree(){
    		Container container = this.getContentPane();
    		
    		// 多选框
    		Checkbox checkbox1 = new Checkbox("记住密码");
    		Checkbox checkbox2 = new Checkbox("忘记密码");
    		Checkbox checkbox3 = new Checkbox("设置密码");
    		
    		// 向容器中添加多选框
    		container.add(checkbox1,BorderLayout.NORTH);
    		container.add(checkbox2,BorderLayout.CENTER);
    		container.add(checkbox3,BorderLayout.SOUTH);
    		
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    
    	}
    	
    	public static void main(String[] args) {
    		new JButtonDemoThree();
    	}
    }
    
  • 效果图

    image-20201223170854573

5.5 列表

5.5.1 下拉框JComboBox

  • 代码示例

    package ComboboxDemo;
    
    import java.awt.Container;
    
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.WindowConstants;
    
    /*
     * 下拉框
     */
    public class ComboboxDemoOne extends JFrame{
    	public ComboboxDemoOne() {
    		Container container = this.getContentPane();
    		
    		// 下拉框
    		JComboBox status = new JComboBox();
    		
    		status.addItem(null);
    		status.addItem("正在上映");
    		status.addItem("即将上映");
    		status.addItem("即将下架");
    		
    		// 获取下拉框中的内容,需要绑定一个点击事件,然后通过e.getSource()获取status对象,通过getText()方法即可获取文本信息
    		// status.addActionListener();
    		
    		container.add(status);
    
    		this.setVisible(true);
    		this.setBounds(100,100,500,500);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    
    	public static void main(String[] args) {
    		new ComboboxDemoOne();
    	}
    }
    
  • 效果图

    image-20201223171656116

    image-20201223171758518

5.5.2 列表框JList

  • 示例代码

    package ComboboxDemo;
    
    import java.awt.Container;
    import java.util.Vector;
    
    import javax.swing.JFrame;
    import javax.swing.JList;
    import javax.swing.WindowConstants;
    
    /*
     * 列表框
     */
    public class ComboboxDemoTwo extends JFrame{
    	public ComboboxDemoTwo() {
    		Container container = this.getContentPane();
    		
    		// 列表框
    		
    		/*方式一:
    			 生成了列表的内容        	此方法是稀疏数组,压缩数据(本质上还是数组)
    			此方法将列表中的数据写死了,所以不可取
    			String[] contents = {"1","2","3","4","5"};
    			
    			列表中需要放入内容
    			JList jList = new JList(contents);
    		*/
    		
    		// 方式二:推荐(看情况使用)
    		Vector contents = new Vector();
    		
    		// 动态向contents数组中添加数据
    		contents.add("1");
    		contents.add("2");
    		contents.add("3");
    		contents.add("4");
    		contents.add("5");
    		
    		// 列表中需要放入内容
    		JList jList = new JList(contents);
    		
    		container.add(jList);
    		this.setVisible(true);
    		this.setBounds(100,100,500,500);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    
    	public static void main(String[] args) {
    		new ComboboxDemoTwo();
    	}
    }
    
  • 效果图

    image-20201223171910784

5.6 文本框

5.6.1 文本框JTextField

  • 示例代码

    package TextDemo;
    
    import java.awt.BorderLayout;
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JTextField;
    import javax.swing.WindowConstants;
    
    /*
     * 文本框
     */
    public class TextDemoOne extends JFrame{
    	public TextDemoOne(){
    		Container container = this.getContentPane();
    		
    		// 创建文本框
    		JTextField textField1 = new JTextField("hello");
    		JTextField textField2 = new JTextField("world",20);
    		
    		// 添加文本框到窗口容器中
    		container.add(textField1,BorderLayout.NORTH);
    		container.add(textField2,BorderLayout.SOUTH);
    		
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		new TextDemoOne();
    	}
    }
    
  • 效果图

    image-20201223174402543

5.6.2 密码框JPasswordField

  • 代码样式

    package TextDemo;
    
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JPasswordField;
    import javax.swing.WindowConstants;
    
    /*
     * 密码框:输入的密码默认是居中显示
     */
    public class TextDemoTwo extends JFrame{
    	public TextDemoTwo(){
    		Container container = this.getContentPane();
    		
    		// 创建密码框对象
    		JPasswordField passwordField = new JPasswordField();
    		// 设置密码的样式
    		passwordField.setEchoChar('*');
    		
    		// 添加密码框到窗口容器中
    		container.add(passwordField);
    		
    		this.setVisible(true);
    		this.setBounds(100,100,400,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		new TextDemoTwo();
    	}
    }
    
  • 效果图

    image-20201223174546885

5.6.3 文本域

  • 示例代码

    package TextDemo;
    
    import java.awt.Container;
    
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.WindowConstants;
    
    public class TextDemoThree extends JFrame{
    	
    	public TextDemoThree(){
    		Container container = this.getContentPane();
    		
    		// 文本域
    		JTextArea textArea = new JTextArea(20,50);
    		textArea.setText("欢迎学习GUI之Swing编程");
    		
    		// Scroll面板
    		JScrollPane scrollPane = new JScrollPane(textArea);
    		container.add(scrollPane);
    		
    		this.setVisible(true);
    		this.setBounds(100,100,300,400);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	
    	public static void main(String[] args) {
    		new TextDemoThree();
    	}
    
    }
    
  • 效果图

    image-20201223174637091

5.7 图标

5.7.1 标签图标

  • 示例代码

    package IconDemo;
    
    import java.awt.Component;
    import java.awt.Container;
    import java.awt.Graphics;
    
    import javax.swing.Icon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingConstants;
    import javax.swing.WindowConstants;
    
    /*
     * 标签图标,图标添加到标签上
     */
    
    // 图标,需要实现类,继承JFrame
    public class IconDemoOne extends JFrame implements Icon{
    	private int width;
    	private int height;
    	
    	// 无参构造
    	public IconDemoOne(){
    		
    	}
    	// 有参构造
    	public IconDemoOne(int width, int height){
    		this.width = width;
    		this.height = height;
    	}
    	// 初始化
    	public void init(){
    		// 图标放在标签上,也可以放在按钮上
    		JLabel label = new JLabel("icontest",this,SwingConstants.CENTER);
    		
    		Container container = this.getContentPane();
    		container.add(label);
    		
    		this.setVisible(true);
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	// 程序主入口
    	public static void main(String[] args) {
    			new IconDemoOne(10,10).init();
    	}
    
    	// 实现Icon所需要的重写的方法
    	@Override
    	public void paintIcon(Component c, Graphics g, int x, int y) {
    		g.fillOval( x, y, this.height, this.width);
    	}
    	@Override
    	public int getIconWidth() {
    		return this.width;
    	}
    	@Override
    	public int getIconHeight() {
    		return this.height;
    	}
    }
    
  • 效果图

    image-20201223172159648

5.7.2 图片图标

  • 示例代码

    package IconDemo;
    
    import java.awt.Container;
    import java.net.URL;
    
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingConstants;
    import javax.swing.WindowConstants;
    
    /*
     * 图片图标,图标是一张图片
     */
    
    public class IconDemoTwo extends JFrame{
    	// 构造方法	
    	public IconDemoTwo(){
    		// 创建一个标签,用于添加图标
    		JLabel label = new JLabel("ImageIcon");
    		// 获取图片地址,是当前类的位置
    		// URL url = ImageIcon.class.getResource("头像.png");
    		URL url = IconDemoTwo.class.getResource("头像.png");
    		// 创建一个图片图标对象
    		ImageIcon imageIcon = new ImageIcon(url);
    		// 将图片图标对象添加到标签中
    		label.setIcon(imageIcon);
    		// 设置标签中的内容居中显示
    		label.setHorizontalAlignment(SwingConstants.CENTER);
    		// 获取当前的窗口容器
    		Container container = this.getContentPane();
    		// 将标签添加到窗口容器中
    		container.add(label);
    		// 设置窗口可见
    		this.setVisible(true);
    		// 关闭窗口点击事件
    		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    	}
    	// 程序主入口
    	public static void main(String[] args) {
    		new IconDemoTwo();
    	}
    }
    
  • 效果图

    image-20201223172634684

6. 贪吃蛇案例

  • StartGame.java

    package Snake;
    
    import javax.swing.JFrame;
    import javax.swing.WindowConstants;
    
    /*
     * 游戏设计步骤
     * 		1.定义数据
     * 		2.画上去信息
     * 		3.监听事件
     * 			(1)、键盘监听
     * 			(2)、事件监听
     */
    
    // 游戏的主启动类
    public class StartGame {
    	public static void main(String[] args) {
    		JFrame frame = new JFrame();
    		
    		frame.setBounds(10,10,900,720);
    		frame.setResizable(false); // 设置窗口大小不可变化
    		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    		
    		// 正常的游戏界面应该放在面板上
    		frame.add(new GamePanel());
    		
    		frame.setVisible(true);
    	}
    }
    
  • GamePanel.java

    package Snake;
    
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.Random;
    
    import javax.swing.JPanel;
    import javax.swing.Timer;
    
    // 游戏的面板
    public class GamePanel extends JPanel implements KeyListener,ActionListener{
    	// 定义蛇的数据结构
    	int length;
    	int[] snakeX = new int[600];
    	int[] snakeY = new int[500];
    	String direction; // 定义蛇的方向
    	 // 食物的坐标
    	int foodX;
    	int foodY;
    	
    	Random random = new Random();
    	int score; // 成绩
    	
    	boolean isStart = false; // 游戏当前状态,开始or停止       默认是停止的 
    	boolean isFail = false; // 游戏失败状态
    	
    	// 定时器    以毫秒为单位	  1000ms = 1s
    	Timer timer = new Timer(100, this); // 100毫秒执行一次	
    	
    	// 构造器
    	public GamePanel(){
    		init();
    		// 获得焦点和键盘事件
    		this.setFocusable(true); // 获得焦点事件
    		this.addKeyListener(this); // 获得键盘监听事件
    		timer.start(); // 游戏一开始定时器就启动
    	}
    	
    	// 初始化方法
    	public void init(){
    		length = 3;
    		snakeX[0] = 100;snakeY[0] = 100; // 蛇脑袋坐标
    		snakeX[1] = 75;snakeY[1] = 100; // 第一个身体的坐标
    		snakeX[2] = 50;snakeY[2] = 100; // 第二个身体的坐标
    		direction = "R"; // 初始方向向右
    		
    		// 把食物随机分配在界面上
    		foodX = 25 + 25*random.nextInt(34);
    		foodY = 75 + 25*random.nextInt(24);
    		
    		score = 0; // 初始化成绩为0
    		
    	}
    
    	// 绘制面板,我们游戏中的所有东西,都是用这个画笔来画的
    	@Override
    	protected void paintComponent(Graphics g) {
    		super.paintComponent(g); // 清屏
    		// 绘制静态的面板
    		this.setBackground(Color.WHITE);
    		Data.header.paintIcon(this, g, 25, 11); // 头部广告栏画上去
    		g.fillRect(25, 75, 850, 600); // 默认的游戏界面
    		
    		// 画积分
    		g.setColor(Color.white);
    		g.setFont(new Font("微软雅黑",Font.BOLD,18));
    		g.drawString("长度   "+length, 750, 35);
    		g.drawString("分数    "+score, 750, 50);
    		
    		
    		// 把食物画上面板
    		Data.food.paintIcon(this, g, foodX, foodY);
    		
    		
    		// 把小蛇画上去
    		if(direction.equals("R")){
    			Data.right.paintIcon(this, g, snakeX[0], snakeY[0]); // 蛇的初始化方向向右,需要通过方向来判断
    		}else if(direction.equals("L")){
    			Data.left.paintIcon(this, g, snakeX[0], snakeY[0]); // 蛇的初始化方向向左,需要通过方向来判断
    		}else if(direction.equals("U")){
    			Data.up.paintIcon(this, g, snakeX[0], snakeY[0]); // 蛇的初始化方向向上,需要通过方向来判断
    		}else if(direction.equals("D")){
    			Data.down.paintIcon(this, g, snakeX[0], snakeY[0]); // 蛇的初始化方向向下,需要通过方向来判断
    		}
    		
    		
    		
    		
    		for (int i = 1; i < length; i++) {
    			Data.body.paintIcon(this, g, snakeX[i], snakeY[i]); // 第一个身体的坐标
    		}
    		
    		// 游戏状态
    		if(isStart == false){
    			g.setColor(Color.WHITE);
    			g.setFont(new Font("微软雅黑", Font.BOLD, 40)); // 设置字体
    			g.drawString("按下空格开始游戏", 300,300);
    		}
    		
    		if(isFail){
    			g.setColor(Color.RED);
    			g.setFont(new Font("微软雅黑", Font.BOLD, 18)); // 设置字体
    			g.drawString("失败,按下空格重新开始", 300,300);
    		}
    	}
    
    	// 键盘监听事件
    	@Override
    	public void keyPressed(KeyEvent e) {
    		int keyCode = e.getKeyCode(); // 获得键盘按下的是哪个键
    		if(keyCode == KeyEvent.VK_SPACE){ // 如果按下的是空格键
    			if(isFail){
    				// 重新开始
    				isFail = false;
    				init();
    			}else {
    				isStart = !isStart; // 取反
    			}
    			repaint();
    		}
    		// 小蛇移动
    		if(keyCode == KeyEvent.VK_UP){
    			direction = "U";
    		}else if(keyCode == KeyEvent.VK_DOWN){
    			direction = "D";
    		}else if(keyCode == KeyEvent.VK_LEFT){
    			direction = "L";
    		}else if(keyCode == KeyEvent.VK_RIGHT){
    			direction = "R";
    		}
    		
    		
    	}
    
    	// 事件监听------需要通过固定事件来刷新  1s=10次
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if(isStart && isFail == false){ // 如果游戏是开始状态,就让小蛇动起来
    			
    			// 吃食物
    			if(snakeX[0] == foodX && snakeY[0] == foodY){
    				// 长度 +1
    				length++;
    				
    				score += 10; // 分数+10
    				
    				// 再次随机食物出现
    				foodX = 25 + 25*random.nextInt(34);
    				foodY = 75 + 25*random.nextInt(24);
    				
    			}
    			
    			
    			// 移动
    			for(int i = length - 1; i>0;i--){ // 后一节移动到前一节的位置 snakeX[0] = snakeX[1]
    				snakeX[i] = snakeX[i-1];
    				snakeY[i] = snakeY[i-1];
    			}
    			// 走向
    			if(direction.equals("R")){
    				snakeX[0] = snakeX[0] + 25;
    				if(snakeX[0]>850){snakeX[0] = 25;} // 边界判断
    			}else if(direction.equals("L")){
    				snakeX[0] = snakeX[0] - 25;
    				if(snakeX[0]<25){snakeX[0] = 850;} // 边界判断
    			}else if(direction.equals("U")){
    				snakeY[0] = snakeY[0] - 25;
    				if(snakeY[0]<75){snakeY[0] = 650;} // 边界判断
    			}else if(direction.equals("D")){
    				snakeY[0] = 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]){
    					isFail = true;
    				}
    			}
    			
    			repaint(); // 重画页面
    		}
    		timer.start(); // 定时器开启
    	}
    
    	@Override
    	public void keyReleased(KeyEvent e) {
    	}
    	
    	@Override
    	public void keyTyped(KeyEvent e) {
    	}
    }
    
  • Data.java

    package Snake;
    
    import java.net.URL;
    
    import javax.swing.ImageIcon;
    
    // 数据中心 录入游戏所需的数据
    public class Data {
    	
    	// 相对路径   tx.txt
    	// 绝对路径  /相当于当前的项目
    	public static URL headerURL = Data.class.getResource("statics/header.jpg");
    	public static ImageIcon header = new ImageIcon(headerURL);
    	
    	public static URL bodyURL = Data.class.getResource("statics/body.png");
    	public static ImageIcon body = new ImageIcon(bodyURL);
    	
    	public static URL downURL = Data.class.getResource("statics/down.png");
    	public static ImageIcon down = new ImageIcon(downURL); 
    	
    	public static URL upURL = Data.class.getResource("statics/up.png");
    	public static ImageIcon up = new ImageIcon(upURL); 
    	
    	public static URL leftURL = Data.class.getResource("statics/left.png");
    	public static ImageIcon left = new ImageIcon(leftURL); 
    	
    	public static URL rightURL = Data.class.getResource("statics/right.png");
    	public static ImageIcon right = new ImageIcon(rightURL); 
    	
    	public static URL foodURL = Data.class.getResource("statics/food.png");
    	public static ImageIcon food = new ImageIcon(foodURL); 
    }
    
    
  • 效果图

    • 开始状态

      image-20201225121223485

    • 死亡状态

      image-20201224215158419

原文地址:https://www.cnblogs.com/borntodie/p/14188306.html