JavaGUI

JavaGUI

参考视频:BV1DJ411B75F

关键类:Swing、AWT

技术已不常用,不过可以为了解MVC架构打基础

1.AWT

1.1 AWT介绍

java.awt.* ,内部包含很多GUI相关的类和接口。

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

在这里插入图片描述

1.2 组件和容器

注:大体学习思路是:知道有相关的类–>创建这个类的对象–>各种类方法的使用和细节可以看源码(IDEA中通过ctrl+鼠标点击相关类可以跳到类的源码)

1.2.1 Frame

/**
* 创建一个Frame窗口
*/

import java.awt.*;
public class TestFrame {
    public static void main(String[] args) {
        //Frame创建窗口对象,具体细节看源码
        Frame frame=new Frame("My first java frame");
        
        //设置窗口是否可见
        frame.setVisible(true);
    
        //设置窗口大小
        frame.setSize(400,300);
        
        //设置背景颜色  Color类
        frame.setBackground(new Color(111,56,220));
        
        //窗口弹出的初始位置
        frame.setLocation(200,200);
    }
}

在这里插入图片描述

下面实现一次弹出多个窗口,可以将窗口的特点进行封装,写成自己的窗口类

import java.awt.*;
public class TestFrame2 {
    public static void main(String[] args) {
        //弹出多个窗口
        MyFrame myFrame1=new MyFrame(100,100,200,200, Color.cyan);
        MyFrame myFrame2=new MyFrame(100,300,200,200, Color.pink);
        MyFrame myFrame3=new MyFrame(100,500,200,200, Color.red);
        MyFrame myFrame4=new MyFrame(100,700,200,200, Color.yellow);
    }
}


class MyFrame extends Frame{
    static int id=0;   //统计创建的窗口数

    public MyFrame(int x,int y,int w,int h,Color color){
        super("MyFrame"+(++id));
        setBackground(color);
        setBounds(x,y,w,h);
        setVisible(true);
    }
}

在这里插入图片描述

1.2.2 Panel(面板)

Panel不能单独存在,可以堪称是一个空间或容器

//Panel源码定义部分
public class Panel extends Container implements Accessible {
    private static final String base = "panel";
    private static int nameCounter = 0;
//......
}

Panel继承了Container

public class Container extends Component {

    private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Container");
    private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.Container");

    private static final Component[] EMPTY_ARRAY = new Component[0];
	//......
}

Container继承了Component。因此Panel对象作为元素放入Frame对象

测试样例

import java.lang.*;
import java.util.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class TestPanel {
    public static void main(String[] args) {
        Frame frame=new Frame("包含Panel的窗口");
        Panel panel=new Panel();
        //设置布局
        frame.setLayout(null);

        //坐标
        frame.setBounds(300,300,500,500);
        frame.setBackground(Color.cyan);

        //设置panel坐标,相对于frame。frame的左上角为panel的(0,0)坐标
        panel.setBounds(50,50,260,260);
        panel.setBackground(Color.magenta);

        //将panel加入frame中
        frame.add(panel);
        frame.setVisible(true);

        //监听事件,监听窗口关闭事件
        //下面采用适配器模式,这种模式下可以在众多待重载的方法中,只重载部分需要的方法
        frame.addWindowListener(new WindowAdapter() {
            //窗口右上角关闭事件
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
    }
}

在这里插入图片描述

1.3 布局管理器

基本布局
  • 流式布局(从左往右)
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
    public static void main(String[] args) {
        Frame frame=new Frame();

        //组件+按钮
        Button button1=new Button("button1");
        Button button2=new Button("button2");
        Button button3=new Button("button3");

        //设置为流式布局
        //frame.setLayout(new FlowLayout());
        //frame.setLayout(new FlowLayout(FlowLayout.LEFT));
        frame.setLayout(new FlowLayout(FlowLayout.RIGHT));

        frame.setSize(300,300);

        //添加按钮
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.setVisible(true);
    }

}

在这里插入图片描述

  • 东西南北中
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
    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 center=new Button("Center");

        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.setSize(500,500);
        frame.setVisible(true);
    }

}

在这里插入图片描述

  • 表格布局
