JAVA—组件及事件处理

        对于使用JAVA的GUI程序的学习了解,学习常用的组件,容器和常用的一些API

1.java Swing 概述

 java Swing 包下提供了强大的用于开发桌面程序的API 理解面向对象编而简单学习一些内容


2.窗口

介绍:
窗口是基于JFrame类实例的一个底层容器,使用底层容器与操作系统进行信息交互

              (窗口默认添加到桌面 因此不允许添加到另一个容器中)

(1)常用方法

方法说明
JFrame() /JFrame(String s)创建一个无标题的窗口/创建标题为s的窗口
public void setVisible(boolean b)设置窗口是否可见(默认是不可见)
public void dispose()撤销当前的窗口,并释放当前的资源
public void setDefaultCloseOperation()窗口的关闭策略(程序对于×号的处理策略)
opreation说明
DO_ NOTHING_ON_CLOSE什么也不做
HIDE_ON_CLOSE隐藏当前的窗口
DISPOSE_ON_CLOSE隐藏当前的窗口,并释放占用资源
EXIT_ON_CLOSE结束窗口所在的应用程序

package GUI_study.JFrame_study;

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

public class Text01 {
    public static void main(String[] args) {
        JFrame widows = new JFrame("第一个窗口");
        Container con = widows.getContentPane();
        con.setBackground(Color.PINK);
        widows.setBounds(100,100,450,200); //窗口出现位置和长宽大小设置
        widows.setVisible(true);
        widows.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

(2)窗口菜单

选项说明
菜单条JMenubar的实例
菜单JMenu的实例
菜单项JMenuItem的实例
嵌入子菜单JMenuItem的子类实现
菜单上的图标Icon图标类

package GUI_study.JFrame_study;

import javax.swing.*; // 导入Swing包中的类
import java.awt.event.InputEvent; // 导入AWT事件处理相关的类
import java.awt.event.KeyEvent; // 导入键盘事件相关的类

public class WidowsMenu extends JFrame { // 定义WidowsMenu类,继承自JFrame

    JMenuBar menuBar = new JMenuBar(); // 创建菜单栏对象
    JMenu menu = new JMenu("菜单"), submenu = new JMenu("软件项目"); // 创建主菜单和子菜单对象
    JMenuItem Item1 = new JMenuItem("java话题", new ImageIcon("2.png")); // 创建带有图标的菜单项
    JMenuItem Item2 = new JMenuItem("动画话题", new ImageIcon("3,jpg")); // 注意这里文件名可能有误,应为"3.jpg"

    // 无参构造函数
    public WidowsMenu(){}

    // 带参构造函数,用于初始化窗口的标题、位置、大小和可见性
    public WidowsMenu(String s, int x, int y, int h, int w){
        Init(s); // 调用Init方法设置窗口的标题和菜单
        setLocation(x,y); // 设置窗口的位置
        setSize(w,h);
        setVisible(true); // 设置窗口为可见
        setDefaultCloseOperation(DISPOSE_ON_CLOSE); // 设置窗口关闭时的操作,这里是销毁窗口
    }

    // 私有方法,用于初始化窗口的标题和菜单
    private void Init(String s) {
        setTitle(s); // 设置窗口的标题
        // 为菜单项设置快捷键
        Item1.setAccelerator(KeyStroke.getKeyStroke('A')); // Item1的快捷键为A
        Item2.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK)); // Item2的快捷键为Ctrl+S
        menu.add(Item1); // 将Item1添加到主菜单
        menu.addSeparator(); // 在主菜单中添加分隔符
        menu.add(Item2); // 将Item2添加到主菜单
        menu.add(submenu); // 将子菜单添加到主菜单
        // 向子菜单中添加菜单项
        submenu.add(new JMenuItem("汽车销售系统", new ImageIcon("4.jpg")));
        submenu.add(new JMenuItem("农场信息系统", new ImageIcon("4.jpg"))); // 注意这里两个菜单项使用了相同的图标
        menuBar.add(menu); // 将主菜单添加到菜单栏
        setJMenuBar(menuBar); // 将菜单栏设置到窗口上
    }
}

菜单项放在菜单上,菜单放在菜单条上,菜单也可以当做菜单项添加另一个菜单上做子菜单 

package GUI_study.JFrame_study;

public class Text02 {
    public static void main(String[] args) {
        WidowsMenu widows = new WidowsMenu("带菜单的窗户",20,30,200,190);
    }
}

3.常用组件与布局

(1)常用组件

组件说明
文本框 JTextField类创建文本区 允许在文本区输入多行文本
按钮  JButton类创建按钮 允许单击按钮
标签 JLabel类创建标签 标签为用户提供信息
选择框 JCheckBox类创建选择框 提供两种状态 一种是选中 另一种是未选中,单击组件以切换形态
单选按钮 JRadioButton类

创建单项选择框 为用户提供单项选择

下拉按钮 JComboBox类创建下拉列表 提供单项选择 单击箭头以打开选择
密码框 JPasdswordField类允许输入单行密码 默认显示字符是“*”

[1] JTextField 类

JTextField 用于创建单行文本输入框,允许用户输入文本

参数说明

  • 无参数构造器:JTextField() 创建一个空的文本字段。
  • 带字符串参数的构造器:JTextField(String text) 创建一个包含指定文本的文本字段。
  • 带列数和列宽的构造器:JTextField(int columns) 创建一个具有指定列数的文本字段,列数大致决定了字段的宽度。

用法示例

JTextField textField = new JTextField(10); // 创建一个宽度大致为10列的文本字段

[2] JButton 类

JButton 用于创建按钮,用户可以通过单击按钮来触发某些动作

参数说明

  • 无参数构造器:JButton() 创建一个不带文本和图标的按钮。
  • 带文本参数的构造器:JButton(String text) 创建一个带有文本的按钮。
  • 带图标参数的构造器:JButton(Icon icon) 创建一个带有图标的按钮。

用法示例

JButton button = new JButton("点击我"); // 创建一个带有文本“点击我”的按钮

[3] JLabel 类

JLabel 用于创建标签,为用户提供信息,如文本、图标或两者的组合

参数说明

  • 无参数构造器:JLabel() 创建一个空标签。
  • 带文本参数的构造器:JLabel(String text) 创建一个带有文本的标签。
  • 带图标参数的构造器:JLabel(Icon icon) 创建一个带有图标的标签。
  • 带文本和图标参数的构造器:JLabel(String text, Icon icon, int horizontalAlignment) 创建一个带有文本、图标和文本水平对齐方式的标签。

用法示例

JLabel label = new JLabel("这是一个标签"); // 创建一个带有文本“这是一个标签”的标签

