02-GUI.md

GUI

GUI组件 : 跟web和windows一样

  • 窗口
  • 弹窗
  • 面板
  • 文本框
  • 列表
  • 按钮
  • 图片
  • 事件
    • 鼠标事件
    • 键盘事件

简介:

GUI的核心技术: Swing和AWT

学习的目的:

1. 了解MVC架构,了解监听. 思考守护线程的意义; (自己实现一个计算器);

AWT:

1.核心架构图:

2.组件(Componet)和容器(Container):

Panel:
  1. 可以看做是一个看不见的盒子,类似div和span;
  2. 不能单独存在,需要放到Frame容器中;
  3. Panel从源码中看到构造方法是需要布局的;如下图: FlowLayout:流布局

image-20210322200711699

3.布局方式:

1. 流式布局(FlowLayout): 
   	1. ![image-20210323095618565](I:\Java\java书籍\java笔记\自己的\image-20210323095618565.png)
2. 东西南北中-布局(BorderLayout):
   	1. ![image-20210323100008440](I:\Java\java书籍\java笔记\自己的\image-20210323100008440.png)
3. 表格布局(栅格布局GridLayout):  也就是表格
   	1. ![image-20210323100202207](I:\Java\java书籍\java笔记\自己的\image-20210323100202207.png)

4.事件监听(ActionListener):

  1. OOP原则 : 组合 优先于继承;

    1. 在阿里的java开发手册里面提到;
    2. 在Thinking in java 书中,也有提到;
  2. 内部类的最大好处就是可以畅通无阻的访问外部类的属性和方法!

  3. 基于事件监听-实现一个简单的计算器, 模拟面向过程面向对象的演变. 更好理解面向对象编程思想

    1. main方法中不能创建非静态内部类对象 ->如下:

      1. image-20210323112534374
        2. 原因: 在类中,非静态方法能够创建内部类对象是因为类中隐含了this关键字;如
        1. image-20210323112724755
          2. 因为this即是对象,所以静态方法main()方法要创建内部类对象,需要先有外部类对象,即是main方法所在对象,才能通过外部类对象来创建内部类对象;
          3. 更改后代码:
          1. image-20210323113008744
    2. 面向过程的 事件监听 代码如下:

      1. package com.xiaohei.awt;
        import java.awt.*;
        import java.awt.event.*;
        public class AWT_OOP {
            public static void main(String[] args) {
                //new JiSuanQi();
                new AWT_OOP().new JiSuanQi();
            }
            class JiSuanQi extends Frame {
              	//此处面向过程编程的原因: 当前类JiSuanQi中无对象属性 无行为方法;
                public JiSuanQi() {
                    //采用的布局:流式布局
                    setLayout(new FlowLayout());
                    //3个文本框,1个标签,1个=号按钮
                    TextField t1 = new TextField(10); // this("文本信息", 字符长度);
                    TextField t2 = new TextField(10); // this("文本信息", 字符长度);
                    TextField t3 = new TextField(20); // this("文本信息", 字符长度);
                    Label label = new Label("+"); //+号  
                    Button button = new Button("="); //=号按钮,  
                    //添加监听事件
                    button.addActionListener(new MyJiSuanQiListener(t1,t2,t3));
                    //按照流式布局方式添加容器
                    add(t1);
                    add(label);
                    add(t2);
                    add(button);
                    add(t3);
                    //设置frame属性
                    setSize(500, 100);
                    setVisible(true);
                }
            }
            class MyJiSuanQiListener implements ActionListener {
                //此处面向过程的原因:下面这段代码中,t1,t2,t3均是计算器类中的属性;
                //应当使用组合的方式将其更改为操作对象来操作组合对象中的属性;
                //OOP的核心思想就是 通过操作对象来操作对象的属性和方法
                TextField t1;
                TextField t2;
                TextField t3;
                //需要三个文本域对象,要对其进行操作,通过构造方法传参
                public MyJiSuanQiListener(TextField t1,TextField t2,TextField t3) {
                    this.t1 = t1;
                    this.t2 = t2;
                    this.t3 = t3;
                }
                @Override
                public void actionPerformed(ActionEvent e) {
                    //获取文本框输入内容,并转换成数字
                    int a = Integer.parseInt(t1.getText());
                    int b = Integer.parseInt(t2.getText());
                    //清空前俩文本框
                    t1.setText("");
                    t2.setText("");
                    //将2个数相加的值写入第三个文本框
                    t3.setText(""+(a+b));
                }
            }
        }
        
    3. 面向对象的事件监听 代码如下:

      1. package com.xiaohei.awt;
        import java.awt.*;
        import java.awt.event.*;
        public class AWT_OOP {
            public static void main(String[] args) {
                //面向对象,全程对象调方法
                new AWT_OOP().new JiSuanQi().initLoad();
            }
            class JiSuanQi extends Frame {
                TextField t1;
                TextField t2;
                TextField t3;
                public void initLoad() {
                    setLayout(new FlowLayout());
                    t1 = new TextField(10);
                    t2 = new TextField(10);
                    t3 = new TextField(20);
                    Label label = new Label("+");
                    Button button = new Button("=");
                    button.addActionListener(new MyJiSuanQiListener(this));
                    add(t1);
                    add(label);
                    add(t2);
                    add(button);
                    add(t3);
                    setSize(500, 100);
                    setVisible(true);
                }
            }
            class MyJiSuanQiListener implements ActionListener {
                private JiSuanQi jiSuanQi;
                public MyJiSuanQiListener(JiSuanQi jiSuanQi) {
                    this.jiSuanQi = jiSuanQi;
                }
                @Override
                public void actionPerformed(ActionEvent e) {
                    int a = Integer.parseInt(jiSuanQi.t1.getText());
                    int b = Integer.parseInt(jiSuanQi.t2.getText());
                    jiSuanQi.t1.setText("");
                    jiSuanQi.t2.setText("");
                    jiSuanQi.t3.setText(""+(a+b));
                }
            }
        }
        
    4. 更加面向对象的事件监听->内部类:

      1. package com.xiaohei.awt;
        
        import java.awt.*;
        import java.awt.event.*;
        
        public class AWT_OOP {
            public static void main(String[] args) {
                //面向对象,全程对象调方法
                new AWT_OOP().new JiSuanQi().initLoad();
            }
            class JiSuanQi extends Frame {
                TextField t1;
                TextField t2;
                TextField t3;
                public void initLoad() {
                    setLayout(new FlowLayout());
                    t1 = new TextField(10);
                    t2 = new TextField(10);
                    t3 = new TextField(20);
                    Label label = new Label("+");
                    Button button = new Button("=");
                    button.addActionListener(new MyJiSuanQiListener());
                    add(t1);
                    add(label);
                    add(t2);
                    add(button);
                    add(t3);
                    setSize(500, 100);
                    setVisible(true);
                }
                //直接将监听事件放到了计算器JiSuanQi类中;不用再传入JiSuanQi类
                //内部类直接访问外部类成员;private更体现了OOP的特性之一封装.
                //所以更加的面向对象
                private class MyJiSuanQiListener implements ActionListener {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int a = Integer.parseInt(t1.getText());
                        int b = Integer.parseInt(t2.getText());
                        t1.setText("");
                        t2.setText("");
                        t3.setText(""+(a+b));
                    }
                }
            }
        }
        
      2. 内部类更加体现了什么叫做面向对象;

