GUI笔记

1、简介

​ GUI的核心技术:Swing、AWT。

  • why? :
    • 可以写出一些心中想要的小工具(外挂?);
    • 工作室,可能需要维护到swing界面(低概率);
    • 了解MVC架构、监听;

2、AWT

2.1、AWT介绍

1、包含了很多类和接口!GUI!

2、元素:窗口、按钮、文本框;

3、java.awt image-20220226124526440

2.2、 组件和容器

Frame

package com.company;

import java.awt.*;

/**
 * 我的第一个GUI界面
 */
public class TestFrame {
    public static void main(String[] args) {
        MyFrame myFrame1 = new MyFrame(300, 300, 1980, 1080, Color.cyan);
        MyFrame myFrame2 = new MyFrame(500, 500, 1980, 1080, Color.cyan);
    }
}


//自定义的图形界面
class MyFrame extends Frame {
    static int id =0;//有可能会打开多个窗口,给窗口一个编号;
     //修改构造器
    public MyFrame(int x,int y,int w,int h,Color color){
        super("我的图形界面"+id++);//调用父类构造器,设置标题
        setBackground(color);//设置背景
        setBounds(x,y,w,h);//打开的位置,大小
        setVisible(true);//设置可视化
    }
}

面板(Panel)

Panel 可以看成是一个空间,但是不能单独存在

解决了关闭事件;

package com.company;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

/**
 * panel    可以看成是一个空间,但是不能单独存在
 *
 */
public class TestPanel {
    public static void main(String[] args) {
        Frame frame = new Frame();
        Panel panel = new Panel();

        //设置布局
        frame.setLayout(null);

        //坐标
        frame.setBounds(300,300,500,500);
        frame.setBackground(new Color(48, 114, 177));

        //Panel设置坐标
        panel.setBounds(50,50,250,250);
        panel.setBackground(new Color(1, 37, 8));
        //frame.add(panel)
        frame.add(panel);

        frame.setVisible(true);

        //监听事件,关闭窗口 System.exit(0)
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.exit(0);
            }
        });
    }
}

2.3、布局管理器

  • 流式布局(默认)

    package com.company;
    
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    /**
     * 流式布局案例
     */
    public class TestFlowLayout {
        public static void main(String[] args) {
            Frame frame =new Frame("流式布局窗口");
            frame.setSize(300,300);
    
            Button button1 = new Button("button1");
            Button button2 = new Button("button2");
            Button button3 = new Button("button3");
            //设置为流式布局
            frame.setLayout(new FlowLayout());
            frame.setVisible(true);
            //添加按钮
            frame.add(button1);
            frame.add(button2);
            frame.add(button3);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    super.windowClosing(e);
                    System.exit(0);
                }
            });
        }
    }
    
    
  • 东西南北中

    package com.company;
    
    import java.awt.*;
    
    /**
     * 测试东西南北中布局
     */
    public class TestBorderLayout {
        public static void main(String[] args) {
            Frame frame = new Frame("测试东西南北中布局---");
    
            Button east = new Button("east");
            Button west = new Button("west");
            Button south = new Button("south");
            Button north = new Button("north");
            Button centre = new Button("centre");
    
            frame.add(east,BorderLayout.EAST);
            frame.add(west,BorderLayout.WEST);
            frame.add(south,BorderLayout.SOUTH);
            frame.add(north,BorderLayout.NORTH);
            frame.add(centre,BorderLayout.CENTER);
    
            frame.setSize(300,300);
            frame.setVisible(true);
        }
    }
    
    
  • 表格式布局

    package com.company;
    
    import java.awt.*;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    /**
     * 测试表格布局
     */
    public class TestGridLayout {
        public static void main(String[] args) {
            Frame frame = new Frame("测试表格式布局---");
    
            Button b1 = new Button("b1");
            Button b2 = new Button("b2");
            Button b3 = new Button("b3");
            Button b4 = new Button("b4");
            Button b5 = new Button("b5");
            Button b6 = new Button("b6");
            Button b7 = new Button("b7");
            Button b8 = new Button("b8");
    
            frame.setLayout(new GridLayout(3,3));
    
            frame.add(b1);
            frame.add(b2);
            frame.add(b3);
            frame.add(b4);
            frame.add(b5);
            frame.add(b6);
            frame.add(b7);
            frame.add(b8);
    
            
            frame.setSize(600,600);
            frame.setVisible(true);
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
        }
    }
    
    