[4] JCheckBox 类

JCheckBox 用于创建复选框,允许用户从多个选项中选择一个或多个

参数说明

  • 无参数构造器:JCheckBox() 创建一个未选中的复选框,没有文本。
  • 带文本参数的构造器:JCheckBox(String text) 创建一个带有文本的复选框,默认未选中。
  • 带文本和布尔值的构造器:JCheckBox(String text, boolean b) 创建一个带有文本的复选框,并根据布尔值确定是否选中。

用法示例

JCheckBox checkBox = new JCheckBox("选项1", true); // 创建一个带有文本“选项1”且默认选中的复选框

[5] JRadioButton 类

JRadioButton 用于创建单选按钮,允许用户从一组互斥的选项中选择一个

参数说明

  • 无参数构造器:JRadioButton() 创建一个未选中的单选按钮,没有文本。
  • 带文本参数的构造器:JRadioButton(String text) 创建一个带有文本的单选按钮,默认未选中。
  • 带文本和布尔值的构造器:JRadioButton(String text, boolean b) 创建一个带有文本的单选按钮,并根据布尔值确定是否选中。

用法示例

JRadioButton radioButton = new JRadioButton("选项A", false); // 创建一个带有文本“选项A”且默认未选中的单选按钮

[6] JComboBox 类

JComboBox 用于创建下拉列表,允许用户从预定义的选项中选择一个

参数说明

  • 无参数构造器:JComboBox() 创建一个空的下拉列表。
  • 带向量参数的构造器:JComboBox(Vector<?> items) 创建一个包含指定元素向量的下拉列表。
  • 带字符串数组参数的构造器:JComboBox(String[] items) 创建一个包含指定字符串数组的下拉列表。

用法示例

String[] items = {"选项1", "选项2", "选项3"}; 
JComboBox<String> comboBox = new JComboBox<>(items); // 创建一个包含三个选项的下拉列表

[7] JPasswordField 类

JPasswordField 用于创建密码框,允许用户输入单行密码,但默认显示字符是“*”或圆点,以保护用户隐私。

参数说明

  • 无参数构造器:JPasswordField() 创建一个空的密码框。
  • 带列数的构造器:JPasswordField(int columns) 创建一个具有指定列数的密码框。

用法示例

JPasswordField passwordField = new JPasswordField(10); // 创建一个宽度大致为10列的密码框

实际上当前界面的内容都是紧随其后的(如下图)相关的标签是添加在创建内容前端的

package GUI_study.JFrame_study;

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

public class ComponentInWidow extends JFrame {
    JTextField text = new JTextField(10);//文本框
    JButton button = new JButton("确定"); //按钮
    JCheckBox checkBox1 = new JCheckBox("喜欢音乐");
    JCheckBox checkBox2 = new JCheckBox("喜欢旅游");
    JCheckBox checkBox3 = new JCheckBox("喜欢篮球"); //选择框
    JRadioButton radio1 = new JRadioButton("男"),radio2 = new JRadioButton("女"); //单选按钮
    ButtonGroup group = new ButtonGroup();//背景
    JComboBox comboBox;//下拉列表
    JTextArea area;//文本区

