Java GUI个人学习

Java GUI

1、简介

核心技术:

Swing、AWT

缺点:

  1. 界面不美观
  2. 运行需要jre

作用:

  1. 自己写需要的小工具

  2. 工作时可能需要维护到Swing界面

  3. 了解MVC架构,了解监听器

2、AWT

2.1、AWT介绍

  1. (抽象窗口工具) 包含很多类和接口
  2. 元素:窗口、按钮、文本框
  3. 导入java.awt包

在这里插入图片描述

2.2、组件和容器

2.2.1、Frame
        //新建窗口
        Frame frame=new Frame("my first java gui window");
        //需要设置可见性
        frame.setVisible(true);
        //设置窗口大小、颜色、初始位置、不可改变大小
        frame.setSize(400,400);
        frame.setBackground(Color.gray);
        frame.setLocation(200,200);
        frame.setResizable(false);
2.2.2、Pannel

可以看作一个空间,但不能单独存在,在Frame内部

 		//新建面板
        Panel panel=new Panel();
        //pannel设置,相对于frame
        panel.setBounds(50,50,200,200);
        panel.setBackground(Color.yellow);
        //pannel加入frame
        frame.add(panel);

        //监听窗口关闭
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
                //1指的是异常退出
            }
        });

2.3、布局管理器

  1. 流式布局(所有布局从左到右)
  2. 边框布局(相对)
  3. 表格布局
		//流式布局
		frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
        frame.setVisible(true);
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
		//边框布局
		frame.add(button1,BorderLayout.CENTER);
        frame.add(button2,BorderLayout.EAST);
        frame.add(button3,BorderLayout.NORTH);
        frame.setVisible(true);
		//设置为表格布局
        frame.setLayout(new GridLayout(1,3));
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.setVisible(true);
        frame.pack();//自动适应大小


在这里插入图片描述

在这里插入图片描述

三者嵌套:

		//定义窗口
        Frame frame=new Frame();

        //定义四个面板,上、下、上中、下中
        Panel panelup,paneldown,panelcu,panelcd;

        panelup=new Panel(new BorderLayout());//边框布局
        paneldown=new Panel(new BorderLayout());
        panelcu=new Panel(new GridLayout(2,1));//表格布局
        panelcd=new Panel(new GridLayout(2,2));
        frame.setLayout(new GridLayout(2,1));

        frame.setVisible(true);
        frame.setBounds(400,300,300,300);

        //上下两个面板添加模块
        panelup.add(new Button("Buttonu-1"),BorderLayout.WEST);
        panelup.add(panelcu,BorderLayout.CENTER);
        panelup.add(new Button("Buttonu-2"),BorderLayout.EAST);
        paneldown.add(new Button("Buttond-1"),BorderLayout.WEST);
        paneldown.add(panelcd,BorderLayout.CENTER);
        paneldown.add(new Button("Buttond-2"),BorderLayout.EAST);

        //上中、下中两个面板添加模块
        panelcu.add(new Button("Buttoncu-1"));
        panelcu.add(new Button("Buttoncu-2"));
        for(int i=1;i<=4;i++){
            panelcd.add(new Button("Buttoncd-"+i));
        }

        frame.add(panelup);
        frame.add(paneldown);

在这里插入图片描述

2.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("开始-结束");
        frame.setBounds(400,400,400,300);
        frame.setVisible(true);
        //设置开始、结束两个按钮
        Button button1=new Button("start");
        Button button2=new Button("end");
        //定义为边框布局
        frame.setLayout(new BorderLayout());
        frame.add(button1,BorderLayout.NORTH);
        frame.add(button2,BorderLayout.SOUTH);
        //定义点击事件
        MyActionMonitor monitor=new MyActionMonitor();
        button1.addActionListener(monitor);
        button2.addActionListener(monitor);
        //监听关闭窗口
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}
//重写点击监听器,多个按钮使用同一个监听器,更加方便
class MyActionMonitor implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("按钮被点击!点击了:"+e.getActionCommand());
    }
}

2.5、输入框TextField

​ 在监听器内实现获取输入框内容:

TextField field=(TextField)e.getSource();
String string=field.getText();

​ 设置编码,如密码不可见:

textField.setEchoChar('*');

​ 键入回车时清空文本框:

field.setText("");

2.6、简易计算器的实现

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) {
        Calculator calculator=new Calculator();
    }
}