import java.io.BufferedReader;
import java.lang.*;
import java.util.*;
import java.awt.*;
public class TestFlowLayout {
    public static void main(String[] args) {
        Frame frame=new Frame();
        
        Button bin1=new Button("bin1");
        Button bin2=new Button("bin2");
        Button bin3=new Button("bin3");
        Button bin4=new Button("bin4");
        Button bin5=new Button("bin5");
        Button bin6=new Button("bin6");


        //设置表格布局规格
        frame.setLayout(new GridLayout(3,2));
        frame.add(bin1);
        frame.add(bin2);
        frame.add(bin3);
        frame.add(bin4);
        frame.add(bin5);
        frame.add(bin6);
        frame.setSize(500,500);
        frame.setVisible(true);
    }

}

在这里插入图片描述

嵌套布局

实现下面布局

在这里插入图片描述

import java.lang.*;
import java.util.*;
import java.awt.*;
import java.util.concurrent.Flow;

public class TestFlowLayout {
    public static void main(String[] args) {
        Frame frame=new Frame();


        //上半部分
        Panel panelup=new Panel(new BorderLayout());
        panelup.add(new Button("West-1"),BorderLayout.WEST);
        panelup.add(new Button("East-1"),BorderLayout.EAST);

        Panel panelup1=new Panel(new GridLayout(2,1));
        panelup1.add(new Button("center1-bin-1"));
        panelup1.add(new Button("center1-bin-2"));
        panelup.add(panelup1,BorderLayout.CENTER);

        //下半部分
        Panel paneldown=new Panel(new BorderLayout());
        paneldown.add(new Button("West-2"),BorderLayout.WEST);
        paneldown.add(new Button("East-3"),BorderLayout.EAST);
        Panel paneldown1=new Panel(new GridLayout(2,2));

        for(int i=1;i<=4;i++){
            paneldown1.add(new Button("center2-bin-"+i));
        }
        paneldown.add(paneldown1,BorderLayout.CENTER);


        //设置表格布局规格

        frame.setSize(500,500);
        panelup.setSize(250,250);
        panelup.setLocation(0,0);
        paneldown.setSize(250,250);
        paneldown.setLocation(250,0);
        frame.setLayout(new GridLayout(2,1));
        frame.add(panelup);
        frame.add(paneldown);
        frame.setVisible(true);
    }
}

在这里插入图片描述

1.4 事件监听

目的:某个事件发生时可以触发什么操作

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

public class TestActionEvent {

    public static void main(String[] args) {

        //点击按钮触发事件
        Frame frame=new Frame();
        Button button=new Button("button");
        frame.setVisible(true);

        //自定义监听事件类
        MyActionListener myActionListener=new MyActionListener();
        button.addActionListener(myActionListener);   //添加监听器
        frame.add(button,BorderLayout.CENTER);
        frame.pack();   //自动调整组件布局
        windowClose(frame);
    }

    //关闭窗体事件
    private static void windowClose(Frame frame){
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e){
                System.exit(0);
            }
        });
    }
}


class MyActionListener implements ActionListener{

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

在这里插入图片描述

/**
*  两个按钮共用一个监听器
*/
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestActionTwo {
    public static void main(String[] args) {
        
        Frame frame=new Frame();
        Button bin1=new Button("Start");
        Button bin2=new Button("End");

        //修改bin2的内部信息。默认值为按钮名
        bin2.setActionCommand("button2-stop");

        MyMonitor myMonitor=new MyMonitor();
        bin1.addActionListener(myMonitor);
        bin2.addActionListener(myMonitor);

        frame.add(bin1,BorderLayout.NORTH);
        frame.add(bin2,BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }
}


class MyMonitor implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
        //e.getActionCommand()  可以获取按钮的信息
        System.out.println(e.getActionCommand());
        if(e.getActionCommand().equals("Start")){
            System.out.println("1111111111111111");
        }
        else if(e.getActionCommand().equals("End")){
            System.out.println("2222222222222222");
        }
    }
}

在这里插入图片描述

1.5 TextField(输入框)

不可换行的文本框

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

public class TextTest {
    public static void main(String[] args) {
        new MyFrame();
    }
}

class MyFrame extends Frame{
    public MyFrame(){
        TextField textField=new TextField();
        add(textField);
        setVisible(true);
        pack();

        //监听文本框输入的内容
        MyActionListener myActionListener=new MyActionListener();
        //写入内容后按回车触发事件
        textField.addActionListener(myActionListener);

        //设置替换编码
        textField.setEchoChar('*');

    }
}


class MyActionListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e){
        TextField field=(TextField) e.getSource();    //e.getSource()返回Object类型
        System.out.println(field.getText());
        //field.setText("");
    }
}

在这里插入图片描述

案例:简易计算器

涉及组合、内部类的内容

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

public class TestCal {
    public static void main(String[] args) {
        new Calculator();
    }
}

//计算器类
class Calculator extends Frame {

    public Calculator(){
        //3个文本框
        TextField num1 = new TextField(10);  //10为限制字符数
        TextField num2 = new TextField(10);
        TextField num3 = new TextField(20);

        //1个按钮
        Button button=new Button("=");
        button.addActionListener(new MyCalculatorListener(num1,num2,num3));
        //1个标签
        Label label=new Label("+");

        //布局
        setLayout(new FlowLayout());
        add(num1);add(label);add(num2);add(button);add(num3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.exit(0);
            }
        });
    }
}


//监听器类
class MyCalculatorListener implements ActionListener{
    private TextField num1,num2,num3;

    public MyCalculatorListener(TextField num1, TextField num2, TextField num3) {
        this.num1 = num1;
        this.num2 = num2;
        this.num3 = num3;
    }

    @Override
    public void actionPerformed(ActionEvent e){
        //获取两个加数
        int n1=Integer.parseInt(num1.getText());
        int n2=Integer.parseInt(num2.getText());
        
        //计算结果放到第三个文本框
        num3.setText(""+(n1+n2));
        
        //清除前两个框
        num1.setText("");
        num2.setText("");
    }
}

在这里插入图片描述

上述代码以面向过程为主,下面通过组合形式优化成面向对象的代码

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

public class TestCal {
    public static void main(String[] args) {
        new Calculator();
    }
}

//计算器类
class Calculator extends Frame {
    TextField num1,num2,num3;


    public Calculator(){
        //3个文本框
        num1 = new TextField(10);  //10为限制字符数
        num2 = new TextField(10);
        num3 = new TextField(20);
        //1个按钮
        Button button=new Button("=");
        button.addActionListener(new MyCalculatorListener(this));
        //1个标签
        Label label=new Label("+");


        //布局
        setLayout(new FlowLayout());
        add(num1);add(label);add(num2);add(button);add(num3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.exit(0);
            }
        });
    }
}


//监听器类
class MyCalculatorListener implements ActionListener{

    //获取对象,在一个类中组合另一个类
    Calculator calculator=null;

    public MyCalculatorListener(Calculator calculator) {
        this.calculator = calculator;
    }

    @Override
    public void actionPerformed(ActionEvent e){
        //获取两个加数
        int n1=Integer.parseInt(calculator.num1.getText());
        int n2=Integer.parseInt(calculator.num2.getText());
        
        //计算结果放到第三个文本框
        calculator.num3.setText(""+(n1+n2));
        
        //清除前两个框
        calculator.num1.setText("");
        calculator.num2.setText("");
    }
}

进一步,还可以使用内部类方法将监听器类放到计算器类中,从而更好地封装类

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

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

//计算器类
class Calculator extends Frame {
    TextField num1,num2,num3;
    
    public void loadFrame(){
        //3个文本框
        num1 = new TextField(10);  //10为限制字符数
        num2 = new TextField(10);
        num3 = new TextField(20);
        //1个按钮
        Button button=new Button("=");
        button.addActionListener(new MyCalculatorListener());
        //1个标签
        Label label=new Label("+");


        //布局
        setLayout(new FlowLayout());
        add(num1);add(label);add(num2);add(button);add(num3);

        pack();
        setVisible(true);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.exit(0);
            }
        });
    }
    
    //监听器内部类
    public class MyCalculatorListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e){
            //获取两个加数
            int n1=Integer.parseInt(num1.getText());
            int n2=Integer.parseInt(num2.getText());

            //计算结果放到第三个文本框
            num3.setText(""+(n1+n2));

            //清除前两个框
            num1.setText("");
            num2.setText("");
        }
    }
}

1.6 Paint(画笔)

import java.awt.*;
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) {
        super.paint(g);
        g.setColor(Color.cyan);
        g.fillOval(100,100,100,100); //实心圆
        g.setColor(Color.magenta);
        g.fillRect(150,200,200,200);
    }
}