2.4、事件监听

当某个事件发生时,做如何响应?

  • 可以定义自己的实现类来实现ActionListener ;
  • 也可以通过匿名内部类单独实现响应监听事件(或者Lambda表达式实现)
  • 通过修改ActionCommand的按钮内容可以灵活用多个按钮实现一个监听事件,省略重复实现(定义或创建实现类)的方法;
package com.company.GUI;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 《监听事件--案例》
 * 两个按钮同时使用同一个监听器
 * 另:通过对ActionCommand的修改,可以让监听事件针对不同的按钮实现不同的相应;
 */
public class TestAction {
    public static void main(String[] args) {
        Frame frame =new Frame("监听事件案例");
        Button bt1 =new Button("start");
        Button bt2 =new Button("stop");
        //利用actioncommand可以灵活设置按钮对同一监听事件运用
        bt1.setActionCommand("这是我自己设置的'actioncommand'");

        //new一个监听事件对象
        MyAction myAct=new MyAction();
        //给按钮添加监听事件(两个按钮同时用同一个监听事件
        bt1.addActionListener(myAct);
        bt2.addActionListener(myAct);

        frame.add(bt1,BorderLayout.NORTH);
        frame.add(bt2,BorderLayout.SOUTH);
        frame.setVisible(true);
        frame.setBounds(500,500,500,500);
    }
}

//自定义一个监听事件
class MyAction implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        //可以在这里利用`if(e.getActionCommand()==```)来实现一个监听事件,针对不同按钮实现不同响应!!!
        System.out.println("按钮被点击了:msg---->"+e.getActionCommand());
    }
}

运行结果:image-20220227172408094

2.5、输入框

​ 输入单行文本框的案例(监听输入内容)

package com.company.GUI;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 《GUI之文本框案例》
 * 2022年2月27日
 */
public class TestText {
    public static void main(String[] args) {
        new MyFrame();
    }
}

//自己的Frame类
class MyFrame extends Frame{
    public MyFrame(){
        TextField textField=new TextField();//一行文本的文本框
        this.add(textField);
        //监听文本框中输入的文字
        MyTextListener myTextListener=new MyTextListener();
        //按下enter 触发这个输入框的事件
        textField.addActionListener(myTextListener);
        //可以设置替换编码(输入之后看到的文字)
        textField.setEchoChar('*');

        this.setVisible(true);
        this.pack();//自适应
    }
}

//定义输入框事件
class MyTextListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        TextField source = (TextField) e.getSource();//获得一些资源,返回一个对象
        System.out.println(source.getText());;//获得输入的文本
    }
}

结果:

image-20220227220106484

2.6、简易计算器(组合+内部类回顾复习)

​ oop原则:组合大与继承!

//装饰者模式

//继承
class A extends B{
    
}

