【Java基础】swing-图形界面学习(上)

就是个人学习的笔记,按照下面的Demo一个一个复制粘贴跑起来大概就会使用Swing了

【Java基础】swing-图形界面学习(下)

Swing

  • Swing 是一个为Java设计的GUI工具包。

Swing开发的图形界面比AWT更加轻量级,使用100%的java开发不再依赖本地图形界面可以在所有平台保持相同的运行效果。
优点:

  1. Swing组建不再依赖本地平台GUI无需采用各种平台的GUI交集,因此Swing提供大量图形界面组件
  2. Swing组建不再依赖本地GUI不会产生平台相关bug
  3. Swing组件在各种平台上运行可以保证具有相同的图形界面外观
  4. Swing采用MVC(model-view-controller,模型-视图-控制器)设计模式,模型用于维护组件的状态,视图是组件的可视化表现,控制器用于控制各个事件,组件做出怎么样的响应。模型发生改变,它通知所有依赖它的视图,视图根据模型数据来更新自己。

一.快速开始

  • JFrame是GUI中的容器
  • JButton是最常见的组件- 按钮

    注意:f.setVisible(true);会对所有的组件进行渲染,所以一定要放在最后面

public static void main(String[] args) {
		// 主窗体
		JFrame f = new JFrame("LoL");
		// 主窗体设置大小
		f.setSize(400, 300);
		// 主窗体设置位置
		f.setLocation(200, 200);
		// 主窗体中的组件设置为绝对定位
		f.setLayout(null);
		// 按钮组件
		JButton b = new JButton("一键秒对方基地挂");
		// 同时设置组件的大小和位置
		b.setBounds(50, 50, 280, 30);
		// 把按钮加入到主窗体中
		f.add(b);
		// 关闭窗体的时候,退出程序
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		// 让窗体变得可见
		f.setVisible(true);

	}

结果
在这里插入图片描述

练习-在上次关闭位置启动窗口

比如这次使用这个窗口,导致窗口被移动到了右下角。 关闭这个窗口,下一次再启动的时候,就会自动出现在右下角。

思路提示:

  • 启动一个线程,每个100毫秒读取当前的位置信息,保存在文件中,比如location.txt文件。
  • 启动的时候,从这个文件中读取位置信息,如果是空的,就使用默认位置,如果不是空的,就把位置信息设置在窗口上。
  • 读取位置信息的办法: f.getX() 读取横坐标信息,f.getY()读取纵坐标信息。

注: 这个练习要求使用多线程来完成。 还有另一个思路来完成,就是使用监听器,因为刚开始学习GUI,还没有掌握监听器的使用,所以暂时使用多线程来完成这个功能。

public class TestGUI {