class Calculator extends Frame{
    public Calculator(){
        //定义元素
        Frame frame=new Frame("加法计算器");
        TextField text1=new TextField(10);
        TextField text2=new TextField(10);
        TextField text3=new TextField(20);
        Label label=new Label("+");
        Button button=new Button("=");
        //流式加入窗口
        frame.setLayout(new FlowLayout());
        frame.add(text1);
        frame.add(label);
        frame.add(text2);
        frame.add(button);
        frame.add(text3);
        frame.pack();
        frame.setVisible(true);
        //给按钮添加监听
        MyCalculatorListener monitor=new MyCalculatorListener(text1,text2,text3);
        button.addActionListener(monitor);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
}

class MyCalculatorListener implements ActionListener{
    private TextField t1,t2,t3;
    public MyCalculatorListener(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());
        t3.setText(String.valueOf(a+b));
        t1.setText("");
        t2.setText("");
    }
}

运行截图:

在这里插入图片描述
在这里插入图片描述

2.7、画笔Graphics

@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);//画矩形
    //画笔用完后需还原到最初颜色(黑色)
}

2.8、鼠标监听

鼠标点击画笔模拟:

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;

public class TestPaint {
    public static void main(String[] args) {
        //新建窗口,MyPaint继承自Frame
        new MyPaint("画图");
    }
}

class MyPaint extends Frame{
    //存储所有点击的点集
    private ArrayList<Point> points;
    //构造函数,注册关闭窗口的点击监听和画图鼠标点击监听
    public MyPaint(String title){
        super(title);
        points=new ArrayList<>();
        setBounds(400,300,600,400);
        setVisible(true);
        //监听鼠标点击,MyMouseMonitor继承自MouseAdapter
        this.addMouseListener(new MyMouseMonitor());
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }
    //绘图,使用迭代器
    @Override
    public void paint(Graphics g){
        Iterator iterator=points.iterator();
        while (iterator.hasNext()){
            Point point=(Point) iterator.next();
            g.setColor(Color.BLACK);
            g.fillOval(point.x,point.y,10,10);
        }
    }
    //新加点
    public void addPaint(Point point){
        points.add(point);
    }
    //鼠标点击监听
    private class MyMouseMonitor extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            //获取窗口
            MyPaint mypaint=(MyPaint) e.getSource();
            mypaint.addPaint(new Point(e.getX(),e.getY()));
            //刷新,重新绘图
            mypaint.repaint();
        }
    }
}

在这里插入图片描述

窗口监听、键盘监听类似。

3、Swing

AWT——底层

Swing——封装,更高级

3.1、窗口与面板

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

public class TestJFrame {
    //初始化
    public void init(){
        //JFrame是顶级窗口
        JFrame jFrame=new JFrame("JFrame");
        jFrame.setVisible(true);
        jFrame.setBounds(100,100,200,200);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JLabel jLabel=new JLabel("My first JFrame demo");
        //设置label居中
        jLabel.setHorizontalAlignment(SwingConstants.CENTER);
        jFrame.add(jLabel);

        //容器实例化,获得一个容器
        Container container=jFrame.getContentPane();
        //无法直接设置JFrame颜色
        container.setBackground(Color.YELLOW);
    }
    public static void main(String[] args) {
        new TestJFrame().init();
    }
}

3.2、弹窗

JDialog类,监听器弹出,默认有关闭方法。

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

public class TestDialog extends JFrame {
    public TestDialog(){
        super("TestDialogDemo");
        setVisible(true);
        setSize(700,500);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        Container container=this.getContentPane();
        //绝对定位,全部写死
        container.setLayout(null);

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

        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new MyDialogDemo();
            }
        });
    }

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

class MyDialogDemo extends JDialog{
    public MyDialogDemo(){
        setVisible(true);
        setBounds(100,100,500,500);

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

        container.add(new Label("这是一个弹窗"));
    }
}

在这里插入图片描述

3.4、Icon与ImageIcon

Icon是一个接口,ImageIcon继承自Icon。

package TestIcon;

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