//组合,B写入A中用以调用B的功能,减少耦合
class A{
    public B b;
}
  • 1、简易计算器(初级写法)(面向过程)

    package com.company.GUI;
    
    import com.sun.xml.internal.ws.api.server.EndpointReferenceExtensionContributor;
    
    import javax.xml.soap.Text;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class TestSimpleCal {
        public static void main(String[] args) {
            new Calculator();
        }
    }
    
    //计算器类
    class Calculator extends Frame {
        public Calculator(){
            super("SimpleCalculator");
            this.setLayout(new FlowLayout());//流式布局
            //3个文本框
            TextField textField1 = new TextField(10);//文本框字符数
            TextField textField2 = new TextField(10);//文本框字符数
            TextField textField3 = new TextField(30);//文本框字符数
    
            //1个按钮
            Button button = new Button("=");
            button.addActionListener(new MyCalculatorListener(textField1,textField2,textField3));
            //1个加号
            Label label = new Label("+");
    
            this.add(textField1);
            this.add(label);
            this.add(textField2);
            this.add(button);
            this.add(textField3);
    
            this.pack();
            this.setVisible(true);
    
        }
    
    }
    
    //监听器类
    class MyCalculatorListener implements ActionListener{
        private TextField text1;
        private TextField text2;
        private TextField text3;
    
        public MyCalculatorListener(TextField text1,TextField text2,TextField text3){
            this.text1=text1;
            this.text2=text2;
            this.text3=text3;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            //获得加数和被加数
            int i1 = Integer.parseInt(text1.getText());
            int i2 = Integer.parseInt(text2.getText());
            
            //计算结果int用string输出
            text3.setText(""+(i1+i2));
    
            //清除前两个框的内容
            text1.setText("");
            text2.setText("");
        }
    }
    
  • 使用继承+组合 (推荐方式)

    package com.company.GUI;
    
    
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class TestSimpleCal {
        public static void main(String[] args) {
            new Calculator().loadCalculator();
        }
    }
    
    //计算器类
    class Calculator extends Frame {
        //属性
        TextField text1;
        TextField text2;
        TextField text3;
    
        //方法
    
        public void loadCalculator(){
            this.setLayout(new FlowLayout());//流式布局
            //3个文本框
            text1 = new TextField(10);//文本框字符数
            text2 = new TextField(10);//文本框字符数
            text3 = new TextField(30);//文本框字符数
    
            //1个按钮
            Button button = new Button("=");
            button.addActionListener(new MyCalculatorListener(this));
            //1个加号
            Label label = new Label("+");
    
            this.add(text1);
            this.add(label);
            this.add(text2);
            this.add(button);
            this.add(text3);
    
            this.pack();
            this.setVisible(true);
    
        }
    
    }
    
    //监听器类
    class MyCalculatorListener implements ActionListener{
    
        //获取计算器对象
        //在一个类中组合另外一个类
        Calculator calculator=null;
    
        public MyCalculatorListener(Calculator calculator){
            this.calculator=calculator;
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            //获得加数和被加数
            int i1 = Integer.parseInt(calculator.text1.getText());
            int i2 = Integer.parseInt(calculator.text2.getText());
    
            //计算结果int用string输出
            calculator.text3.setText(""+(i1+i2));
    
            //清除前两个框的内容
            calculator.text1.setText("");
            calculator.text2.setText("");
        }
    }
    

    完全改造为面向对象写法!!!! (属性+方法)

  • 内部类(!!!!!)

    更好的包装;

    可以直接拿到类的对象属性,而不用传递一个对象给独立的类;

    内部类的最大好处:可以畅通无阻的访问外部类的方法和属性!!!!

    package com.company.GUI;
    
    
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class TestSimpleCal {
        public static void main(String[] args) {
            new Calculator().loadCalculator();
        }
    }
    
    //计算器类
    class Calculator extends Frame {
        //属性
        TextField text1;
        TextField text2;
        TextField text3;
    
        //方法
    
        public void loadCalculator(){
            this.setLayout(new FlowLayout());//流式布局
            //3个文本框
            text1 = new TextField(10);//文本框字符数
            text2 = new TextField(10);//文本框字符数
            text3 = new TextField(30);//文本框字符数
    
            //1个按钮
            Button button = new Button("=");
            button.addActionListener(new MyCalculatorListener());
            //1个加号
            Label label = new Label("+");
    
            this.add(text1);
            this.add(label);
            this.add(text2);
            this.add(button);
            this.add(text3);
    
            this.pack();
            this.setVisible(true);
    
        }
    
        //监听器类
        private class MyCalculatorListener implements ActionListener{
    
            @Override
            public void actionPerformed(ActionEvent e) {
                //获得加数和被加数
                int i1 = Integer.parseInt(text1.getText());
                int i2 = Integer.parseInt(text2.getText());
    
                //计算结果int用string输出
               text3.setText(""+(i1+i2));
    
                //清除前两个框的内容
                text1.setText("");
                text2.setText("");
            }
        }
    }
    

2.7、画笔(paint)

package com.company.GUI;

import java.awt.*;