1.7 常用监听

1.7.1 鼠标监听

/**
* 简易画板
*/
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Iterator;

public class TestMouseListener {
    public static void main(String[] args) {
        new MyFrame("画图");
    }
}



class MyFrame extends Frame{
    //画笔。需要监听鼠标当前的位置,还需要一个存储所画点的集合
    ArrayList points;

    public MyFrame(String title) {
        super(title);
        setBounds(200,200,400,300);
        setVisible(true);

        //存储鼠标点击的位置
        points=new ArrayList();

        //鼠标监听器
        addMouseListener(new MyMouseListener());
    }

    @Override
    public void paint(Graphics g) {
        //监听鼠标的事件
        Iterator iterator=points.iterator();
        while(iterator.hasNext()){
            Point point=(Point)iterator.next();
            g.setColor(Color.cyan);
            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 myFrame=(MyFrame)e.getSource();

            //鼠标的位置
            addPoint(new Point(e.getX(),e.getY()));

            //每次点击鼠标都需要重新调用paint函数
            myFrame.repaint();
        }
    }
}

在这里插入图片描述

1.7.2 窗口监听

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.cyan);
        setBounds(200,200,200,200);
        setVisible(true);

        this.addWindowListener(new WindowAdapter() {
            //匿名内部类
            @Override
            public void windowOpened(WindowEvent e) {
                System.out.println("窗口打开");
            }

            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("窗口正在关闭");
                System.exit(0);
            }
        });
    }
}

1.7.3 键盘监听

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,200,200);
        setVisible(true);

        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode=e.getKeyCode();
                if(keyCode==KeyEvent.VK_UP){
                    System.out.println("👆");
                }
                else if(keyCode==KeyEvent.VK_LEFT){
                    System.out.println("👈");
                }
                else if(keyCode==KeyEvent.VK_RIGHT){
                    System.out.println("👉");
                }
                else if(keyCode==KeyEvent.VK_DOWN){
                    System.out.println("👇");
                }
            }
        });
    }
}

在这里插入图片描述

2.Swing

功能比AWT更强。

大体用法相近

2.1 窗口、面板

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

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

class MyJframe extends JFrame{
    public void init(){
        setBounds(200,200,200,200);
        setVisible(true);

        JLabel label=new JLabel("A JLabel");
        add(label);
        //将label设为居中
        label.setHorizontalAlignment(SwingConstants.CENTER);

        //获取一个容器
        Container container=this.getContentPane();
        container.setBackground(Color.cyan);
    }
}

在这里插入图片描述

2.2 弹窗

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

public class DialogDemo extends JFrame {
    public DialogDemo(){
        setVisible(true);
        setSize(700,500);
        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 MyDialogDemo();
            }
        });
        container.add(button);
    }

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

//弹窗类
class MyDialogDemo extends JDialog{
    public MyDialogDemo() {
        setVisible(true);
        setBounds(100,100,500,500);

        //这句话的功能在JDialog中已实现,不用再添加
        //setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        Container container=this.getContentPane();
        container.setLayout(null);

        container.add(new Label("弹窗文本"));
    }
}

在这里插入图片描述

2.3 标签(Icon)

JLabel

图标Icon

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

public class IconDemo extends JFrame implements Icon {

    private int width;
    private int height;

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