    public ComponentInWidow(){
        init();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void init() {
        setLayout(new FlowLayout());
        add(new JLabel("文本框"));
        add(text);
        add(new JLabel("按钮:"));
        add(button);
        add(new JLabel("选择框"));
        add(checkBox1);
        add(checkBox2);
        add(checkBox3);
        add(new JLabel("单选按钮"));
        group.add(radio1);
        group.add(radio2);
        add(radio1);
        add(radio2);
        add(new JLabel("下拉列表"));
        comboBox = new JComboBox();
        comboBox.addItem("音乐天地");
        comboBox.addItem("武术天地");
        comboBox.addItem("象棋乐园");
        add(comboBox);
        add(new JLabel("文本区:"));
        area = new JTextArea(6,12);
        add(new JScrollPane(area));
    }
}

(2)常用容器

JComponent是Container的子类,因此,JComponent子类创建的组件也是容器,但很少将JButton,JTextField,JCheckBox等组件当做容器使用。

JComponent专门提供了一些经常用来添加组件的容器:

[1] JPanel面板

经常使用JPanel先创建一个面板,在向这个面板添加组件,然后把这个面板添加到其他容器中。
JPanel面板的默认布局是FlowLayout布局


[2] JScrollPane

(滚动窗格)

滚动面板**只能添加一个组件**,可以把一个组件放到一个滚动窗格中,然后通过滚动条来观看该组件。
比如:
            JTextArea不自带滚动条,因此需要把文本区放到一个滚动窗格中:
       

JScrollPane scroll = new JScrollPane(new JTextArea());`
package GUI_study.JFrame_study;

import javax.swing.*;

public class Text04 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("面板窗口");
        frame.setBounds(100,100,310,260);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        JPanel panel = new JPanel(); //面板

        JTextArea area = new JTextArea(10,20);
        area.setLineWrap(true); // 设置自动换行

        JScrollPane scroll = new JScrollPane(area);
        panel.add(scroll);
        frame.add(panel);
    }
}

[3] JSplitPane(拆分窗格)

拆分窗格就是被分成“两部分”的容器。
拆分窗格有两种类型,一种是水平(HORIZONTAL_SPLIT),一种是垂直(VERTICAL_SPLIT)。
水平拆分窗格用一条拆分线(Divider)把窗口分为左右两部分,拆分线可以左右移动。
垂直拆分窗格用一条拆分线把窗口分为上下两部分,拆分线可以垂直移动。

JSplitPane的构造方法有:
①JSplitPane();
②JSplitPane(int a,Component b,Component c);
    (1)参数a取JSplitPane的静态常量HORIZONTAL_SPLIT或VERTICAL_SPLIT,以决定是水平拆分还是垂直拆分。
    (2)参数b,c决定放置的组件
③JSplitPane(int a,boolean b,Component c,Component d)
    (1)参数a,c,d同上a,b,c
    (2)参数b决定当拆分线移动时,组件是否连续变化(true是连续)。

package GUI_study.JFrame_study;

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

public class Text05 {
    public static void main(String[] args) {
        // 创建面板和按钮
        JPanel panel1 = new JPanel();
        JPanel panel2 = new JPanel();
        JButton button1 = new JButton("111");
        JButton button2 = new JButton("222");
        JButton button3 = new JButton("333");

        // 创建分割面板,并设置分割方向
        JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, panel1, panel2);

        // 设置面板布局
        panel1.setLayout(new BorderLayout()); //不设置布局时 默认是FlowLayout布局
        panel2.setLayout(new BorderLayout()); // 通常也设置panel2的布局

        // 添加按钮到面板
        panel1.add(button1, BorderLayout.CENTER);
        panel1.add(button2, BorderLayout.SOUTH);
        panel2.add(button3, BorderLayout.CENTER); // 为panel2的按钮设置布局位置

        // 设置分割面板的属性
        sp.setOneTouchExpandable(true); // 允许通过双击分隔线来展开或折叠面板
        sp.setContinuousLayout(true); // 当分隔线位置改变时,立即重绘
        sp.setDividerSize(5); // 设置分隔线的宽度
        sp.setDividerLocation(150); // 初始分隔线位置

        // 设置面板边框
        panel1.setBorder(BorderFactory.createLineBorder(Color.green));
        panel2.setBorder(BorderFactory.createLineBorder(Color.red));

        // 创建JFrame来显示分割面板
        JFrame frame = new JFrame("拆分窗口");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(sp);
        frame.setSize(600, 400);
        frame.setLocationRelativeTo(null); // 居中显示
        frame.setVisible(true);
    }
}

[4] JLayeredPane(分层窗格)

如果添加到容器中的组件经常需要处理重叠问题,就可以考虑将组件添加到分层窗格。
分层窗格分成5个层,分层窗格使用:add(JComponent com,int layer);

(1)参数com表示添加的组件
(2)参数layer表示指定组件com的层

参数layer可以取JLayeredPane类中的类常量:


①DEFAULT_LAYER

Z_order的Layer数值为0,以整数对象Integer(0)来表
示最底层,添加到该层的组件如果和其他层的组件发生了重叠,将被其他组件遮挡。
一般我们加入的组件若没有标记是第几层,默认值就 把组件放在此Default Layer中。

②PALETTE_LAYER
Z_order的Layer数值为100,以整数对象Integer(100)来表示
位于Default Layer之上,一般用于放置可移动的 工具栏(Floatable Toolbar)。

③MODAL_LAYER
Z_order的Layer数值为200,以整数对象Integer(200)来表示
位于PALETTE_LAYER之上,一般用于放置对话框 (Dialog Box)。

④POPUP_LAYER
Z_order的Layer数值为300,以整数对象Integer(300)来表示
,位于MODAL_LAYER之上,一般用于快捷菜单(Poup Menu)与工具栏提示(Tool Tips)中。

⑤DRAG_LAYER
Z_order的Layer数值为400,以整数对象Integer(400)来表示,位于POPUP_LAYER之上,一般用于拖曳组件使其在不同区域上。
是最上面的层,如果分层窗格中添加了许多组件,当用户用鼠标移动已组建时,可以把该组件放到DRAG_LAYER层,这样,用户在移动组件的过程中,改组件就不会被其他组件遮挡。添加到同一层上的组件,如果发生重叠,先添加的会遮挡后添加的组件。

分层窗格调用:
public void setLayer(Component c,int layer)
可以重新设置组件c所在的层。
public int getLayer(Component c)
可以获取组件所在的层数。

下面用代码来加深对JLayeredPane窗格的了解:

import java.awt.Color;
import java.awt.Point;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;

public class Window extends JFrame {


    private JButton[] button;
    private JLayeredPane layeredpane;


    public Window(){
        Integer[] layerConstants = {
                new Integer(-100),
                JLayeredPane.DEFAULT_LAYER,   //Z_order的Layer数值为0
                JLayeredPane.PALETTE_LAYER,   //Z_order的Layer数值为100
                JLayeredPane.MODAL_LAYER,     //Z_order的Layer数值为200
                JLayeredPane.POPUP_LAYER,     //Z_order的Layer数值为300
                JLayeredPane.DRAG_LAYER,      //Z_order的Layer数值为400
                new Integer(500)
        };

        Color[] colors = {Color.red,Color.blue,Color.magenta,Color.cyan,
                Color.yellow,Color.green,Color.pink
        };

        Point position  = new Point(20,20);
        button = new JButton[layerConstants.length];

        layeredpane = getLayeredPane();//获得窗口的Layered Pane
        for (int i = 0; i < button.length; i++) {
            button[i] = createButton("第" + (i + 1) + "层", colors[i], position);
            position.x = position.x + 20;
            position.y = position.y + 20;
            // 将组件(JLabel)放入Layered Pane中并给予深度(Z-order layer)的数值。
            layeredpane.add(button[i], layerConstants[i]);
        }

    }

    public JButton createButton(String content,Color color,Point position){
        JButton button = new JButton(content);
        button.setVerticalAlignment(JButton.TOP);
        button.setBackground(color);
//      button.setForeground(Color.black);
        button.setOpaque(true);//设置不透明度,默认为true,true时表示不透明
        button.setBounds(position.x,position.y,100,100);
        return button;
    }
}

从上面可以看出,除了5个常量,我们还可以自定义层。

我们可以调用JLayeredPane的moveToFront()将组件移到最前面,moveToBack()将组件移到最后面。

import java.awt.Color;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;

public class JLayeredPane3 extends JFrame {
    public JLayeredPane3() {

        setTitle("aaa");
        setVisible(true);
        setBounds(100,100,300,300);


        JButton button1,button2;
        button1 = new JButton("左边的");
        button1.setBackground(Color.blue);
        button1.setBounds(20, 20, 150, 150);
        button1.setVerticalAlignment(JLabel.TOP);

        button2 = new JButton("右边的");
        button2.setBackground(Color.red);
        button2.setBounds(50,50, 150, 150);
        button2.setVerticalAlignment(JLabel.TOP);


        JLayeredPane layer = getLayeredPane();

        layer.add(button1, new Integer(500));
        layer.add(button2, new Integer(500));

        layer.moveToFront(button2);
        layer.moveToBack(button1);

    }

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

(3)常用布局

[1] FlowLayout类

FlowLayout 按照组件的添加顺序从左到右排列它们,遇到容器的边界时则换行继续排列。这是最简单的布局管理器之一,适合那些不需要复杂布局的应用场景。

package GUI_study.JFrame_study;

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

public class Text06 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("常见布局-默认");
        frame.setBounds(100,100,310,260);
        frame.setBackground(Color.cyan);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());
        frame.add(new JButton("按钮一"));
        frame.add(new JButton("按钮二"));
    }
}

[2] BorderLay类

BorderLayout 将容器分成东、南、西、北、中五个区域。每个区域只能放置一个组件。如果尝试向某个区域添加多个组件,则只有最后一个组件会显示。这是创建窗口时非常常用的布局方式。

package GUI_study.JFrame_study;

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

public class Text07 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("常见布局-widows默认");
        frame.setBounds(100,100,310,270);
        frame.setVisible(true);
        frame.setBackground(Color.green);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLayout(new BorderLayout());
        frame.add(new JButton("东"),BorderLayout.EAST);
        frame.add(new JButton("南"),BorderLayout.SOUTH);
        frame.add(new JButton("西"),BorderLayout.WEST);
        frame.add(new JButton("北"),BorderLayout.NORTH);
        frame.add(new JButton("中"),BorderLayout.CENTER);

    }
}

[3] CardLayout类

CardLayout 允许容器一次只显示一个组件,但可以将多个组件(卡片)堆叠在一起,并允许通过编程方式或用户操作来切换显示的组件。这非常适合实现向导式界面或需要在不同视图之间切换的场景。

package GUI_study.JFrame_study;

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

public class Text08 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("常见布局-Card");
        frame.setBounds(100,100,310,270);
        frame.setVisible(true);
        frame.setBackground(Color.green);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        CardLayout cardLayout = new CardLayout();
        JPanel card = new JPanel(cardLayout);
        card.add("第一张",new JButton("1"));
        card.add("第二张",new JButton("2"));
        card.add("第三张",new JButton("3"));
        card.add("第四张",new JButton("4"));

        frame.add(card);
        //cardLayout.show(card,"第一张");
        cardLayout.next(card);
    }
}

[4] GridLayout类

GridLayout 将容器分割成多个大小相等的矩形区域,每个区域放置一个组件。这种方式适用于需要组件以表格形式排列的场景。

package GUI_study.JFrame_study;

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

public class Text09 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("常见布局-Grid");
        frame.setBounds(100,100,310,270);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setBackground(Color.green);
        JPanel panel = new JPanel();
        GridLayout grid = new GridLayout(4, 2);
        panel.setLayout(grid);
        panel.add(new JButton("1"));
        panel.add(new JButton("2"));
        panel.add(new JButton("3"));
        panel.add(new JButton("4"));
        panel.add(new JButton("5"));
        panel.add(new JButton("6"));
        panel.add(new JButton("7"));
        panel.add(new JButton("8"));
        panel.add(new JButton("9"));
        panel.add(new JButton("0"));
        frame.add(panel);
    }
}

对于自己需要的布局 四种常见布局可以嵌套布局 在新面板中使用新布局去设计界面


(4)选项卡窗格

常见布局的选项卡窗格是一种用户界面设计元素,它允许用户在不同的视图或功能之间切换,而无需离开当前页面。这种设计方式在多种软件和应用程序中广泛使用,如操作系统、办公软件、浏览器扩展、网页设计等。以下是对常见布局的选项卡窗格进行讲解:

[1] 选项卡窗格的基本概念

选项卡窗格,通常也被称为标签页或标签组,是一种将多个页面或视图组织在单个窗口中的方式。每个选项卡代表一个独立的页面或视图,用户可以通过点击不同的选项卡来快速切换查看或操作的内容。

[2] 选项卡窗格的优点

  1. 提高空间利用率:选项卡窗格可以在有限的屏幕空间内展示多个页面或视图,避免了频繁打开和关闭窗口的需要。
  2. 提升用户体验:用户可以在不离开当前页面的情况下快速访问其他相关页面或视图,提高了工作效率和操作的流畅性。
  3. 简化界面设计:通过选项卡窗格,可以将复杂的功能或信息分类组织,使界面更加简洁明了。

[3] 常见布局类型

  1. 水平布局
    • 特点:选项卡水平排列在窗口顶部或底部,用户可以通过点击或滚动来切换不同的选项卡。
    • 适用场景:适用于大多数桌面和网页应用程序,如浏览器、办公软件等。
  2. 垂直布局
    • 特点:选项卡垂直排列在窗口的一侧(通常是左侧或右侧),用户可以通过点击或滚动来切换不同的选项卡。
    • 适用场景:适用于需要展示大量选项卡或需要节省水平空间的应用程序,如文件管理器、侧边栏导航等。
  3. 可折叠布局
    • 特点:部分选项卡可以折叠起来,以节省空间或隐藏不常用的功能。用户可以通过点击折叠按钮来展开或收起选项卡。
    • 适用场景:适用于需要同时展示多个选项卡但又不想占用太多空间的应用程序,如一些复杂的配置界面或工具软件。
  4. 标签式布局
    • 特点:类似于浏览器的标签页,每个选项卡都可以独立关闭,用户可以在多个选项卡之间自由切换。
    • 适用场景:适用于需要同时处理多个任务或文档的应用程序,如文档编辑器、浏览器等。

package GUI_study.JFrame_study;

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

public class Text10 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("常见布局-Tabbed");
        frame.setBounds(100,100,310,270);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.ORANGE);

        JTabbedPane tabbed = new JTabbedPane();
        tabbed.add("第一页",new JButton("1"));
        tabbed.add("第二页",new JPanel().add(new JTextArea(1,1)));
        tabbed.add("第三页",new JButton("3"));
        frame.add(tabbed);
    }
}

4.处理事件

1. 事件和事件源

  • 事件(Event):是一个对象,它包含了事件发生的详细信息,如事件类型、事件发生的时间、位置等。
  • 事件源(Event Source):是产生事件的组件,比如按钮、文本框等。

2. 事件监听器

事件监听器是一个实现了特定监听器接口的类实例,该接口定义了处理事件所需的方法。当事件源上发生特定类型的事件时,该事件的监听器就会被调用,并执行相应的处理代码。

(1) ActionEvent 事件 

 文本框 按钮 菜单项 密码框 单选按钮都可以触发ActionEvent事件

package GUI_study.JFrame_study.Event;

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

public class ReaderListen implements ActionListener {
    private JTextArea area;
    private JTextField field;

    public void setArea(JTextArea area) {
        this.area = area;
    }

    public void setField(JTextField field) {
        this.field = field;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        //String rs = e.getActionCommand();
        String rs = field.getText();
        area.append(rs + "的长度为:" + rs.length());
    }
}
package GUI_study.JFrame_study.Event;

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

public class event_01 {
    public static void main(String[] args) {
     //学习事件响应
        JFrame frame = new JFrame("ActionEvent响应");
        frame.setBounds(100,100,310,270);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setBackground(Color.green);
        frame.setLayout(new FlowLayout());

        JTextArea text = new JTextArea(10,5);
        JTextField field = new JTextField(10);
        JButton button = new JButton("读取");
        ReaderListen lister = new ReaderListen();
        lister.setArea(text);
        lister.setField(field);

        button.addActionListener(lister);

        frame.add(field);
        frame.add(button);
        frame.add(new JScrollPane(text));
    }
}

(2) ItemEvent事件

选择框 下拉列表都可以触发ItemEvent事件 由选中到未选中或者由未选中到选中都会触发

ItemEvent 的基本属性

  • getItem():返回被选中或取消选中的项。
  • getItemSelectable():返回触发事件的 ItemSelectable 对象(通常是列表、下拉列表等)。
  • getStateChange():返回事件的状态变化,通常是一个布尔值,表示项是被选中(ItemEvent.SELECTED)还是被取消选中(ItemEvent.DESELECTED)
import javax.swing.*;  
import java.awt.event.ItemEvent;  
import java.awt.event.ItemListener;  
  
public class ItemEventExample extends JFrame {  
    public ItemEventExample() {  
        // 创建一个下拉列表  
        JComboBox<String> comboBox = new JComboBox<>();  
        comboBox.addItem("选项 1");  
        comboBox.addItem("选项 2");  
        comboBox.addItem("选项 3");  
  
        // 为下拉列表添加 ItemListener  
        comboBox.addItemListener(new ItemListener() {  
            @Override  
            public void itemStateChanged(ItemEvent e) {  
                if (e.getStateChange() == ItemEvent.SELECTED) {  
                    // 当项被选中时  
                    System.out.println("选中的项: " + e.getItem());  
                } else if (e.getStateChange() == ItemEvent.DESELECTED) {  
                    // 注意:JComboBox 不支持 DESELECTED 状态,因为只能选中一个项  
                    // 对于支持多选的组件(如 JList),这个状态会有效  
                    System.out.println("(JComboBox 不支持 DESELECTED 状态)");  
                }  
            }  
        });  
  
        // 添加下拉列表到窗口  
        this.add(comboBox);  
  
        // 设置窗口属性  
        this.setTitle("ItemEvent 示例");  
        this.setSize(300, 200);  
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        this.setVisible(true);  
    }  
  
    public static void main(String[] args) {  
        SwingUtilities.invokeLater(new Runnable() {  
            @Override  
            public void run() {  
                new ItemEventExample();  
            }  
        });  
    }  
}

(3) Document事件

文本区实现DocumentEvent接口的实例 文本区维护的文档

package GUI_study.JFrame_study.Event;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.util.Arrays;

public class MyFrame implements DocumentListener {
    JTextArea inputArea,showText;

    public void setInputArea(JTextArea inputArea) {
        this.inputArea = inputArea;
    }

    public void setShowText(JTextArea showText) {
        this.showText = showText;
    }

    @Override
    public void insertUpdate(DocumentEvent e) {
        changedUpdate(e);
    }

    @Override
    public void removeUpdate(DocumentEvent e) {
        changedUpdate(e);
    }

    @Override
    public void changedUpdate(DocumentEvent e) {
        String rs = inputArea.getText();
        String regex = "[\\s\\d\\p{Punct}]+";
        String words[] = rs.split(regex);
        Arrays.sort(words);
        showText.setText(null);
        for (String s : words) {
            showText.append(s+",");
        }
    }
}
package GUI_study.JFrame_study.Event;

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

public class event_02 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("DocumentEvent事件");
        frame.setLayout(new FlowLayout());
        frame.setVisible(true);
        frame.setBounds(100,100,350,350);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.PINK);

        JTextArea inputArea = new JTextArea(6,8);
        JTextArea showArea  = new JTextArea(6,8);
        frame.add(new JScrollPane(inputArea));
        frame.add(new JScrollPane(showArea));

        MyFrame listen = new MyFrame();
        listen.setInputArea(inputArea);
        listen.setShowText(showArea);
        (inputArea.getDocument()).addDocumentListener(listen);
    }
}

(4) MouseEvent事件

任何组件都可以触发鼠标事件,如鼠标进入组件 退出组件 在组件上单击,拖动鼠标等都可以触发鼠标事件 导致MouseEvent类自动创建一个事件对象

 举例用法

  • getX() 和 getY():返回鼠标事件发生时鼠标指针在组件上的 x 和 y 坐标。
  • getPoint():返回一个 Point 对象,表示鼠标事件发生时鼠标指针的坐标。
  • getID():返回事件的类型(如 MouseEvent.MOUSE_PRESSEDMouseEvent.MOUSE_RELEASED 等)。
  • getClickCount():返回鼠标连续点击的次数(对于双击事件很有用)。
  • getModifiers():返回触发事件时按下的修饰键(如 Shift、Ctrl、Alt 等)。
  • getSource():返回触发事件的源组件。

[1] MouseLister接口实现

package GUI_study.JFrame_study.Event;

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

public class event_03 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("鼠标响应事件1");
        frame.setBounds(100,100,310,254);
        frame.setLayout(new FlowLayout());
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.ORANGE);

        JTextField field = new JTextField(10);
        JTextArea area = new JTextArea();
        JButton button = new JButton("确认");
        Mouse_1 mouse = new Mouse_1();
        mouse.setArea(area);
        field.addMouseListener(mouse);
        button.addMouseListener(mouse);

        frame.add(field);
        frame.add(button);
        frame.add(area);

    }
}
package GUI_study.JFrame_study.Event;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class Mouse_1 implements MouseListener {
    JTextArea Area;

    public void setArea(JTextArea area) {
        this.Area = area;
    }

    @Override
    public void mouseClicked(MouseEvent e) { //负责处理在组件上单击鼠标键触发的鼠标事件
         if(e.getClickCount() >= 2){
             Area.setText("鼠标连击"+"("+e.getX()+","+e.getY()+")");
         }
    }

    @Override
    public void mousePressed(MouseEvent e) { //负责处理在组件上按下鼠标触发的鼠标事件
        Area.append("\n鼠标按下 位置:("+e.getX()+","+e.getY()+")");
    }

    @Override
    public void mouseReleased(MouseEvent e) { //负责处理在组件上释放鼠标键触发的鼠标事件
        Area.append("\n鼠标释放 位置:("+e.getX()+","+e.getY()+")");
    }

    @Override
    public void mouseEntered(MouseEvent e) { //负责处理鼠标进入组件触发的鼠标事件
        if(e.getSource() instanceof JButton){ Area.append("\n鼠标进入按钮 位置:("+e.getX()+","+e.getY()+")");}
        if(e.getSource() instanceof JTextField){ Area.append("\n鼠标进入文本框 位置:("+e.getX()+","+e.getY()+")");}
        if(e.getSource() instanceof JFrame){ Area.append("\n鼠标进入窗口 位置:("+e.getX()+","+e.getY()+")");}
    }

    @Override
    public void mouseExited(MouseEvent e) { //负责处理鼠标离开组价的鼠标事件
        Area.append("\n鼠标退出 位置:("+e.getX()+","+e.getY()+")");
    }
}

[2] MouseMotionListener接口实现 

该接口实现以下两种操作,在事件源上拖动鼠标和在事件源上移动鼠标(代码存在问题未改正)

package GUI_study.JFrame_study.Event;

import javax.swing.*;
import javax.xml.stream.events.Comment;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class Mouse_2 extends JFrame implements MouseListener,MouseMotionListener {
    JButton button;
    int x,y,a,b,x0,y0;
    Mouse_2(){
        button = new JButton("请使用鼠标拖动我");
        button.addMouseListener(this);
        button.addMouseMotionListener(this);
        setLayout(new FlowLayout());
        add(button,JLayeredPane.DEFAULT_LAYER);
    }
    @Override
    public void mouseDragged(MouseEvent e) {
        Component com = null;
        if(e.getSource()instanceof Component){
         com = (Component)e.getSource();
         a = com.getBounds().x;
         b = com.getBounds().y;
         x = e.getX();
         y = e.getY();
         a = a + x;
         b = b + y;
         com.setLocation(a-x0,b-y0);
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void mouseClicked(MouseEvent e) {

    }

    @Override
    public void mousePressed(MouseEvent e) {
    JComponent com = null;
    com = (JComponent)e.getSource();
    //setLayer(com,JLayeredPane.DEFAULT_LAYER);
    a = com.getBounds().x;
    b = com.getBounds().y;
    x0 = e.getX();
    y0 = e.getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    JComponent com = null;
    com = (JComponent)e.getSource();
    //setLayer(com,JLayeredPane.DEFAULT_LAYER);
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}

(5])焦点事件

组件触发焦点事件,组件从输入焦点到有输入焦点或者从有输入焦点到无输入焦点都会触发FocusEvent事件

触发时会调用实现接口的focusLost方法 也可以调用requestFocusInWindow方法获取输入焦点 


(6])键盘事件

在Java中,键盘事件主要由KeyEvent类表示。这个类封装了所有与键盘事件相关的信息,如按键的字符、按键的虚拟码(如VK_ENTER代表回车键)、按键的修饰符(如CTRL、SHIFT等)等。

键盘事件监听器通过实现KeyListener接口或使用KeyAdapterKeyAdapterKeyListener的一个空实现,用于简化事件监听器的编写)来定义。KeyListener接口包含三个方法:keyTyped(KeyEvent e)keyPressed(KeyEvent e)keyReleased(KeyEvent e),分别用于处理字符键的输入、按键被按下和按键被释放的事件。

案列介绍:输入序列号码,并且要在几个文本框中依次输入。每个文本框输入的字符数量是固定的,当在第一个文本框输入了恰好的字符个数后,输入光标会自动转移到下一个文本框。

package GUI_study.JFrame_study.Event;

import javax.swing.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Police implements KeyListener, FocusListener {
    @Override
    public void focusGained(FocusEvent e) {
        JTextField t= (JTextField) e.getSource();
        t.setText(null);
    }

    @Override
    public void focusLost(FocusEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        JTextField t= (JTextField) e.getSource();
        if(t.getCaretPosition() >= 6){t.transferFocus();}
    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}
package GUI_study.JFrame_study.Event;

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

public class win extends JFrame {
    JTextField [] text = new JTextField[3];
    Police police;
    JButton b;
    win(){
        setLayout(new FlowLayout());
        police = new Police();
        for (int i = 0; i < 3; i++) {
            text[i] = new JTextField(7);
            text[i].addKeyListener(police);
            text[i].addFocusListener(police);
            add(text[i]);
        }
        b = new JButton("确定");
        add(b);
        text[0].requestFocusInWindow();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
package GUI_study.JFrame_study.Event;

import javax.swing.*;

public class event_05 {
    public static void main(String[] args) {
    win in = new win();
    in.setBounds(12,12,300,310);
    in.setVisible(true);
    in.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

}

(7) 匿名类做监视器

匿名的外嵌类成员在匿名类中仍然有效。发生事件监视器比较容易处理事件源所在外嵌类的成员。使用事件源所在的类的实例作为监视器,使事件处理比较方便。可以方便的操作事件源所在内的其他成员。

(8)总结

[1] 授权模式

事件处理基于授权模式,既事件源调用方法将某个对象注册成为自己的监视器

[2] 接口回调

接口回调是一种将函数作为参数传递给另一个函数的技术,或者更一般地说,是一种允许上层代码将代码块传递给底层代码并由底层代码在适当时候执行的技术。

Java实现

  • 在Java中,接口回调通常通过定义接口并在需要回调的地方将其作为参数传递来实现。
  • Java 8引入的函数式接口(Functional Interface)和Lambda表达式极大地简化了接口回调的使用,如RunnableCallableComparator等。
  • 在异步编程、事件处理、GUI编程等场景中,接口回调被广泛使用。

[3] 方法绑定

方法绑定在Java中通常指的是将方法引用(或Lambda表达式)与特定对象或类关联起来,以便在需要时调用。这包括静态方法绑定、实例方法绑定和构造方法引用

Java实现

  • Java 8引入的方法引用(Method References)和Lambda表达式是方法绑定的主要实现方式。
  • 方法引用允许你更简洁地引用已存在的方法或构造器。例如,System.out::println是一个方法引用,它引用了System.out类的println方法。
  • Lambda表达式提供了一种简洁的方式来表示匿名方法(即没有名称的方法),它可以被用作参数传递给需要函数式接口的方法。

[4] 保持松耦合

松耦合是软件设计中的一个重要原则,它要求系统中的各个组件之间尽可能少地相互依赖,以便于修改、扩展和重用。


5.MVC结构

MVC(Model-View-Controller)是一种软件设计模式,用于将应用程序分为三个主要逻辑组件:模型(Model)、视图(View)和控制器(Controller)。这种分离有助于管理复杂的应用程序,因为它们各自处理不同的方面,同时保持低耦合和高内聚。

模型:用于存储数据的对象

视图:为模型提供数据显示的对象

控制器:处理用户的交互操作 对操作做出响应 模型和视图间进行必要的交互 

案例:使用MVC结构简易设计一个三角形面积计算器

 

package GUI_study.JFrame_study.Event.MVC;

public class Triangle {
    double sizeA,sizeB,sizeC,area;
    boolean isTriange;

    public void setSizeB(double b) {
        sizeB = b;
        isTriange = sizeA + sizeB > sizeC && sizeC + sizeB > sizeA && sizeA + sizeC > sizeB;
    }

    public void setSizeC(double c) {
        sizeC = c;
        isTriange = sizeA + sizeB > sizeC && sizeC + sizeB > sizeA && sizeA + sizeC > sizeB;
    }

    public void setSizeA(double a) {
        sizeA = a;
        isTriange = sizeA + sizeB > sizeC && sizeC + sizeB > sizeA && sizeA + sizeC > sizeB;
    }

    public String getArea() {
        if(isTriange){
            double p = (sizeA+sizeB+sizeC)/2.0;
            area = Math.sqrt(p*(p - sizeA)*(p - sizeB)*(p - sizeC));
            return String.valueOf(area);
        }
        else{
            return "无法计算面积";
        }
    }
}
package GUI_study.JFrame_study.Event.MVC;

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

public class Widow_T extends JFrame implements ActionListener {
    Triangle triangle; // 数据对象
    JTextField textA,textB,textC; // 数据对象的视图
    JTextArea showArea; // 数据对象的视图
    JButton button; // 控制器对象
    Widow_T(){
        triangle = new Triangle();
        textA = new JTextField(5);
        textB = new JTextField(5);
        textC = new JTextField(5);
        showArea = new JTextArea();
        button = new JButton("计算面积");
        JPanel panel = new JPanel();
        panel.add(new JLabel("边A"));
        panel.add(textA);
        panel.add(new JLabel("边B"));
        panel.add(textB);
        panel.add(new JLabel("边C"));
        panel.add(textC);
        panel.add(button);
        button.addActionListener(this);
        add(panel, BorderLayout.NORTH);
        add(new JScrollPane(showArea),BorderLayout.CENTER);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        double a =  Double.parseDouble(textA.getText().trim());
        double b =  Double.parseDouble(textB.getText().trim());
        double c =  Double.parseDouble(textC.getText().trim());
        triangle.setSizeA(a);
        triangle.setSizeB(b);
        triangle.setSizeC(c);
        String area = triangle.getArea();
        showArea.append("三角形"+a+"+"+b+"+"+"+"+c+"的面积为:" + area + "\n");

    }
}
package GUI_study.JFrame_study.Event.MVC;

import javax.swing.*;

public class Text {
    public static void main(String[] args) {
        Widow_T wt = new Widow_T();
        wt.setVisible(true);
        wt.setTitle("MVC结构");
        wt.setBounds(12,12,300,320);
        wt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

6.对话框

在Java中,对话框(Dialog)是一种特殊的窗口,用于在应用程序的主窗口(Frame或JFrame)之外向用户显示信息或请求用户输入。对话框是模态(Modal)或非模态(Non-Modal)的,这取决于它们如何影响用户与应用程序其他部分的交互。

  • 模态对话框(Modal Dialog):当模态对话框打开时,用户必须先与对话框进行交互(如点击按钮或关闭对话框),才能返回到应用程序的其他部分。这种对话框通常用于需要用户立即响应的情况。
  • 非模态对话框(Non-Modal Dialog):非模态对话框允许用户在对话框打开时继续与应用程序的其他部分进行交互。这种对话框通常用于提供辅助信息或允许用户在应用程序的其他部分工作时执行后台任务。

(1)消息对话框

在重要操作前进行提醒 使用静态方法showMessageDialog创建 包含参数如下:

  1. Component parentComponent:对话框的父组件。这通常是一个 JFrame 或 JDialog 的实例,用于确定对话框的显示位置(例如,对话框可能会居中显示在其父组件上)。如果传递 null,则对话框将居中显示在屏幕上。

  2. Object message:要显示的消息。这可以是一个字符串、图标或任何可以转换为字符串的对象。

  3. String title:对话框的标题。

  4. int messageType:一个指定消息类型的整数,它决定了对话框中显示的图标。JOptionPane 类提供了几个常量来表示不同的消息类型,如 INFORMATION_MESSAGEWARNING_MESSAGEERROR_MESSAGE 和 PLAIN_MESSAGE(没有图标)。

package GUI_study.JFrame_study.Event.JDialog;

public class Text1 {
    public static void main(String[] args) {
        WindowsMess mess = new WindowsMess();
        mess.setTitle("带消息对话框的窗口");
        mess.setBounds(12,12,300,310);
    }
}
package GUI_study.JFrame_study.Event.JDialog;

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

public class WindowsMess extends JFrame implements ActionListener {
    JTextField inputEnglish;
    JTextArea showArea;
    String regex = "[a-zZ-Z]+";
    WindowsMess(){
        inputEnglish = new JTextField(22);
        inputEnglish.addActionListener(this);
        showArea = new JTextArea();
        add(inputEnglish, BorderLayout.NORTH);
        add(showArea,BorderLayout.CENTER);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == inputEnglish){
            String rs = inputEnglish.getText();
            if(rs.matches(regex)){
                showArea.append(rs+" ");
            }
            else{
                JOptionPane.showMessageDialog(this,"您输入了非法字符","消息对话框",JOptionPane.WARNING_MESSAGE);
                inputEnglish.setText(null);
            }
        }
    }
}

(2)输入对话框

含有供用户输入文本的文本框 含有确认和取消按钮 是有模式对话框 使用方法showInputDialog创建 包含参数如下:

  1. Component parentComponent:对话框的父组件。这通常是一个 JFrame 或 JDialog 的实例,用于确定对话框的显示位置。如果传递 null,则对话框将居中显示在屏幕上。

  2. Object message:要显示的消息。这可以是一个字符串、图标或任何可以转换为字符串的对象。它通常用于向用户说明需要输入什么。

  3. String title:对话框的标题。

package GUI_study.JFrame_study.Event.JDialog;

public class Text2 {
    public static void main(String[] args) {
        WindowsInput input = new WindowsInput();
        input.setTitle("带输入对话框的窗口");
        input.setBounds(12,12,300,310);
    }
}
package GUI_study.JFrame_study.Event.JDialog;

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

public class WindowsInput extends JFrame implements ActionListener {
    JTextArea showArea;
    JButton openButton;
    WindowsInput(){
        openButton = new JButton("弹出输入对话框");
        showArea = new JTextArea();
        add(openButton,BorderLayout.NORTH);
        add(showArea,BorderLayout.CENTER);
        openButton.addActionListener(this);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        String str = JOptionPane.showInputDialog(this,"输入内容 使用空格分隔","输入对话框",JOptionPane.PLAIN_MESSAGE);
        if(str != null){
            Scanner sc = new Scanner(System.in);
            double sum = 0;
            int k= 0;
            while(sc.hasNext()){
                double number = sc.nextDouble();
                if(k == 0){showArea.append(""+number);}
                else{showArea.append("+"+number);}
                sum += number;
                k++;
            }
            showArea.append("="+sum+"\n");
        }
    }
}

(3)确认对话框

确认对话框是有模式对话框 使用showConfirmDialog 创建 用法如下:

参数

showConfirmDialog 方法有多个重载版本,但最常用的一个接受以下参数:

  1. Component parentComponent:对话框的父组件。这通常是一个 JFrame 或 JDialog 的实例,用于确定对话框的显示位置。如果传递 null,则对话框将居中显示在屏幕上。

  2. Object message:要显示的消息。这可以是一个字符串、图标或任何可以转换为字符串的对象。它通常用于向用户说明需要做出什么决定。

  3. String title:对话框的标题。

  4. int optionType:一个指定对话框中按钮组合的整数。JOptionPane 类提供了几个常量来表示不同的按钮组合,如 YES_NO_OPTIONYES_NO_CANCEL_OPTION 和 OK_CANCEL_OPTION

  5. int messageType(可选):一个指定消息类型的整数,它决定了对话框中显示的图标。虽然这不是 showConfirmDialog 所有重载版本的必需参数,但它是某些重载版本中的一部分。JOptionPane 类提供了几个常量来表示不同的消息类型,如 INFORMATION_MESSAGEWARNING_MESSAGEERROR_MESSAGE 和 PLAIN_MESSAGE

返回值

  • 返回一个整数,表示用户点击的按钮。JOptionPane 类定义了几个常量来表示不同的按钮,如 YES_OPTIONNO_OPTIONCANCEL_OPTIONOK_OPTION 和 CLOSED_OPTION(如果用户关闭了对话框而不是点击了任何按钮)。

 

package GUI_study.JFrame_study.Event.JDialog;

public class Text3 {
    public static void main(String[] args) {
        WindowsEnter enter = new WindowsEnter();
        enter.setTitle("带确认对话框的窗口");
        enter.setBounds(12,12,310,350);
    }
}
package GUI_study.JFrame_study.Event.JDialog;

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

public class WindowsEnter extends JFrame implements ActionListener {
    JTextField field;
    JTextArea area;
    WindowsEnter(){
        field = new JTextField(10);
        area = new JTextArea();
        field.addActionListener(this);
        add(field, BorderLayout.NORTH);
        add(area,BorderLayout.CENTER);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        String str = field.getText();
        int n = JOptionPane.showConfirmDialog(this,"确认是否正确","确认对话框",JOptionPane.YES_NO_OPTION);
        if(n == JOptionPane.YES_OPTION){area.append("\n"+str);}
        else if(n == JOptionPane.NO_OPTION){field.setText(null);}
    }
}

(4)颜色对话框

颜色对话框是有模式对话框 使用showDialog 创建 (返回类型为Color)

package GUI_study.JFrame_study.Event.JDialog;

public class Text4 {
    public static void main(String[] args) {
    WindowsColor color = new WindowsColor();
    color.setTitle("带颜色对话框的窗口");
    color.setBounds(12,12,310,325);
    }
}
package GUI_study.JFrame_study.Event.JDialog;

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

public class WindowsColor extends JFrame implements ActionListener {
    JButton button;
    WindowsColor(){
        button = new JButton("打开颜色对话框");
        button.addActionListener(this);
        setLayout(new FlowLayout());
        add(button);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
    Color newColor = JColorChooser.showDialog(this,"调色板",getContentPane().getBackground());
    if(newColor != null){getContentPane().setBackground(newColor);}
    }
}

(5)文件对话框

文件对话框是一个从文件中选择文件的界面 用JFlieChooser()创建有模式的对话框

package GUI_study.JFrame_study.Event.JDialog;

public class Text5 {
    public static void main(String[] args) {
        WindowsReader reader =new WindowsReader();
        reader.setTitle("文件对话框");
    }
}
package GUI_study.JFrame_study.Event.JDialog;

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

public class WindowsReader extends JFrame implements ActionListener {
    JFileChooser fileChooser;
    JMenuBar menuBar;
    JMenu menu;
    JMenuItem itemSave,itemOpen;
    JTextArea text;
    BufferedReader in;
    FileReader fileReader;
    BufferedWriter out;
    FileWriter fileWriter;
    WindowsReader(){
        init();
        setSize(300,400);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    private void init() {
        text = new JTextArea(10,10);
        text.setFont(new Font("楷体_gb2312",Font.PLAIN,28));
        add(new JScrollPane(text),BorderLayout.CENTER);
        menuBar = new JMenuBar();
        menu = new JMenu("文件");
        itemSave = new JMenuItem("保存文件");
        itemOpen = new JMenuItem("打开文件");
        itemSave.addActionListener(this);
        itemOpen.addActionListener(this);
        menu.add(itemSave);
        menu.add(itemOpen);
        menuBar.add(menu);
        setJMenuBar(menuBar);
        fileChooser = new JFileChooser();
    }
    @Override
    public void actionPerformed(ActionEvent e) {

            if (e.getSource() == itemSave) {
                int state = fileChooser.showSaveDialog(this);
                try {
                    if (state == JFileChooser.APPROVE_OPTION) {
                        File dir = fileChooser.getCurrentDirectory();
                        String name = fileChooser.getSelectedFile().getName();
                        File file = new File(dir, name);
                        fileWriter = new FileWriter(file);
                        out = new BufferedWriter(fileWriter);
                        out.write(text.getText());
                        out.close();
                        fileWriter.close();
                    }
                }
        catch(IOException exp){ }
        }
        else if(e.getSource() == itemSave){
            int state = fileChooser.showSaveDialog(this);
            if(state == JFileChooser.APPROVE_OPTION){
                text.setText(null);
                try{
                    File dir = fileChooser.getCurrentDirectory();
                    String name = fileChooser.getSelectedFile().getName();
                    File file = new File(dir,name);
                    fileReader = new FileReader(file);

                } catch (FileNotFoundException ex) {
                    throw new RuntimeException(ex);
                }
            }
            }
    }
}

(6)自定义对话框 

创建对话框与创建窗口类似,通过建立JDIalog的子类来建立一个对话框类的一个实例 默认布局是BorderLayout 可以添加组件进行交互 由于对话框默认是添加到显示器屏幕上 所以不可以再添加到容器中 常用的构造方法有两个 区别于有无标题


7.GUI程序

使用jar把文件进行压缩成JAR文件 把涉及到的类全部压缩为JAR文件然后使用解释器去执行该压缩文件

 学习时间 2024.9.17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值