/**
 * 《画笔测试》
 */
public class TestPaint {
    public static void main(String[] args) {
        new MyPaint().loadFrame();
    }
}

class MyPaint extends Frame{
    public void loadFrame () {
        this.setBounds(200,200,1000,800);
//        pack();
        this.setVisible(true);
    }
    //画笔
    @Override
    public void paint(Graphics g) {
        //画笔,颜色,画的形状
        g.setColor(Color.red);
        g.fillOval(50,50,50,50);//实心圆
        g.fillRect(200,200,200,200);//实心矩形
    }
}

结果:image-20220302114424382


2.8、鼠标监听

目的:实现用鼠标画画!

思路:image-20220302123632283

package com.company.GUI;

import java.awt.*;
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 MyFrameOfPaintor("画图");
    }
}

//自己的类
class MyFrameOfPaintor extends Frame{
    //画画需要画笔,需要监听鼠标当前位置,用集合来存储鼠标位置(x,y)
    ArrayList points;//记录鼠标的位置


    public MyFrameOfPaintor(String title){
        super(title);
        this.setBounds(200,200,1000,800);

        //存鼠标的点
        points = new ArrayList();

        //鼠标监听器,针对这个窗口
        this.addMouseListener(new MyMouseListener());
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        //画画,监听鼠标的事件
        Iterator iterator = points.iterator();
        while(iterator.hasNext()){
            Point point = (Point) iterator.next();
            g.setColor(Color.magenta);
            g.fillOval(point.x,point.y,5,5);
        }
    }

    //添加一个点到界面上
    public void addPaint(Point point){
        points.add(point);
    }

    //适配器模式
    private  class MyMouseListener extends MouseAdapter{
        //鼠标:按下、弹起、长按

        @Override
        public void mousePressed(MouseEvent e) {
            MyFrameOfPaintor myMouseFrame = (MyFrameOfPaintor) e.getSource();
            //这里我们点击的时候,界面上就会产生一个点!!
            myMouseFrame.addPaint(new Point(e.getX(),e.getY()));

            //每次点击鼠标都要重画一遍
            myMouseFrame.repaint();
        }
    }
}

2.9、窗口监听

package com.company.GUI;

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

/**
 * 《测试窗口》
 */
public class TestWindow {
    public static void main(String[] args) {
        new WindowFrame();
    }
}

class WindowFrame extends Frame{

    public WindowFrame(){
        setBackground(Color.pink);
        setBounds(100,100,1000,800);
        setVisible(true);
//        addWindowListener(new MyWindowlistener());

        //匿名内部类
        this.addWindowListener(new WindowAdapter() {
            //关闭窗口
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("你点击了×");
//                setVisible(false);//隐藏窗口(如何通过按钮隐藏窗口? )
                System.exit(0);
            }
            //激活窗口
            @Override
            public void windowActivated(WindowEvent e) {
                System.out.println("windowActivated");
            }
        });


    }


    /*
    //内部类,相比之下更建议使用匿名内部类
    class MyWindowlistener extends WindowAdapter{
        @Override
        public void windowClosing(WindowEvent e) {
            setVisible(false);//隐藏窗口(如何通过按钮隐藏窗口? )
            System.exit(0);
        }
    }
    */

}

2.10、键盘监听

package com.company.GUI;

import java.awt.*;
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(200,200,1000,888);
            setVisible(true);

            this.addKeyListener(new KeyAdapter() {
                //键盘按下事件
                @Override
                public void keyPressed(KeyEvent e) {
                    //获取键盘按下的是哪一个键(获得键值)
                    int keyCode = e.getKeyCode();
                    System.out.println(keyCode);//不用专门记忆对应的code值,每个键都有对应的枚举变量
                    if (keyCode == KeyEvent.VK_UP){
                        System.out.println("你按下了上键!!!");
                    }//根据按下的键不同产生不同的效果
                }
            });
        }
  }

3、Swing

3.1、窗口、面板

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;

/**
 * 《Swing的窗口、面板》(JFrame)
 *
 *
 */