    public void init(){
        IconDemo iconDemo=new IconDemo(13,15);
        JLabel label=new JLabel("icontest",iconDemo,SwingConstants.CENTER);

        Container container=this.getContentPane();
        container.add(label);

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


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


    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        g.drawImage(new ImageIcon("C:\\Users\\96955\\Desktop\\tempblog\\chigua.png").getImage(),10,10,new JPanel());
    }

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

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

在这里插入图片描述

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

public class ImageIconDemo extends JFrame{
    public ImageIconDemo(){
        //获取图片地址
        JLabel label=new JLabel("ImageIcon");
        URL url=ImageIconDemo.class.getResource("chigua.png");

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

        Container container=new Container();
        container.add(label);

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

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

2.4 面板

JPanel

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

public class JPanelDemo extends JFrame {
    public JPanelDemo(){
        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"));
        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);

        setVisible(true);
        setSize(500,500);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

注:JButton可以通过setIcon方法设置按钮图标

在这里插入图片描述

JScrollPanel

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

public class JScrollDemo extends JFrame {
    public JScrollDemo(){
        Container container=this.getContentPane();

        //文本域
        JTextArea jTextArea=new JTextArea(20,50);
        jTextArea.setText("测试测试测试测试测试测试测试测试");

        //Scroll面板
        JScrollPane jScrollPane=new JScrollPane(jTextArea);
        container.add(jScrollPane);
        setVisible(true);
        setBounds(100,100,300,350);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

在这里插入图片描述

3.5 按钮

  • 单选按钮
import javax.swing.*;
import java.awt.*;
import java.net.URL;

public class JButtonDemo extends JFrame {
    public JButtonDemo(){
        Container container=this.getContentPane();
        //将一个图片变为图标
        URL url=JButtonDemo.class.getResource("chigua.png");

        //单选框
        JRadioButton radioButton1=new JRadioButton("单选1");
        JRadioButton radioButton2=new JRadioButton("单选2");
        JRadioButton radioButton3=new JRadioButton("单选3");
        //单选只能选一个,因此可以对其进行分组
        ButtonGroup buttonGroup=new ButtonGroup();
        buttonGroup.add(radioButton1);
        buttonGroup.add(radioButton2);
        buttonGroup.add(radioButton3);

        container.add(radioButton1,BorderLayout.CENTER);
        container.add(radioButton2,BorderLayout.NORTH);
        container.add(radioButton3,BorderLayout.SOUTH);

        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

在这里插入图片描述

  • 多选按钮
import javax.swing.*;
import java.awt.*;
import java.net.URL;

public class JButtonDemo extends JFrame {
    public JButtonDemo(){
        Container container=this.getContentPane();
        //将一个图片变为图标
        URL url=JButtonDemo.class.getResource("chigua.png");

        //多选框
        JCheckBox checkBox1=new JCheckBox("多选1");
        JCheckBox checkBox2=new JCheckBox("多选2");
        JCheckBox checkBox3=new JCheckBox("多选3");

        container.add(checkBox1,BorderLayout.CENTER);
        container.add(checkBox2,BorderLayout.NORTH);
        container.add(checkBox3,BorderLayout.SOUTH);

        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

在这里插入图片描述

3.6 列表

  • 下拉框
import javax.swing.*;
import java.awt.*;
import java.net.URL;

public class TestComboboxDemo extends  JFrame{

    public TestComboboxDemo(){
        Container container=this.getContentPane();

        JComboBox subject=new JComboBox();

        
        subject.addItem("高等数学");
        subject.addItem("线性代数");
        subject.addItem("数据库");
        subject.addItem("数据结构");
        subject.addItem("计算机网络");


        container.add(subject);
        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }


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

在这里插入图片描述

  • 列表框
import javax.swing.*;
import java.awt.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.Vector;

public class TestComboboxDemo extends  JFrame{

    public TestComboboxDemo(){
        Container container=this.getContentPane();

        //生成列表内容
        Vector contents=new Vector();
        contents.add("操作系统");
        contents.add("数字电子技术");
        //列表中添加内容
        JList jList=new JList(contents);
        //可以实现动态添加内容
        contents.add("高等数学");
        contents.add("线性代数");
        contents.add("计算机网络");

        container.add(jList);
        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }


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

在这里插入图片描述

3.7 文本框

  • 文本框(单行)
import javax.swing.*;
import java.awt.*;

public class TestTextDemo extends JFrame {
    public TestTextDemo(){
        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);

        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

在这里插入图片描述

  • 密码框
import javax.swing.*;
import java.awt.*;

public class TestTextDemo extends JFrame {
    public TestTextDemo(){
        Container container=this.getContentPane();

        JPasswordField jPasswordField=new JPasswordField();
        jPasswordField.setEchoChar('*');
        container.add(jPasswordField);
        setVisible(true);
        setSize(500,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

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

在这里插入图片描述

  • 文本域

JTextArea

2.4的JScrollPanel测试中已用过,可以回看。

实践:贪吃蛇

定时器:Timer,用于划分游戏的帧数

  1. 定义数据结构
  2. 添加素材
  3. 添加监听事件

在这里插入图片描述

package Snake;

import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

//游戏的主启动类
public class StartGame {
    public static void main(String[] args) {
        JFrame frame=new JFrame();
        
        frame.setResizable(false); //锁定窗口大小
        frame.setBounds(10,10,900,720);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //游戏的主要内容写在面板类中
        frame.add(new GamePanel());
        frame.setVisible(true);
    }
}
package Snake;

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

//数据中心类(图片素材相关数据)
public class Data {
    public static URL headerURL=Data.class.getResource("static/chigua.png");
    public static URL bodyURL=Data.class.getResource("static/body.png");
    public static URL downURL=Data.class.getResource("static/down.png");
    public static URL foodURL=Data.class.getResource("static/food.png");
    public static URL leftURL=Data.class.getResource("static/left.png");
    public static URL rightURL=Data.class.getResource("static/right.png");
    public static URL upURL=Data.class.getResource("static/up.png");

    public static ImageIcon header=new ImageIcon(headerURL);
    public static ImageIcon body=new ImageIcon(bodyURL);
    public static ImageIcon down=new ImageIcon(downURL);
    public static ImageIcon food=new ImageIcon(foodURL);
    public static ImageIcon left=new ImageIcon(leftURL);
    public static ImageIcon right=new ImageIcon(rightURL);
    public static ImageIcon up=new ImageIcon(upURL);

}
package 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;

//游戏面板
public class GamePanel extends JPanel implements KeyListener, ActionListener {
    //设计🐍的数据结构
    int length;  //🐍的长度
    int[] snakeX=new int[600];  //🐍的x坐标 25*25
    int[] snakeY=new int[500];  //🐍的y坐标 25*25
    String fx;  //初始方向向右

    //食物的坐标
    int foodX,foodY;
    Random random=new Random();



    //游戏的状态:开始、停止
    boolean isStart=false;
    boolean isFail=false; //游戏失败状态
    int score; //游戏得分
    //定时器
    Timer timer=new Timer(100,this); //100ms刷新一次


    //构造器
    public GamePanel() {
        init();
        //获取焦点和键盘事件
        this.setFocusable(true); //获取焦点事件
        //this.addKeyListener(this); //获取键盘监听事件
        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; //第二节身体的坐标
        fx="R";

        //事务位置随机分布
        foodX=25+25*random.nextInt(24);
        foodY=75+25*random.nextInt(24);
        score=0;
    }

    //绘制面板
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g); //清屏

        //绘制静态面板
        this.setBackground(Color.BLACK);
        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);

        //根据方向添加蛇头
        switch (fx) {
            case "R" -> Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
            case "L" -> Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
            case "U" -> Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
            case "D" -> Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
        }


        for(int i=1;i<length;i++){
            //第i节身体
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        Data.food.paintIcon(this,g,foodX,foodY);


        //游戏状态判断
        if(!isStart){
            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,40));
            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){
            fx="U";
        }
        else if(keyCode==KeyEvent.VK_DOWN){
            fx="D";
        }
        else if(keyCode==KeyEvent.VK_LEFT){
            fx="L";
        }
        else if(keyCode==KeyEvent.VK_RIGHT){
            fx="R";
        }
    }

    //事件监听   需要超过固定事件来刷新,1秒10次
    @Override
    public void actionPerformed(ActionEvent e){
        if(isStart && !isFail){ //当前游戏是开始状态。小蛇运动

            //吃食物
            if(snakeX[0]==foodX && snakeY[0]==foodY){
                length++;
                score+=10;
                //再生成一个食物
                foodX=25+25*random.nextInt(24);
                foodY=75+25*random.nextInt(24);
            }

            //身体移动
            for(int i=length-1;i>0;i--){
                snakeX[i]=snakeX[i-1];
                snakeY[i]=snakeY[i-1];
            }

            //走向
            if(fx.equals("R")){
                snakeX[0]=snakeX[0]+25;
                if(snakeX[0]>850) snakeX[0]=25;
            }
            else if(fx.equals("L")){
                snakeX[0]=snakeX[0]-25;
                if(snakeX[0]<25) snakeX[0]=850;
            }
            else if(fx.equals("U")){
                snakeY[0]=snakeY[0]-25;
                if(snakeY[0]<25) snakeY[0]=650;
            }
            else if(fx.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 keyTyped(KeyEvent e) {}
    @Override
    public void keyReleased(KeyEvent e) {}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值