public class IconDemo extends JFrame  {
    public IconDemo() {
        JLabel label = new JLabel("icon_test");
        URL url = IconDemo.class.getResource("pierce.jpg");

        ImageIcon imageIcon = new ImageIcon(url);
        //图标可以放在按钮、标签等元素上
        label.setIcon(imageIcon);
        label.setHorizontalAlignment(SwingConstants.CENTER);

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

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

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

3.5、JScroll

指侧边滚动条。

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

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

        JTextArea jTextArea=new JTextArea(20,50);
        jTextArea.setText("");

        //container面板套jScrollPane面板,后者再套文本域
        JScrollPane jScrollPane=new JScrollPane(jTextArea);
        container.add(jScrollPane);

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

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

在这里插入图片描述

3.6、Button

  • 按钮——Button
  • 图片按钮——Button加入图片标签
  • 单选框——RadioButton
  • 复选框——CheckBox

皆与安卓类似。

3.7、列表框、下拉框、文本框

  • 下拉框:JComboBox
  • 列表框:JList(展示信息,动态扩容)
  • 文本框:JTextField,前述
  • 密码框:JPasswordField
  • 文本域:JTextArea

4、应用:贪吃蛇

启动类:

package Snake;

import javax.swing.*;

public class StartGame {
    //主启动类
    public static void main(String[] args) {
        JFrame jFrame=new JFrame();

        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jFrame.setBounds(100,100,1000,800);
        jFrame.setResizable(false);

        jFrame.add(new GamePanel());

        jFrame.setVisible(true);
    }
}

面板类:

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;//长度小于54
    int[] snakeX=new int[60];//蛇的X坐标
    int[] snakeY=new int[60];//蛇的Y坐标
    String fx;//方向
    boolean isStart=false;//是否开始
    Timer timer=new Timer(100,this);//100ms执行一次,监听本类
    //食物的坐标
    int foodx,foody;
    Random random=new Random();
    //游戏是否失败
    boolean isFail=false;
    //成绩
    int score;

    public GamePanel(){
        init();
        //获得焦点和键盘事件
        this.setFocusable(true);
        this.addKeyListener(this);
        timer.start();//游戏开始,定时器启动
    }

    //初始化
    public void init(){
        length=3;
        snakeX[0]=350;snakeY[0]=310;
        snakeX[1]=250;snakeY[1]=310;
        snakeX[2]=150;snakeY[2]=310;
        fx="R";
        //随机食物坐标
        foodx=50+100*random.nextInt(9);
        foody=210+100*random.nextInt(6);
        //初始化积分
        score=0;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//清屏
        //绘制静态面板
        this.setBackground(Color.black);
        Data.header.paintIcon(this,g,50,5);
        g.setColor(Color.white);
        g.fillRect(50,210,900,600);

        //画小蛇
        switch (fx){
            case "R":Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);break;
            case "L":Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);break;
            case "U":Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);break;
            case "D":Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);break;
        }
        for(int i=1;i<length;i++){
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);
        }

        //画食物
        Data.food.paintIcon(this,g,foodx,foody);

        //画积分
        g.setColor(Color.BLACK);
        g.setFont(new Font("微软雅黑",Font.BOLD,18));
        g.drawString("长度:"+length,880,80);
        g.drawString("分数:"+score,880,120);

        if(!isStart){
            g.setColor(Color.BLACK);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("按下空格开始游戏",350,500);
        }

        if(isFail){
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑",Font.BOLD,40));
            g.drawString("失败!按下空格开始游戏",350,500);
        }
    }

    //键盘监听器
    @Override
    public void keyTyped(KeyEvent e) {}
    @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";
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {}

    //事件监听(定时器,1s十次)
    @Override
    public void actionPerformed(ActionEvent e) {
        if(isStart&&!isFail){
            //吃食物
            if(snakeX[0]==foodx&&snakeY[0]==foody){
                length++;
                //再次随机食物坐标
                foodx=50+100*random.nextInt(9);
                foody=210+100*random.nextInt(6);
                score+=10;
            }

            //身子移动
            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]+100;
                //边界判断
                if(snakeX[0]>900){
                    snakeX[0]=50;
                }
            }else if(fx.equals("L")){
                snakeX[0]=snakeX[0]-100;
                if(snakeX[0]<50){
                    snakeX[0]=950;
                }
            }else if(fx.equals("U")){
                snakeY[0]=snakeY[0]-100;
                if(snakeY[0]<210){
                    snakeY[0]=810;
                }
            }else if(fx.equals("D")){
                snakeY[0]=snakeY[0]+100;
                if(snakeY[0]>760){
                    snakeY[0]=210;
                }
            }

            //失败判定(撞到自己)
            for(int i=1;i<length;i++){
                if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){
                    isFail=true;
                }
            }
            repaint();
        }
        timer.start();
    }
}

数据类:

package Snake;

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

//数据中心
public class Data {
    public static URL headerURL=Data.class.getResource("static/header.png");
    public static ImageIcon header=new ImageIcon(headerURL);

    public static URL bodyURL=Data.class.getResource("static/body.png");
    public static ImageIcon body=new ImageIcon(bodyURL);

    public static URL foodURL=Data.class.getResource("static/food.png");
    public static ImageIcon food=new ImageIcon(foodURL);

    public static URL upURL=Data.class.getResource("static/up.png");
    public static ImageIcon up=new ImageIcon(upURL);

    public static URL downURL=Data.class.getResource("static/down.png");
    public static ImageIcon down=new ImageIcon(downURL);

    public static URL leftURL=Data.class.getResource("static/left.png");
    public static ImageIcon left=new ImageIcon(leftURL);

    public static URL rightURL=Data.class.getResource("static/right.png");
    public static ImageIcon right=new ImageIcon(rightURL);
}

运行效果:
在这里插入图片描述

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值