    public static void main(String[] args) {
    	//classPath下面创建名为location.txt的文件用户保存窗口坐标
        String fileName = "location.txt";

        String data = readClassPathFile(fileName);
        if (StringUtils.isEmpty(data)) {
            data = writeLocation(null, data);
        }
        JSONObject location = JSONObject.parseObject(data);

        // 主窗体
        JFrame f = new JFrame("LoL");
        // 主窗体设置大小
        f.setSize(400, 300);
        // 主窗体设置位置
        f.setLocation(location.getInteger("x"), location.getInteger("y"));
        // 主窗体中的组件设置为绝对定位
        f.setLayout(null);

        // 按钮组件
        JButton b = new JButton("一键秒对方基地挂");
        // 设置按钮组件的大小和位置
        b.setBounds(50, 50, 280, 30);

        // 把按钮加入到主窗体中
        f.add(b);
        // 关闭窗体的时候,退出程序
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 让窗体变得可见
        f.setVisible(true);


        //异步保存当前窗口坐标
        new Thread(() -> {
            while (true) {
                try {
                    TimeUnit.MILLISECONDS.sleep(1500);
                    writeLocation(f, fileName);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }


    /**
     * 写入窗口坐标到clpassPath下面的文件
     * @param f
     * @param fileName
     */
    public static String writeLocation(JFrame f, String fileName) {
        JSONObject json = new JSONObject();
        if (f == null) {
            json.put("x", "200");
            json.put("y", "200");
            System.out.println("初始坐标=>" + json);
        } else {
            json.put("x", f.getX());
            json.put("y", f.getY());
            System.out.println("当前坐标=>" + json);
            writeClassPathFile(fileName, json.toJSONString());
        }

        return json.toJSONString();
    }

    /**
     * 读取classPath下面的文件并转换成字符串
     * @param fileName
     * @return
     */
    public static String readClassPathFile(String fileName) {

        StringBuilder sb = new StringBuilder();
        String content = null;
        try (
                //读取classPath下面文件流
                InputStream in = TestGUI.class.getClassLoader().getResourceAsStream(fileName);
                BufferedReader br = new BufferedReader(new InputStreamReader(in));
        ) {
            while ((content = br.readLine()) != null) {
                sb.append(content);
            }

            return sb.toString();

        } catch (IOException e) {
            e.printStackTrace();
        }

        return "";
    }


    /**
     * 向classPath下的文件写入指定内容
     * @param fileName
     * @return
     */
    public static boolean writeClassPathFile(String fileName, String data) {
        URL url = TestGUI.class.getClassLoader().getResource(fileName);
        File file = new File(url.getFile());

        try (
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
        ) {
            bw.write(data);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}

二.事件监听

关键字简介
ActionListener按钮监听
KeyListener键盘监听
MouseListener鼠标监听
Adapter适配器

2.1.按钮监听

创建一个匿名类实现ActionListener接口,当按钮被点击时,actionPerformed方法就会被调用

在这里插入图片描述

  • 在本例中,使用ActionListener监听按钮点击使用,通过点击按钮控制图片显示和隐藏
     public static void main(String[] args) {


        JFrame jFrame = new JFrame("LoL");
        jFrame.setSize(400, 300);
        jFrame.setLocation(580, 200);
        jFrame.setLayout(null);

        final JLabel jLabel = new JLabel();

        String imgPath = "e:/data/gareen.jpg";
        ImageIcon imageIcon = new ImageIcon(imgPath);
        jLabel.setIcon(imageIcon);
        jLabel.setBounds(50, 50, imageIcon.getIconWidth(), imageIcon.getIconHeight());

        JButton button = new JButton("隐藏图片");
        button.setBounds(150, 200, 100, 30);

        //原子性保存显示和隐藏状态
        AtomicBoolean isHide = new AtomicBoolean(false);
        
        // 给按钮 增加 监听
        button.addActionListener((e) -> {
            //按钮显示文本
            String txt = isHide.get() ? "显示图片" : "隐藏图片";
            //切换状态
            isHide.set(!isHide.get());
            //设置显示状态 true显示 /false隐藏
            jLabel.setVisible(isHide.get());
            //设置按钮文本
            button.setText(txt);
        });

        jFrame.add(jLabel);
        jFrame.add(button);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        jFrame.setVisible(true);
    }

2.2.键盘监听

键盘监听器: KeyListener

  • keyPressed 代表 键被按下
  • keyReleased 代表 键被弹起
  • keyTyped 代表 一个按下弹起的组合动作

KeyEvent.getKeyCode()可以获取当前点下了哪个键

  • 在本例中,使用KeyListener监听键盘被按下动作,当按下键盘的上下左右时窗口会进行对应移动
  • 提示:keyCode与方向的对应关系38 上,40 下,37 左,39 右
 public static void main(String[] args) {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        final JLabel label = new JLabel();

        String imgPath = "e:/data/gareen.jpg";
        ImageIcon imageIcon = new ImageIcon(imgPath);
        label.setIcon(imageIcon);
        label.setBounds(50, 50, imageIcon.getIconWidth(), imageIcon.getIconHeight());


        // 增加键盘监听
        frame.addKeyListener(new KeyListener() {
            // 键被弹起
            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("keyReleased=>" + e);
            }

            //键被按下时控制窗口坐标
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == 38) { // 38代表按下了 “上键”
                    // 图片向右移动 (窗口x坐标不变,y坐标减少)
                    frame.setLocation(frame.getX(), frame.getY() - 10);
                } else if (e.getKeyCode() == 40) {//40代表按下了 “下键”
                    // 图片向右移动 (窗口x坐标不变,y坐标增加)
                    frame.setLocation(frame.getX(), frame.getY() + 10);
                } else if (e.getKeyCode() == 37) {// 37代表按下了 “左键”
                    // 图片向左移动 (窗口y坐标不变,x坐标减少)
                    frame.setLocation(frame.getX() - 10, frame.getY());
                } else if (e.getKeyCode() == 39) {// 39代表按下了 “右键”
                    // 图片向右移动 (窗口y坐标不变,x坐标增加)
                    frame.setLocation(frame.getX() + 10, frame.getY());
                }
            }

            // 一个按下弹起的组合动作
            @Override
            public void keyTyped(KeyEvent e) {
                System.out.println("keyTyped=>" + e);
            }
        });


        frame.add(label);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

2.3.鼠标监听

MouseListener 鼠标监听器

  • mouseReleased 鼠标释放
  • mousePressed 鼠标按下
  • mouseExited 鼠标退出
  • mouseEntered 鼠标进入
  • mouseClicked 鼠标点击

在本例中,使用mouseEntered,当鼠标进入图片的时候,图片就会移动位置

    public static void main(String[] args) {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        final JLabel label = new JLabel();

        String imgPath = "e:/data/gareen.jpg";
        ImageIcon imageIcon = new ImageIcon(imgPath);
        label.setIcon(imageIcon);
        label.setBounds(50, 50, imageIcon.getIconWidth(), imageIcon.getIconHeight());


        label.addMouseListener(new MouseListener() {
            // 释放鼠标
            @Override
            public void mouseReleased(MouseEvent e) {

            }
            // 按下鼠标
            @Override
            public void mousePressed(MouseEvent e) {

            }
            // 鼠标退出
            @Override
            public void mouseExited(MouseEvent e) {

            }
            // 鼠标进入
            @Override
            public void mouseEntered(MouseEvent e) {

                Random r = new Random();

                int x = r.nextInt(frame.getWidth() - label.getWidth());
                int y = r.nextInt(frame.getHeight() - label.getHeight());

                label.setLocation(x, y);

            }
            // 按下释放组合动作为点击鼠标
            @Override
            public void mouseClicked(MouseEvent e) {

            }
        });

        frame.add(label);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

2.4.适配器

这里以MouseAdapter 鼠标监听适配器为例,一般说来在写监听器的时候,会实现MouseListener接口
但是MouseListener接口里面有很多方法都没有用到,比如mouseReleased ,mousePressed,mouseExited等等。

  • 这个时候就可以使用 鼠标监听适配器MouseAdapter,只需要重写必要的方法即可。

在本例中,使用MouseAdapter只重写了mouseEntered方法,当鼠标进入图片的时候,图片就会移动位置

    public static void main(String[] args) {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        final JLabel label = new JLabel();

        String imgPath = "e:/data/gareen.jpg";
        ImageIcon imageIcon = new ImageIcon(imgPath);
        label.setIcon(imageIcon);
        label.setBounds(50, 50, imageIcon.getIconWidth(), imageIcon.getIconHeight());

        // MouseAdapter 适配器,只需要重写用到的方法,没有用到的就不用写了
        label.addMouseListener(new MouseAdapter() {

            // 只有mouseEntered用到了
            @Override
            public void mouseEntered(MouseEvent e) {

                Random r = new Random();

                int x = r.nextInt(frame.getWidth() - label.getWidth());
                int y = r.nextInt(frame.getHeight() - label.getHeight());

                label.setLocation(x, y);

            }
        });

        frame.add(label);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

三.容器

java的图形界面中,容器是用来存放按钮输入框等组件的。

  • 窗体型容器有两个,一个是JFrame,一个是JDialog

3.1.JFrame

JFrame是最常用的窗体型容器,默认右上角最大化最小化按钮

在这里插入图片描述

 public static void main(String[] args) {
        //普通的窗体,带最大和最小化按钮
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);
        JButton btn  = new JButton("一键秒对方基地挂");
        btn .setBounds(50, 50, 280, 30);
 
        frame.add(btn );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

3.2.JDialog

JDialog也是窗体型容器,右上角没有最大和最小化按钮,通常做为弹窗来使用
在这里插入图片描述

public static void main(String[] args) {
        //普通的窗体,带最大和最小化按钮,而对话框却不带
        JDialog dialog = new JDialog();
        dialog .setTitle("LOL");
        dialog .setSize(400, 300);
        dialog .setLocation(200, 200);
        dialog .setLayout(null);
        JButton btn = new JButton("一键秒对方基地挂");
        btn .setBounds(50, 50, 280, 30);
 
        dialog .add(btn );
        dialog .setVisible(true);
    }

3.3.模态JDialog+锁定窗体大小

当一个对话框被设置为模态的时候,其背后的父窗体,是不能被激活的,除非该对话框被关闭

通过调用方法 setResizable(false); 做到窗体大小不可变化、默认为true,不锁定窗口大小

本例是一个JFrame,上面有一个按钮,文字是 “打开一个模态况”。 点击该按钮后,随即打开一个模态窗口。 在这个模态窗口中有一个按钮,文本是 “锁定大小”, 点击后,这个模态窗口的大小就被锁定住,不能改变。 再次点击,就回复能够改变大小
在这里插入图片描述

    public static void main(String[] args) {
        JFrame frame = new JFrame("外部窗体");
        frame.setSize(800, 600);
        frame.setLocation(100, 100);
        frame.setLayout(null);

        JButton button1 = new JButton("打开一个模态框");
        button1.setBounds(200, 200, 280, 30);
        frame.add(button1);


        button1.addActionListener((e) -> {
            // 根据外部窗体实例化JDialog
            JDialog dialog = new JDialog();
            // 设置为模态
            dialog.setModal(true);
            dialog.setTitle("模态的对话框");
            dialog.setSize(400, 300);
            dialog.setLocation(200, 200);
            dialog.setLayout(null);

            JButton button2 = new JButton("锁定大小");
            button2.setBounds(50, 50, 280, 30);
            dialog.add(button2);

            AtomicBoolean aBoolean = new AtomicBoolean(true);
            button2.addActionListener(e2 -> {
                aBoolean.set(!aBoolean.get());
                button2.setText(aBoolean.get()?"锁定大小" : "解锁大小");

                //通过调用方法 setResizable(false); 做到窗体大小不可变化
                dialog.setResizable(aBoolean.get());//默认为true,不锁定大小
            });

            dialog.setVisible(true);
        });

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

四.常见的布局器

布局器是用在容器上的。 用来决定容器上的组件摆放的位置和大小

  • 绝对定位
  • FlowLayout
  • BorderLayout
  • GridLayout
  • setPreferredSize
  • CardLayout

4.1.绝对定位

绝对定位就是指不使用布局器,组件的位置大小需要单独指定

    @Test
    public void absolute_positioning() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        // 设置布局器为null,即进行绝对定位,容器上的组件都需要指定位置和大小
        frame.setLayout(null);
        JButton b1 = new JButton("英雄1");
        // 指定位置和大小
        b1.setBounds(50, 50, 80, 30);
        JButton b2 = new JButton("英雄2");
        b2.setBounds(150, 50, 80, 30);
        JButton b3 = new JButton("英雄3");
        b3.setBounds(250, 50, 80, 30);
        // 没有指定位置和大小,不会出现在容器上
        JButton b4 = new JButton("英雄3");

        frame.add(b1);
        frame.add(b2);
        frame.add(b3);
        // b4没有指定位置和大小,不会出现在容器上
        frame.add(b4);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

4.2.FlowLayout

设置布局器为FlowLayout(顺序布局器):容器上的组件水平摆放加入到容器即可,(无需单独指定大小和位置)
在这里插入图片描述

	@Test
    public void FlowLayout() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        // 设置布局器为FlowLayerout=>容器上的组件水平摆放
        frame.setLayout(new FlowLayout());

        JButton b1 = new JButton("英雄1");
        JButton b2 = new JButton("英雄2");
        JButton b3 = new JButton("英雄3");

        // 加入到容器即可,无需单独指定大小和位置
        frame.add(b1);
        frame.add(b2);
        frame.add(b3);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

4.3.BorderLayout

设置布局器为BorderLayout:容器上的组件按照上北 下南 左西 右东 中的顺序摆放
在这里插入图片描述

 @Test
    public void BorderLayout() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        // 设置布局器为BorderLayerout=>容器上的组件按照上北下南左西右东中的顺序摆放
        frame.setLayout(new BorderLayout());

        JButton northB = new JButton("洪七");
        JButton southB = new JButton("段智兴");
        JButton westB = new JButton("欧阳锋");
        JButton eastB = new JButton("黄药师");
        JButton centerB = new JButton("周伯通");

        // 加入到容器的时候,需要指定位置
        frame.add(northB, BorderLayout.NORTH);//上北
        frame.add(southB, BorderLayout.SOUTH);//下南
        frame.add(westB, BorderLayout.WEST);//左西
        frame.add(eastB, BorderLayout.EAST);//右东
        frame.add(centerB, BorderLayout.CENTER);//中间

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

4.4.GridLayout

GridLayout,即网格布局器
在这里插入图片描述

   @Test
    public void GridLayout() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        // 设置布局器为GridLayerout,即网格布局器=>该GridLayerout的构造方法表示该网格是2行3列
        frame.setLayout(new GridLayout(2, 3));

        JButton b1 = new JButton("洪七");
        JButton b2 = new JButton("段智兴");
        JButton b3 = new JButton("欧阳锋");
        JButton b4 = new JButton("黄药师");
        JButton b5 = new JButton("周伯通");

        frame.add(b1);
        frame.add(b2);
        frame.add(b3);
        frame.add(b4);
        frame.add(b5);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

4.5.setPreferredSize

即使使用了布局器 ,也可以 通过setPreferredSize,向布局器建议该组件显示的大小.

注 只对部分布局器起作用,比如FlowLayout可以起作用。 比如GridLayout就不起作用,因为网格布局器必须对齐
在这里插入图片描述

    @Test
    public void setPreferredSize() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(new FlowLayout());

        JButton b1 = new JButton("英雄1");
        JButton b2 = new JButton("英雄2");
        JButton b3 = new JButton("英雄3");

        // 即便 使用布局器 ,也可以 通过setPreferredSize,向布局器建议该组件b3按钮显示的大小
        b3.setPreferredSize(new Dimension(180, 40));

        frame.add(b1);
        frame.add(b2);
        frame.add(b3);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

4.6.CardLayout

因为需要用到面板,放在后面讲: CardLayout

4.7.练习:使用布局器做出计算器上的按钮效果

在这里插入图片描述

    @Test
    public void practice() throws InterruptedException {
        JFrame frame = new JFrame("计算器");
        frame.setBounds(300, 400, 800, 600);//坐标为 300,400 长宽为600/800
        frame.setLayout(new GridLayout(4, 5, 8, 8));//网格布局为4行4列 上下左右间隔为8/8

        String[] arr = {"7", "8", "9", "/", "sq", "4", "5", "6", "*", "%", "1", "2", "3", "-", "1/x", "0", "+/-", ".", "+", "="};
        for (int i = 0; i < 20; i++) {
            frame.add(new JButton(arr[i]));
        }
        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

五.组件

JAVA的图形界面下有两组控件,一组是awt,一组是swing。一般都是使用swing

  • JLabel 标签
  • setIcon 使用JLabel显示图片
  • JButton 按钮
  • JCheckBox 复选框
  • JRadioButton 单选框
  • ButtonGroup 按钮组
  • JComboBox 下拉框
  • JOptionPane 对话框
  • JTextField 文本框
  • JPasswordField 密码框
  • JTextArea 文本域
  • JProgressBar 进度条
  • JFileChooser 文件选择器

5.1.Label

Label(标签)用于显示文字
在这里插入图片描述

    @Test
    public void JLabel() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);//

        JLabel label = new JLabel("LOL文字");
        //文字颜色
        label.setForeground(Color.red);
        label.setBounds(50, 50, 280, 30);

        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.2.使用JLabel显示图片

Java GUI 显示图片是通过在label上设置图标实现的

  • 注: 这里的图片路径是e:/data/gareen.jpg,所以要确保这里有图片,不然不会显示在这里插入图片描述
    @Test
    public void JLabelShowImg() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        JLabel label = new JLabel();

        String imgPath = "e:/data/gareen.jpg";
        //根据图片创建ImageIcon对象
        ImageIcon img = new ImageIcon(imgPath);
        //设置ImageIcon
        label.setIcon(img);
        //label的大小设置为ImageIcon,否则显示不完整
        label.setBounds(50, 50, img.getIconWidth(), img.getIconHeight());

        frame.add(label);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.3.按钮

JButton 普通按钮
在这里插入图片描述

    @Test
    public void JButton() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);
        JButton b = new JButton("一键秒对方基地挂");
        b.setBounds(50, 50, 280, 30);

        frame.add(b);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.4.复选框

JCheckBox 复选框

使用isSelected来获取是否选中了
在这里插入图片描述

    @Test
    public void JCheckBox() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        JCheckBox bCheckBox1 = new JCheckBox("物理英雄");
        //设置 为 默认被选中
        bCheckBox1.setSelected(true);
        bCheckBox1.setBounds(50, 50, 130, 30);

        JCheckBox bCheckBox2 = new JCheckBox("魔法 英雄");
        bCheckBox2.setBounds(50, 100, 130, 30);
        //判断 是否 被 选中
        System.out.println(bCheckBox2.isSelected());

        frame.add(bCheckBox1);
        frame.add(bCheckBox2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.5.单选框

JRadioButton 单选框

  • 使用isSelected来获取是否选中了
    在这个例子里,两个单选框可以被同时选中,为了实现只能选中一个,还需要用到ButtonGroup
    在这里插入图片描述
    @Test
    public void JRadioButton() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 200);
        frame.setLayout(null);

        JRadioButton b1 = new JRadioButton("物理英雄");
        // 设置 为 默认被选中
        b1.setSelected(true);
        b1.setBounds(50, 50, 130, 30);

        JRadioButton b2 = new JRadioButton("魔法 英雄");
        b2.setBounds(50, 100, 130, 30);

        System.out.println(b2.isSelected());

        frame.add(b1);
        frame.add(b2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.6.按钮组

ButtonGroup 对按钮进行分组,把不同的按钮,放在同一个分组里 ,同一时间,只有一个 按钮 会被选中(比如说单选框)
在这里插入图片描述

    @Test
    public void ButtonGroup() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 240);
        frame.setLayout(null);

        JRadioButton b1 = new JRadioButton("物理英雄");
        b1.setSelected(true);
        b1.setBounds(50, 50, 130, 30);
        JRadioButton b2 = new JRadioButton("魔法 英雄");
        b2.setBounds(50, 100, 130, 30);

        // 按钮分组
        ButtonGroup bg = new ButtonGroup();
        // 把b1,b2放在 同一个 按钮分组对象里 ,这样同一时间,只有一个 按钮 会被选中
        bg.add(b1);
        bg.add(b2);

        frame.add(b1);
        frame.add(b2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.7.下拉框

JComboBox 下拉框

  • 使用getSelectedItem来获取被选中项
  • 使用setSelectedItem() 来指定要选中项
    在这里插入图片描述
    @Test
    public void JComboBox() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 240);
        frame.setLayout(null);

        //下拉框出现的条目
        String[] heros = new String[]{"卡特琳娜", "库奇"};
        JComboBox cb = new JComboBox(heros);

        cb.setBounds(50, 50, 80, 30);

        frame.add(cb);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.8.对话框

JOptionPane 用于弹出对话框

  • JOptionPane.showConfirmDialog(f, “是否 使用外挂 ?”);:表示询问,第一个参数是该对话框以哪个组件对齐
    在这里插入图片描述

  • JOptionPane.showInputDialog(f, “请输入yes,表明使用外挂后果自负”);:接受用户的输入
    在这里插入图片描述

  • JOptionPane.showMessageDialog(frame, “你使用外挂被抓住! 罚拣肥皂3次!”);:显示消息
    在这里插入图片描述

    @Test
    public void JOptionPane() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(580, 240);
        frame.setLayout(null);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        int option = JOptionPane.showConfirmDialog(frame, "是否 使用外挂 ?");
        if (JOptionPane.OK_OPTION == option) {
            String answer = JOptionPane.showInputDialog(frame, "请输入yes,表明使用外挂后果自负");
            if ("yes".equals(answer)) {
                JOptionPane.showMessageDialog(frame, "你使用外挂被抓住! 罚拣肥皂3次!");
            }
        }
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.9.文本框+密码框

JTextField 输入框

  • setText 设置文本
  • getText 获取文本

JTextField 是单行文本框,如果要输入多行数据,请使用JTextArea

  • tfPassword.grabFocus(); 表示让密码输入框获取焦点

JPasswordField 密码框
与文本框不同,获取密码框里的内容,推荐使用getPassword,该方法会返回一个字符数组,而非字符串
在这里插入图片描述

    @Test
    public void JInputAndPawword() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(new FlowLayout());

        JLabel lName = new JLabel("账号:");
        // 输入框
        JTextField tfName = new JTextField("");
        tfName.setText("请输入账号");
        tfName.setPreferredSize(new Dimension(80, 30));

        JLabel lPassword = new JLabel("密码:");
        // 密码框
        JPasswordField tfPassword = new JPasswordField("");
        tfPassword.setText("&48kdh4@#");
        tfPassword.setPreferredSize(new Dimension(80, 30));

        // 与文本框不同,获取密码框里的内容,推荐使用getPassword,该方法会返回一个字符数组,而非字符串
        char[] password = tfPassword.getPassword();
        String p = String.valueOf(password);
        System.out.println(p);

        frame.add(lName);
        frame.add(tfName);
        frame.add(lPassword);
        frame.add(tfPassword);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        tfPassword.grabFocus();
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.10.文本域

JTextArea:文本域可以输入多行数据

  • 如果要给文本域初始文本,通过\n来实现换行效果
  • JTextArea通常会用到append来进行数据追加
  • 如果文本太长,会跑出去,可以通过setLineWrap(true)来做到自动换行
    在这里插入图片描述
    @Test
    public void JTextArea() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(new FlowLayout());

        JLabel l = new JLabel("文本域:");

        JTextArea ta = new JTextArea();
        ta.setPreferredSize(new Dimension(300, 100));//设置大小
        //\n换行符
        ta.setText("抢人头!\n抢你妹啊抢!\n");
        //追加数据
        ta.append("我去送了了了了了了了了了了了了了了了了了了了了了了了了");
        //设置自动换行
        ta.setLineWrap(true);
        frame.add(l);
        frame.add(ta);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.11.进度条

在这里插入图片描述

 @Test
    public void JProgressBar() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(new FlowLayout());

        JProgressBar pb = new JProgressBar();
        //进度条最大1000
        pb.setMaximum(1000);
        //当前进度是50
        pb.setValue(50);
        //显示当前进度
        pb.setStringPainted(true);

        frame.add(pb);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

5.12.文件选择器

JFileChooser 表示文件选择器

在这里插入图片描述

使用FileFilter用于仅选择xlsx文件

        fileChooser.setFileFilter(new FileFilter() {
            @Override
            public String getDescription() {
                return ".xlsx";
            }

            @Override
            public boolean accept(File frame) {
                return frame.getName().toLowerCase().endsWith(".xlsx");
            }
        });
  • fileChooser.showOpenDialog(); 用于打开文件
  • fileChooser.showSaveDialog(); 用于保存文件
    @Test
    public void JFileChooser() throws InterruptedException {
        JFrame frame = new JFrame("LOL");
        frame.setLayout(new FlowLayout());

        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileFilter(new FileFilter() {
            @Override
            public String getDescription() {
                return ".xlsx";
            }

            @Override
            public boolean accept(File frame) {
                return frame.getName().toLowerCase().endsWith(".xlsx");
            }
        });

        JButton bOpen = new JButton("打开文件");
        JButton bSave = new JButton("保存文件");

        frame.add(bOpen);
        frame.add(bSave);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(250, 150);
        frame.setLocationRelativeTo(null);

        frame.setVisible(true);

        //打开文件
        bOpen.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int returnVal = fileChooser.showOpenDialog(frame);
                File file = fileChooser.getSelectedFile();
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    JOptionPane.showMessageDialog(frame, "计划打开文件:" + file.getAbsolutePath());
                }

            }
        });

        //保存文件
        bSave.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int returnVal = fileChooser.showSaveDialog(frame);
                File file = fileChooser.getSelectedFile();
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    JOptionPane.showMessageDialog(frame, "计划保存到文件:" + file.getAbsolutePath());
                }
            }
        });

        //设置休眠时间,是为了延缓主线程销毁
        TimeUnit.SECONDS.sleep(1000);
    }