public class TestJFrame {
    public static void main(String[] args) {
        JFrame jf = new JFrame("这是一个Swing的JFrame");
//        jf.setBackground(Color.pink);
        jf.setBounds(100,100,1000,800);
        jf.setVisible(true);

        //设置文字
        JLabel jLabel=new JLabel("欢迎来到狂学JAVA");
        jf.getContentPane().setBackground(Color.pink);//定义容器getContentPane()
        jf.add(jLabel);


        //设置文职居中
        jLabel.setHorizontalAlignment(SwingConstants.CENTER);

        //关闭事件
        jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

}

文字居中:jLabel.setHorizontalAlignment(SwingConstants.CENTER);

3.2、弹窗

JDialog:默认就有关闭事件,不用专门去添加;

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 《测试弹窗》
 *
 */
public class TestDialog extends JFrame {
    public static void main(String[] args) {
        new TestDialog();
    }


    public TestDialog() throws HeadlessException {
        this.setVisible(true);
        this.setSize(1000,800);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //JFrame容器放置东西
        Container container=this.getContentPane();
        //绝对布局
        container.setLayout(null);

        //按钮
        JButton jButton=new JButton("点击弹出一个对话框");//创建按钮
        jButton.setBounds(30,30,200,50);

        //点击按钮时,弹出一个弹窗
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //弹窗
                new MyDialog();
            }
        });

        container.add(jButton);
    }

}

//弹窗的窗口
class MyDialog extends  JDialog{
    public MyDialog() {
        this.setVisible(true);
        this.setBounds(50,50,200,200);

        Container container  =this.getContentPane();
        container.setLayout(null);
        container.add(new Label("秦老师的JButton"));
    }
}


这里没有看到文字Label是因为绝对布局;

3.3、 标签

Label

new JLabel("xxx");

图标ICON

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;

/**
 * 图标是一个接口,需要实现类,Frame继承
 */
public class IconDemo  extends JFrame implements Icon {
    private int width;
    private int height;

    public static void main(String[] args) {
        new IconDemo().init();
    }

    public IconDemo(){}//无参构造器
    //有参构造器
    public IconDemo(int width,int height){
        this.width=width;
        this.height=height;
    }

    //初始化
    public void init(){
        IconDemo iconDemo = new IconDemo(15, 15);
        //图标放在标签上,也可以放在按钮上
        JLabel jLabel = new JLabel("IconTest", iconDemo, SwingConstants.CENTER);

        Container container = getContentPane();
        container.add(jLabel);
        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        g.fillOval(x,y,width,height);
    }

    @Override
    public int getIconWidth() {
        return this.width;
    }

    @Override
    public int getIconHeight() {
        return this.height;
    }
}

图片ICON

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;
import java.net.URL;

/**
 * 《图片标签测试》
 *
 *
 */
public class ImageIconDemo extends JFrame {
    public ImageIconDemo(){
        //获取图片的地址
        JLabel jLabel = new JLabel("ImageIonTest");
        URL url = ImageIconDemo.class.getResource("kda03.jpg");

        ImageIcon imageIcon = new ImageIcon(url);
        jLabel.setIcon(imageIcon);
        jLabel.setHorizontalAlignment(SwingConstants.CENTER);

        Container container = getContentPane();
        container.add(jLabel);

        setBounds(50,50,1980,1080);
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new ImageIconDemo();
    }
}

3.4、面板

JPanel

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;

public class TestJPanel extends JFrame {
    public TestJPanel(){
        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(1,2));
        JPanel panel3 = new JPanel(new GridLayout(2,1));
        JPanel panel4 = new JPanel(new GridLayout(3,2));