5.画笔:public void paint(Graphics g) :

  1. paint: 画笔; Graphics 画笔设置;

  2. 模仿windows的画板,使用画笔在画板上画点(鼠标监听):

    1. image-20210323150303221

    2. package com.xiaohei.awt;
      import java.awt.*;
      import java.awt.event.MouseAdapter;
      import java.awt.event.MouseEvent;
      import java.util.ArrayList;
      import java.util.Iterator;
      /**
       * 模仿windows画图
       */
      public class AWT_Paint {
          public static void main(String[] args) {
              new MyFrame();
          }
      }
      class MyFrame extends Frame {
          private ArrayList<Point> points;
          public MyFrame() {
              //要初始化一个画板
              setBounds(100, 100, 500, 500);
              setVisible(true);
              points = new ArrayList<>();
              //需要一个鼠标监听事件
              addMouseListener(new MyMouseListener());
          }
          @Override
          public void paint(Graphics g) {
              if (points != null) {
                  //根据鼠标点击过的点来进行绘制每一个点
                  Iterator<Point> iterator = points.iterator();
                  g.setColor(Color.RED);
                  while (iterator.hasNext()) {
                      Point point = iterator.next();
                      g.fillOval((int) point.getX(), (int) point.getY(), 10, 10);
                  }
              }
          }
          private class MyMouseListener extends MouseAdapter {
              @Override
              public void mousePressed(MouseEvent e) {
                  //要获取鼠标当前点击的坐标,存放到point中
                  Point point = new Point(e.getX(), e.getY());
                  //添加到鼠标点击过的点集合中
                  points.add(point);
                  //每次点击都让画笔重新画画
                  repaint();
              }
          }
      }
      

贪吃蛇

  1. 需要一个游戏窗口 :设置游戏窗口的默认大小: 宽1000,长:875
  2. 需要一个Panel来放置游戏载体,并将该Panel放到游戏窗口中
    1. 面板的大小 需要小于游戏窗口25
    2. 面板背景颜色为黑色,将面板加入游戏窗口容器Container中
    3. 所有动画都将画在该panel面板上
posted @ 2021-03-29 22:39  坚毅java  阅读(70)  评论(0)    收藏  举报