六.面板

  • 基本面板
  • ContentPane
  • SplitPanel
  • JScrollPanel
  • TabbedPanel
  • CardLayerout

6.1.基本面板

JPanel即为基本面板

  • 面板和JFrame一样都是容器,不过面板一般用来充当中间容器把组件放在面板上,然后再把面板放在窗体上
  • 一旦移动一个面板,其上面的组件,就会全部统一跟着移动,采用这种方式,便于进行整体界面的设计`
    在这里插入图片描述
 @Test
    public void base() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(null);

        JPanel panel1 = new JPanel();
        // 设置面板大小
        panel1.setBounds(50, 50, 300, 60);
        // 设置面板背景颜色
        panel1.setBackground(Color.RED);
        // 这一句可以没有,因为JPanel默认就是采用的FlowLayout
        panel1.setLayout(new FlowLayout());

        JButton b1 = new JButton("英雄1");
        JButton b2 = new JButton("英雄2");
        JButton b3 = new JButton("英雄3");
        // 把按钮加入面板
        panel1.add(b1);
        panel1.add(b2);
        panel1.add(b3);

        JPanel panel2 = new JPanel();
        JButton b4 = new JButton("英雄4");
        JButton b5 = new JButton("英雄5");
        JButton b6 = new JButton("英雄6");
        // 把按钮加入面板
        panel2.add(b4);
        panel2.add(b5);
        panel2.add(b6);

        panel2.setBackground(Color.BLUE);
        panel2.setBounds(10, 150, 300, 60);

        // 把面板加入窗口
        frame.add(panel1);
        frame.add(panel2);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        TimeUnit.SECONDS.sleep(1000);
    }

6.2.ContentPane

JFrame上有一层面板,叫做ContentPane

  • 平时通过frame.add()向JFrame增加组件,其实是向JFrame上的 ContentPane加东西
 @Test
    public void ContentPane() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);
        JButton b = new JButton("一键秒对方基地挂");
        b.setBounds(50, 50, 280, 30);

        frame.add(b);
        // frame.add等同于frame.getContentPane().add(b);
        frame.getContentPane().add(b);

        // b.getParent()获取按钮b所处于的容器
        // 打印出来可以看到,实际上是ContentPane而非JFrame
        System.out.println(b.getParent());//javax.swing.JPanel[null.contentPane,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,preferredSize=]

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        TimeUnit.SECONDS.sleep(1000);
    }

6.3.SplitPanel

创建一个水平JSplitPane,左边是pLeft,右边是pRight
在这里插入图片描述

  @Test
    public void SplitPanel() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);

        JPanel pLeft = new JPanel();
        pLeft.setBounds(50, 50, 300, 60);
        pLeft.setBackground(Color.RED);
        pLeft.setLayout(new FlowLayout());

        JButton b1 = new JButton("盖伦");
        JButton b2 = new JButton("提莫");
        JButton b3 = new JButton("安妮");

        pLeft.add(b1);
        pLeft.add(b2);
        pLeft.add(b3);

        JPanel pRight = new JPanel();
        JButton b4 = new JButton("英雄4");
        JButton b5 = new JButton("英雄5");
        JButton b6 = new JButton("英雄6");

        pRight.add(b4);
        pRight.add(b5);
        pRight.add(b6);

        pRight.setBackground(Color.BLUE);
        pRight.setBounds(10, 150, 300, 60);

        // 创建一个水平JSplitPane,左边是p1,右边是p2
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pLeft, pRight); //JSplitPane.VERTICAL_SPLIT垂直分割  JSplitPane.HORIZONTAL_SPLIT水平分割
        // 设置分割条的位置
        splitPane.setDividerLocation(80);

        // 把sp当作ContentPane
        frame.setContentPane(splitPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        TimeUnit.SECONDS.sleep(1000);
    }

6.4.JScrollPanel

使用带滚动条的面板有两种方式

  1. 在创建JScrollPane,把组件作为参数传进去
JScrollPane scrollPane = new JScrollPane(textArea);
  1. 希望带滚动条的面板显示其他组件的时候,调用setViewportView
scrollPane.setViewportView(textArea);

在这里插入图片描述

    @Test
    public void JScrollPanel() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);
        frame.setLayout(null);

        //准备一个文本域,在里面放很多数据
        JTextArea textArea = new JTextArea();
        for (int i = 0; i < 1000; i++) {
            textArea.append(String.valueOf(i));
        }
        //自动换行
        textArea.setLineWrap(true);

        //这里使用第一种方式:在创建JScrollPane,把组件作为参数传进去
        JScrollPane scrollPane = new JScrollPane(textArea);
        frame.setContentPane(scrollPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        TimeUnit.SECONDS.sleep(1000);
    }

6.5.TabbedPanel

标签面版 ,切换多个Tab
在这里插入图片描述
在这里插入图片描述

    @Test
    public void TabbedPanel() throws InterruptedException {
        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(null);

        JPanel panel1 = new JPanel();

        panel1.setBounds(50, 50, 300, 60);
        panel1.setBackground(Color.RED);
        panel1.setLayout(new FlowLayout());

        JButton b1 = new JButton("英雄1");
        JButton b2 = new JButton("英雄2");
        JButton b3 = new JButton("英雄3");

        panel1.add(b1);
        panel1.add(b2);
        panel1.add(b3);

        JPanel panel2 = new JPanel();
        JButton b4 = new JButton("英雄4");
        JButton b5 = new JButton("英雄5");
        JButton b6 = new JButton("英雄6");

        panel2.add(b4);
        panel2.add(b5);
        panel2.add(b6);

        panel2.setBackground(Color.BLUE);
        panel2.setBounds(10, 150, 300, 60);

        JTabbedPane tabbedPane = new JTabbedPane();
        tabbedPane.add(panel1);
        tabbedPane.add(panel2);

        // 设置tab的标题
        tabbedPane.setTitleAt(0, "红色tab");
        tabbedPane.setTitleAt(1, "蓝色tab");

        ImageIcon i = new ImageIcon("e:/project/j2se/j.png");
        tabbedPane.setIconAt(0, i);
        tabbedPane.setIconAt(1, i);

        frame.setContentPane(tabbedPane);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        TimeUnit.SECONDS.sleep(1000);
    }

6.6.CardLayerout

CardLayerout布局器 很像TabbedPanel ,在本例里面上面是一个下拉框,下面是一个CardLayerout 的JPanel

这个JPanel里有两个面板,可以通过CardLayerout方便的切换
在这里插入图片描述
在这里插入图片描述

 @Test
    public void CardLayerout() throws InterruptedException {
        JFrame frame = new JFrame("CardLayerout");

        JPanel comboBoxPane = new JPanel();
        String buttonPanel = "按钮面板";
        String inputPanel = "输入框面板";
        String[] comboBoxItems = {buttonPanel, inputPanel};
        JComboBox<String> comboBoxArr = new JComboBox<>(comboBoxItems);
        comboBoxPane.add(comboBoxArr);

        // 两个Panel充当卡片
        JPanel card1 = new JPanel();
        card1.add(new JButton("按钮 1"));
        card1.add(new JButton("按钮 2"));
        card1.add(new JButton("按钮 3"));

        JPanel card2 = new JPanel();
        card2.add(new JTextField("输入框", 20));

        JPanel cards; // a panel that uses CardLayout
        cards = new JPanel(new CardLayout());
        cards.add(card1, buttonPanel);
        cards.add(card2, inputPanel);

        frame.add(comboBoxPane, BorderLayout.NORTH);
        frame.add(cards, BorderLayout.CENTER);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(250, 150);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        comboBoxArr.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent evt) {
                CardLayout cl = (CardLayout) (cards.getLayout());
                cl.show(cards, (String) evt.getItem());
            }
        });

        TimeUnit.SECONDS.sleep(1000);
    }

6.7.练习-SplitPanel:点击左边panel按钮,切换右边panel图片

在这里插入图片描述

    @Test
    public void SplitPanelDemo() throws InterruptedException {

        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 300);
        frame.setLocation(200, 200);

        frame.setLayout(null);

        //左边面板
        JPanel pLeft = new JPanel();
        pLeft.setBounds(50, 50, 300, 60);
        pLeft.setBackground(Color.LIGHT_GRAY);
        pLeft.setLayout(new FlowLayout());

        JButton b1 = new JButton("盖伦");
        JButton b2 = new JButton("提莫");
        JButton b3 = new JButton("安妮");

        pLeft.add(b1);
        pLeft.add(b2);
        pLeft.add(b3);

        //右边面板
        JPanel pRight = new JPanel();
        JLabel lPic = new JLabel("");

        ImageIcon imageIcon = new ImageIcon("e:/data/gareen.jpg");
        lPic.setIcon(imageIcon);

        pRight.add(lPic);
        pRight.setBackground(Color.lightGray);
        pRight.setBounds(10, 150, 300, 60);

        // 创建一个水平JSplitPane,左边是p1,右边是p2
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, pLeft, pRight);
        // 设置分割条的位置
        splitPane.setDividerLocation(80);

        // 把sp当作ContentPane
        frame.setContentPane(splitPane);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        switchPic(b1, "gareen", lPic);
        switchPic(b2, "teemo", lPic);
        switchPic(b3, "annie", lPic);

        TimeUnit.SECONDS.sleep(1000);
    }

	//切换e:/data/{}/.jpg
    private static void switchPic(JButton b1, String fileName, JLabel lPic) {
        b1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                ImageIcon i = new ImageIcon("e:/data/" + fileName + ".jpg");
                lPic.setIcon(i);
            }
        });
    }

6.8.练习-TabbedPanel:按照eclipse的风格显示多个java文件

首先准备一个JavaFilePane专门用于显示文件内容的Panel

然后在TestGUI中遍历e:/project/j2se/jdbc 下的文件,并根据这些文件生成JavaFilePane 。接着把这些JavaFilePane 插入到TabbedPanel中即可
在这里插入图片描述

public class JavaFilePane extends JPanel{
	public JavaFilePane(File file){
		this.setLayout(new BorderLayout());
		String fileContent = getFileContent(file);
		JTextArea ta = new JTextArea();
		ta.setText(fileContent);
		this.add(ta);
	}
	
	private String getFileContent(File f){
		String fileContent = null;
        try (FileReader fr = new FileReader(f)) {
            char[] all = new char[(int) f.length()];
            fr.read(all);
            fileContent= new String(all);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return fileContent;
	}
	
	public static void main(String[] args) {
		JFrame f =new JFrame();
		
		f.setSize(400,300);
		
		f.setContentPane(new JavaFilePane(new File("E:/project/j2se/src/gui/JavaFilePane.java")));
		f.setVisible(true);
		
	}
}
public class TestGUI {
    public static void main(String[] args) {
   
        JFrame f = new JFrame("LoL");
        f.setSize(800, 600);
        f.setLocationRelativeTo(null);
   
        f.setLayout(null);
         
        File folder = new File("E:/project/j2se/src/jdbc");
        File[] fs=folder.listFiles();
        JTabbedPane tp = new JTabbedPane();
        ImageIcon icon = new ImageIcon("e:/project/j2se/j.png");
        for (int i = 0; i < fs.length; i++) {
            JavaFilePane jfp =new JavaFilePane(fs[i]);
            tp.add(jfp);
            tp.setIconAt(i,icon );
            tp.setTitleAt(i, shortName(fs[i].getName()));
        }
 
        f.setContentPane(tp);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
 
    private static String shortName(String name) {
        int length = 6;
        if(name.length()>length){
            return name.substring(0,length) + "...";
        }
        return name;
         
    }
}

七.组件综合练习

7.1.表单组件练习

在这里插入图片描述


public class LayoutDemo {
    public static void main(String[] args) {

        JFrame frame = new JFrame("LoL");
        frame.setSize(400, 400);
        frame.setLocation(200, 200);

        int gap = 10;
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(4, 3, gap, gap));

        JLabel lLocation = new JLabel("地名:");
        JTextField tfLocation = new JTextField("");

        JLabel lType = new JLabel("公司类型:");
        JTextField tfType = new JTextField("");

        JLabel lCompanyName = new JLabel("公司名称:");
        JTextField tfCompanyName = new JTextField("");

        JLabel lBossName = new JLabel("老板名称:");
        JTextField tfBossName = new JTextField("");

        JLabel lMoney = new JLabel("金额:");
        JTextField tfMoney = new JTextField("");

        JLabel lProduct = new JLabel("产品:");
        JTextField tfProduct = new JTextField("");

        JLabel lUnit = new JLabel("价格计量单位");
        JTextField tfUnit = new JTextField("");

        panel.add(lLocation);
        panel.add(tfLocation);
        panel.add(lType);
        panel.add(tfType);
        panel.add(lCompanyName);
        panel.add(tfCompanyName);
        panel.add(lBossName);
        panel.add(tfBossName);
        panel.add(lMoney);
        panel.add(tfMoney);
        panel.add(lProduct);
        panel.add(tfProduct);
        panel.add(lUnit);
        panel.add(tfUnit);

        frame.setLayout(null);
        panel.setBounds(gap, gap, 375, 120);

        JButton button = new JButton("生成");
        JTextArea textArea = new JTextArea();
        textArea.setLineWrap(true);

        button.setBounds(150, 120 + 30, 80, 30);
        textArea.setBounds(gap, 150 + 60, 375, 120);

        frame.add(panel);
        frame.add(button);
        frame.add(textArea);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        button.addActionListener(new ActionListener() {

            boolean checkedPass = true;

            @Override
            public void actionPerformed(ActionEvent e) {
                checkedPass = true;
                checkEmpty(tfLocation, "地址");
                checkEmpty(tfType, "公司类型");
                checkEmpty(tfCompanyName, "公司名称");
                checkEmpty(tfBossName, "老板姓名");
                checkNumber(tfMoney, "金额");
                checkEmpty(tfProduct, "产品");
                checkEmpty(tfUnit, "价格计量单位");

                String location = tfLocation.getText();
                String type = tfType.getText();
                String companyName = tfCompanyName.getText();
                String bossName = tfBossName.getText();
                String money = tfMoney.getText();
                String product = tfProduct.getText();
                String unit = tfUnit.getText();

                if (checkedPass) {
                    String model = "%s最大%s%s倒闭了,王八蛋老板%s吃喝嫖赌,欠下了%s个亿,"
                            + "带着他的小姨子跑了!我们没有办法,拿着%s抵工资!原价都是一%s多、两%s多、三%s多的%s,"
                            + "现在全部只卖二十块,统统只要二十块!%s王八蛋,你不是人!我们辛辛苦苦给你干了大半年,"
                            + "你不发工资,你还我血汗钱,还我血汗钱!";
                    String result = String.format(model, location, type, companyName, bossName, money, product, unit, unit, unit, product, bossName);
                    textArea.setText("");
                    textArea.append(result);
                }
            }

            private void checkNumber(JTextField textField, String msg) {
                if (!checkedPass) {
                    return;
                }
                String value = textField.getText();
                try {
                    Integer.parseInt(value);
                } catch (NumberFormatException e) {
                    JOptionPane.showMessageDialog(frame, msg + " 必须是整数");
                    textField.grabFocus();
                    checkedPass = false;
                }
            }

            private void checkEmpty(JTextField textField, String msg) {
                if (!checkedPass) {
                    return;
                }
                String value = textField.getText();
                if (0 == value.length()) {
                    JOptionPane.showMessageDialog(frame, msg + " 不能为空");
                    textField.grabFocus();
                    checkedPass = false;
                }
            }
        });
    }
}

7.2.登录校验(连接数据库)

在这里插入图片描述

  • 准备两个JTextFiled,一个用于输入账号,一个用于输入密码。

  • 再准备一个JButton,上面的文字是登陆

点击按钮之后,首先进行为空判断,如果都不为空,则把账号和密码,拿到数据库中进行比较(SQL语句判断账号密码是否正确),根据判断结果,使用JOptionPane进行提示。

public class LoginDemo {
    public static void main(String[] args) {

        JFrame f = new JFrame("LoL");
        f.setSize(400, 300);
        f.setLocation(200, 200);

        JPanel pNorth = new JPanel();
        pNorth.setLayout(new FlowLayout());
        JPanel pCenter = new JPanel();

        JLabel lName = new JLabel("账号:");
        JTextField tfName = new JTextField("");
        tfName.setText("");
        tfName.setPreferredSize(new Dimension(80, 30));

        JLabel lPassword = new JLabel("密码:");
        JPasswordField tfPassword = new JPasswordField("");
        tfPassword.setText("");
        tfPassword.setPreferredSize(new Dimension(80, 30));

        pNorth.add(lName);
        pNorth.add(tfName);
        pNorth.add(lPassword);
        pNorth.add(tfPassword);

        JButton b = new JButton("登陆");
        pCenter.add(b);

        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                String name = tfName.getText();
                String password = new String(tfPassword.getPassword());
                if (0 == name.length()) {
                    JOptionPane.showMessageDialog(f, "账号不能为空");
                    tfName.grabFocus();
                    return;
                }
                if (0 == password.length()) {
                    JOptionPane.showMessageDialog(f, "密码不能为空");
                    tfPassword.grabFocus();
                    return;
                }

                if (check(name, password)) {
                    JOptionPane.showMessageDialog(f, "登陆成功");
                } else {
                    JOptionPane.showMessageDialog(f, "密码错误");
                }

            }
        });

        f.setLayout(new BorderLayout());
        f.add(pNorth, BorderLayout.NORTH);
        f.add(pCenter, BorderLayout.CENTER);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.setVisible(true);
    }

    public static boolean check(String name, String password) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        boolean result = false;
        try (Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8", "root", "root");
             Statement s = c.createStatement();
        ) {
            String sql = "select * from user where name = '" + name + "' and password = '" + password + "'";

            // 执行查询语句,并把结果集返回给ResultSet
            ResultSet rs = s.executeQuery(sql);

            if (rs.next()) {
                result = true;
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return result;

    }
}

7.3.随机进度条

创建一个线程,每隔100毫秒,就把进度条的进度+1。从0%一直加到100%

  • 刚开始加的比较快,以每隔100毫秒的速度增加,随着进度的增加,越加越慢,让处女座的使用者,干着急
    在这里插入图片描述
 public static void main(String[] args) {

        JFrame frame = new JFrame("进度条");
        frame.setSize(450, 140);
        frame.setLocation(200, 200);
        frame.setLayout(new FlowLayout());

        JLabel label = new JLabel("文件复制进度:");
        JProgressBar progressBar = new JProgressBar();
        progressBar.setMaximum(100);
        //当前进度是0
        progressBar.setValue(0);
        progressBar.setStringPainted(true);

        frame.add(label);
        frame.add(progressBar);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        new Thread(()-> {
           while (progressBar.getValue() != progressBar.getMaximum()) {
               try {
                   if (progressBar.getValue() > 80) {
                       TimeUnit.MILLISECONDS.sleep(500);
                   }else {
                       TimeUnit.MILLISECONDS.sleep(100);
                   }
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               progressBar.setValue(progressBar.getValue() + 1);
           }
        }).start();

        frame.setVisible(true);
    }

7.4.显示文件夹复制进度条

在这里插入图片描述

public class CopyProgressBarDemoPlus {
    static long allFileSize = 0; // 所有需要复制的文件大小
    static long currentFileSizeCopied = 0;// 已复制的文件总大小


    /**
     * 遍递归历文件夹获取文件夹内容总大小-赋值给全局变量
     *
     * @param file
     */
    public static void calcLateAllFileSize(File file) {
        if (file.isFile()) {
            allFileSize += file.length();
            return;
        }
        if (file.isDirectory()) {
            File[] fs = file.listFiles();
            for (File frame : fs) {
                calcLateAllFileSize(frame);
            }
        }
    }


    /**
     * 遍递归历文件夹获取文件夹内容总大小(增强版)
     *
     * @param file
     */
    public static int calcLateAllFileSizePlus(File file) {
        int fileSizeSum = 0;

        if (file.isFile()) {
            fileSizeSum += file.length();
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File frame : files) {
                fileSizeSum += calcLateAllFileSizePlus(frame);
            }
        }

        return fileSizeSum;
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame("带进度条的文件夹复制");
        frame.setSize(450, 140);
        frame.setLocation(200, 200);
        frame.setLayout(new FlowLayout());

        // 文件地址
        JLabel lStr = new JLabel("源文件地址:");
        JTextField strTf = new JTextField("");
        strTf.setText("e:/data");
        strTf.setPreferredSize(new Dimension(100, 30));
        JLabel lDest = new JLabel("复制到:");
        JTextField destTf = new JTextField("");
        destTf.setText("e:/data2");
        destTf.setPreferredSize(new Dimension(100, 30));

        frame.add(lStr);
        frame.add(strTf);
        frame.add(lDest);
        frame.add(destTf);

        JButton bStartCopy = new JButton("开始复制");
        bStartCopy.setPreferredSize(new Dimension(100, 30));

        JLabel label = new JLabel("文件复制进度:");
        JProgressBar progressBar = new JProgressBar();
        progressBar.setMaximum(100);
        progressBar.setStringPainted(true);

        frame.add(bStartCopy);
        frame.add(label);
        frame.add(progressBar);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);

        // 计算需要复制的文件的总大小
        String srcPath = strTf.getText();
        File folder = new File(srcPath);
        allFileSize = calcLateAllFileSizePlus(folder);

        // 点击开始复制
        bStartCopy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                currentFileSizeCopied = 0;
                String srcPath = strTf.getText();
                String destPath = destTf.getText();
                new Thread(() -> copyFolder(srcPath, destPath)).start();
                bStartCopy.setEnabled(false);
            }
			
			//复制文件
            public void copyFile(String srcPath, String destPath) {

                File srcFile = new File(srcPath);
                File destFile = new File(destPath);

                // 缓存区,一次性读取1024字节
                byte[] buffer = new byte[1024];

                try (FileInputStream fis = new FileInputStream(srcFile);
                     FileOutputStream fos = new FileOutputStream(destFile);) {
                    while (true) {
                        // 实际读取的长度是 actuallyReaded,有可能小于1024
                        int actuallyReaded = fis.read(buffer);
                        // -1表示没有可读的内容了
                        if (-1 == actuallyReaded) {
                            break;
                        }
                        fos.write(buffer, 0, actuallyReaded);
                        fos.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

			//复制目录
            public void copyFolder(String srcPath, String destPath) {
                File srcFolder = new File(srcPath);
                File destFolder = new File(destPath);

                if (!srcFolder.exists()) {
                    return;
                }

                if (!srcFolder.isDirectory()) {
                    return;
                }

                if (destFolder.isFile()) {
                    return;
                }

                if (!destFolder.exists()) {
                    destFolder.mkdirs();
                }

                File[] files = srcFolder.listFiles();
                assert files != null;
                for (File srcFile : files) {

                    if (!(srcFile.isDirectory())) {
                        File newDestFile = new File(destFolder, srcFile.getName());
                        copyFile(srcFile.getAbsolutePath(), newDestFile.getAbsolutePath());
                        currentFileSizeCopied += srcFile.length();
                        System.out.println(srcFile.length());
                        double current = (double) currentFileSizeCopied / (double) allFileSize;
                        int progress = (int) (current * 100);
                        progressBar.setValue(progress);
                        if (progress == 100) {
                            JOptionPane.showMessageDialog(frame, "复制完毕");
                            bStartCopy.setEnabled(true);
                        }

                    }
                    if (srcFile.isDirectory()) {
                        File newDestFolder = new File(destFolder, srcFile.getName());
                        copyFolder(srcFile.getAbsolutePath(), newDestFolder.getAbsolutePath());
                    }

                }
            }
        });
    }
}

下半部分

【Java基础】swing-图形界面学习(下)

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墩墩分墩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值