        panel1.add(new JButton("1"));
        panel1.add(new JButton("1"));
        panel1.add(new JButton("1"));
        panel2.add(new JButton("2"));
        panel2.add(new JButton("2"));
        panel3.add(new JButton("3"));
        panel3.add(new JButton("3"));
        panel3.add(new JButton("3"));
        panel4.add(new JButton("4"));
        panel4.add(new JButton("4"));
        panel4.add(new JButton("4"));
        panel4.add(new JButton("4"));
        panel4.add(new JButton("4"));
        panel4.add(new JButton("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 TestJPanel();
    }
}

JScrollPanel(滚动面板)

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;

/**
 * 《带滚动条测试》
 */
public class TestJScrollPane extends JFrame {
    public TestJScrollPane(){
        Container container = this.getContentPane();

        //文本域
        JTextArea jTextArea = new JTextArea(20,50);
        jTextArea.setText("欢迎来到欢迎来到欢迎来到欢迎来到欢迎来到欢迎来到欢迎来到欢迎来到欢迎来到!!!!");

        //Scroll面板
        JScrollPane jScrollPane = new JScrollPane(jTextArea);
        container.add(jScrollPane);

        this.setVisible(true);
        this.setBounds(100,100,100,100);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        new TestJScrollPane();
    }
}

显示效果:image-20220302231211133

3.5、按钮

设置图标按钮

package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;
import java.net.URL;

/**
 * 《图片按钮》
 */
public class TestJButton extends JFrame {
    public TestJButton(){
        Container container = this.getContentPane();
        //将一个图片作为图标
        URL url = TestJButton.class.getResource("kda03.jpg");
        ImageIcon imageIcon = new ImageIcon(url);

        //把图标放在按钮上
        JButton jButton = new JButton();
        jButton.setIcon(imageIcon);
        jButton.setToolTipText("图片按钮");//设置悬浮提示

        container.add(jButton);

        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }

    public static void main(String[] args) {
        new TestJButton();
    }
}

  • 单选按钮
JRadioButtion radioButton =new JRadioButtion();
package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;
import java.net.URL;

/**
 * 《单选按钮》
 */
public class TestJButton02 extends JFrame {
    public TestJButton02(){
        Container container = this.getContentPane();
        //将一个图片作为图标
        URL url = TestJButton02.class.getResource("kda03.jpg");
        ImageIcon imageIcon = new ImageIcon(url);
        //单选框
        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.add(jRadioButton1,BorderLayout.NORTH);
        container.add(jRadioButton2,BorderLayout.CENTER);
        container.add(jRadioButton3,BorderLayout.SOUTH);

        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }

    public static void main(String[] args) {
        new TestJButton02();
    }
}

  • 复选按钮
package com.company.GUI.Swing;

import javax.swing.*;
import java.awt.*;
import java.net.URL;

/**
 * 《复选》
 */
public class TestJButton03 extends JFrame {
    public TestJButton03(){
        Container container = this.getContentPane();
        //将一个图片作为图标
        URL url = TestJButton03.class.getResource("kda03.jpg");
        ImageIcon imageIcon = new ImageIcon(url);

        //多选框
        JCheckBox jCheckBox = new JCheckBox("jCheckBox01");
        JCheckBox jCheckBox2 = new JCheckBox("jCheckBox02");

        container.add(jCheckBox,BorderLayout.NORTH);
        container.add(jCheckBox2,BorderLayout.SOUTH);

        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }

    public static void main(String[] args) {
        new TestJButton03();
    }
}

3.6、列表

  • 下拉列表

    package com.company.GUI.Swing;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * 《下拉框测试类》
     */
    public class TestComboboxDemo01 extends JFrame {
        public TestComboboxDemo01() {
            Container container = this.getContentPane();
    
            JComboBox status = new JComboBox();
            status.addItem(null);
            status.addItem("正在热映");
            status.addItem("即将上映");
            status.addItem("已下架");
    
            container.add(status);
    
            this.setVisible(true);
            this.setSize(500,300);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            new TestComboboxDemo01();
        }
    }
    
    
  • 选择列表

    package com.company.GUI.Swing;
    
    import javax.swing.*;
    import java.awt.*;
    import java.util.Vector;
    
    /**
     * 《列表测试类》
     */
    public class TestComboboxDemo02 extends JFrame {
        public TestComboboxDemo02() {
            Container container = this.getContentPane();
    
            //生成列表内容
    //        String[] contents={"1","2","3"};
    
            Vector contents = new Vector();
            //列表中需放入内容
            JList list =new JList(contents);
    
            contents.add("张三");
            contents.add("李四");
            contents.add("王五");
    
            container.add(list);
    
            this.setVisible(true);
            this.setSize(500,300);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            new TestComboboxDemo02();
        }
    }
    
    
  • 应用场景

    • 选择地区,或者一些单选;
    • 列表,展示信息,一般是动态扩容

3.7、文本框

  • 文本框

    package com.company.GUI.Swing;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * 《测试文本框》
     */
    public class TestTextDemo01 extends JFrame {
        public TestTextDemo01() {
            Container container = this.getContentPane();
    
            JTextField jTextField = new JTextField("hello");
            JTextField jTextField2 = new JTextField("world",20);
    
            container.add(jTextField,BorderLayout.NORTH);
            container.add(jTextField2,BorderLayout.SOUTH);
    
            this.setVisible(true);
            this.setSize(500,300);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            new TestTextDemo01();
        }
    }
    
    
  • 密码框

    package com.company.GUI.Swing;
    
    import javax.swing.*;
    import java.awt.*;
    
    /**
     * 《密码框测试》
     */
    public class TestTextDemo02 extends JFrame {
        public TestTextDemo02() {
            Container container = this.getContentPane();
    
            JPasswordField jPasswordField = new JPasswordField();
            jPasswordField.setEchoChar('*');
            container.add(jPasswordField);
    
            this.setVisible(true);
            this.setSize(500,300);
            this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            new TestTextDemo02();
        }
    }
    
    
  • 文本域

    JTextArea textArea =new JTextArea();//可传入文本域大小
    

贪吃蛇

  • 1、定义数据
  • 2、画上去
  • 3、监听事件(键盘、事件)

1、 图片加载类:

package com.company.GUI.Snake;

import javax.swing.*;
import java.net.URL;

/**
 * 数据中心
 *
 */
public class Data {
    //相对路径: "xxxx/"
    //绝对路径:"/xxxx/xx"
    public static URL headerURL =Data.class.getResource("statics/header.png");
    public static ImageIcon header =new ImageIcon(headerURL);//设置图标

    public static URL upURL =Data.class.getResource("statics/up.png");
    public static URL downURL =Data.class.getResource("statics/down.png");
    public static URL leftURL =Data.class.getResource("statics/left.png");
    public static URL rightURL =Data.class.getResource("statics/right.png");
    public static ImageIcon up =new ImageIcon(upURL);//设置图标
    public static ImageIcon down =new ImageIcon(downURL);//设置图标
    public static ImageIcon left =new ImageIcon(leftURL);//设置图标
    public static ImageIcon right =new ImageIcon(rightURL);//设置图标

    public static URL bodyURL =Data.class.getResource("statics/body.png");
    public static ImageIcon body =new ImageIcon(bodyURL);//设置图标

    public static URL foodURL =Data.class.getResource("statics/food.png");
    public static ImageIcon food =new ImageIcon(foodURL);//设置图标
}

2、游戏启动类:

package com.company.GUI.Snake;

import javax.swing.*;

/**
 * 游戏启动类
 * 2022年3月6日10:56:37
 */
public class StartGame {
    public static void main(String[] args) {
        JFrame frame = new JFrame();

        //正常的游戏界面都在这个面板上

        frame.setBounds(10,10,900,720);
        frame.setResizable(false);//窗口大小固定
        frame.add(new GamePanel());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    }
}

3、游戏面板

package com.company.GUI.Snake;

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;

/**
 *
 * 游戏执行的面板
 * 2022年3月6日11:00:24
 */
public class GamePanel extends JPanel implements KeyListener,ActionListener {

    //定义蛇的数据结构
    int length;//定义蛇的长度
    int [] snakeX =new int[600];//蛇的X坐标
    int[] snakeY =new int[500];//蛇的Y坐标
    String orient;//定义蛇的方向(初始向右)
    boolean isStart=false;//游戏状态:开始(true)、停止(false)
    Timer timer =new Timer(100,  this);//100毫秒执行一次!!(1秒10次) //定时器
    int foodx; //食物的位置
    int foody;
    Random random =new Random();
    boolean isFail=false;
    int score ;//定义一个积分


    //构造器
    public GamePanel() {
        init();
        //获得焦点和键盘事件
        this.setFocusable(true);//获得焦点事件(窗口是否活跃)
        this.addKeyListener(this);//获得键盘监听事件
    }



    //定义初始化方法
    public void init(){
        length =3;
        //头的位置(x,y)
        snakeX[0] = 100;
        snakeY[0] = 100;
        //第一节身体
        snakeX[1] = 75;
        snakeY[1] = 100;
        //第二节身体
        snakeX[2] = 50;
        snakeY[2] = 100;
        orient ="R";//小蛇初始方向向右
        //随机生成食物的位置
        foodx=25+25*random.nextInt(34);
        foody=75+25*random.nextInt(24);
        //初始化积分
        score =0;


        timer.start();//游戏一开始,计时器就启动
    }

    //绘制面板,游戏的内容都由这个画笔来画
    @Override
    protected void paintComponent(Graphics g) {//注意这里不要重写错方法
        super.paintComponents(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("Cascadia Code",Font.BOLD,18));//设置字体
        g.drawString("长度"+length,750,30);
        g.drawString("分数"+score,750,50);

        //画食物
        Data.food.paintIcon(this,g,foodx,foody);//如果食物出现在蛇的身体中,就重新放置食物




        /**
         * 画蛇
         */
        //画蛇头
        if (orient.equals("R")){
            Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//初始化蛇头朝右,需要通过判断语句判断方向→
        }else  if (orient.equals("L")){
            Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);//朝←
        }else  if (orient.equals("U")){
            Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);//朝上↑
        }else  if (orient.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("Jokerman",Font.BOLD,25));//设置字体
            g.drawString("Press 'Space' To Start Game",250,300);
        }

        if (isFail){
            g.setColor(Color.RED);
            g.setFont(new Font("Jokerman",Font.BOLD,25));//设置字体
            g.drawString("Snake DIE",250,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 && !orient.equals("D")){
            orient="U";
        }else if (keyCode==KeyEvent.VK_DOWN && !orient.equals("U")){
            orient="D";
        }else if (keyCode==KeyEvent.VK_LEFT && !orient.equals("R")){
            orient="L";
        }else if (keyCode==KeyEvent.VK_RIGHT && !orient.equals("L")){
            orient="R";
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    //事件监听-----通过固定刷新来监听事件
    @Override
    public void actionPerformed(ActionEvent e) {
        if (isStart && !isFail){//如果游戏是开始状态,就让小蛇动起来

            //吃食物事件
            if (snakeX[0]==foodx && snakeY[0]==foody){
                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[i]=snakeX[i-1];
                snakeX[i]=snakeX[i-1];
                snakeY[i]=snakeY[i-1];
            }
            //控制走向
            if (orient.equals("R")){//向右
                snakeX[0] = snakeX[0]+25;//头前移
                if (snakeX[0]>850){
                    snakeX[0]=25;//超出屏幕右边时从头再开始
                }
            }else if (orient.equals("L")){
                snakeX[0] = snakeX[0]-25;//头前移
                if (snakeX[0]<25){
                    snakeX[0]=850;//边界判断
                }
            }else if (orient.equals("U")){
                snakeY[0] = snakeY[0]-25;//头前移
                if (snakeY[0]<75){
                    snakeY[0]=650;//边界判断
                }
            }else if (orient.equals("D")){
                snakeY[0] = snakeY[0]+25;//头前移
                if (snakeY[0]>650){
                    snakeY[0]=75;//边界判断
                }
            }

            //失败判定
            for(int i =1 ;i<length;i++){
                if (foodx==snakeX[i] && foody==snakeY[i]){//食物出现在蛇身上,就重画食物位置
                    //再次随机生成食物
                    foodx=25+25*random.nextInt(34);
                    foody=75+25*random.nextInt(24);
                }
                if (snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
                    isFail=true;
                }
            }
            repaint();//记得刷新界面(重画)
        }
    }
}

在原基础上添加了蛇不能回头、食物不能出现在蛇身体中的设定。

posted @ 2022-02-28 15:46  devynlime  阅读(41)  评论(0)    收藏  举报