GUI图形化演示

概述

Swing组件通常被称为"轻量级组件",他完全由Java编写,不依赖操作系统语言,他的类继承关系如下:

Java.lang.Object ->Java.awt.Component->Java.awt.Container->Javax.swing.JCompoment

JCompoent是swing组件存放的位置,

常用组件如下:

组件名称 说明
JFrame 框架
JDialog 对话框
JOptionPane 对话框
JButton 按钮
JCheckBox 复选框
JComboBox 下拉框
JLabel 标签
JRadioButton 单选按钮
JList 显示一组条目的组件
JTextField 文本框
JPasswordField 密码框
JTextArea 文本区域

继承关系图:

JFrame:

JFrame是一个容器,他是各个组件的载体,在开发过程,我们通过继承java.swing.JFrame来创建给窗体。一般使用BorderLayout布局方式

一.新建JFrame对象:

  • new JFrame()创建没有标题的。//也可以直接传一个字符串当作标题
  • Frame(String s)创建标题为s的窗口,

二.设置JFrame的大小:

  • public void setSize(int width, int height) 设置窗口的大小。
  • public void setLocation(int x, int y) 设置窗口的位置,默认位置是 (0, 0) 。
  • public void setBounds(int a, int b, int width, int height) 设置窗口的初始位置是 (a, b) ,窗口的宽是 width ,高是 height 。
  • public void setVisible(boolean b) 设置窗口是否可见,窗口默认是不可见的。
  • public void setResizable(boolean b) 设置窗口是否可调整大小,默认可调整大小。
  • public void dispose() 撤销当前窗口,并释放当前窗口所使用的资源。
  • public void setExtendedState(int state) 设置窗口的扩展状态,其中参数 state 取 JFrame 类中的下列类常量:
    • MAXIMIZED_HORIZ (水平方向最大化)
    • MAXIMIZED_VERT (垂直方向最大化)
    • MAXIMIZED_BOTH (水平、垂直方向都最大化)

三.设定JFrame的关闭方式

  • public void setDefaultCloseOperation(int operation) 该方法用来设置单击窗体右上角的关闭图标后,程序会做出怎样的处理,其中的参数 operation 取 JFrame 类中的下列 int 型 static 常量,程序根据参数 operation 取值做出不同的处理:
    • DO_NOTHING_ON_CLOSE (什么也不做)
    • HIDE_ON_CLOSE (隐藏当前窗口)
    • DISPOSE_ON_CLOSE (隐藏当前窗口,并释放窗体占有的其他资源)
    • EXIT_ON_CLOSE (结束窗口所在的应用程序)

下面来写一下:

java 复制代码
package pdsu__zjh;


import javax.swing.*;

import javax.swing.JFrame;
public class Textt {
	
	public static void main(String []args) {
		
			JFrame jf=new JFrame();
		    jf.setSize(400,250);//设置长宽
		    jf.setLocation(400,250);//设置位置
		    
		    jf.setVisible(true);//设置是否显示!!!!
		    jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭方式
		    
  }	
}

结果:

布局方式:

setLayout 方法概述

在 Java 的 JFrame 中,setLayout 方法用于设置容器的布局管理器。布局管理器决定了容器中组件的排列方式。JFrame 默认使用 BorderLayout,但可以通过 setLayout 方法更改为其他布局管理器。

好处:布局方式可以让组件的位置随着窗口的大小而改变。

常用布局管理器

  1. BorderLayout(边界布局)

    • 将容器分为五个区域:NORTHSOUTHEASTWESTCENTER

    • 示例代码:

      java 复制代码
      JFrame frame = new JFrame("BorderLayout Example");        
      // 设置JFrame的布局管理器为BorderLayout,用于管理组件的布局        
      frame.setLayout(new BorderLayout());        
      // 创建一个按钮,按钮上的文本为"North",并将其添加到JFrame的NORTH区域        
      frame.add(new JButton("North"), BorderLayout.NORTH);        
      // 创建一个按钮,按钮上的文本为"South",并将其添加到JFrame的SOUTH区域        
      frame.add(new JButton("South"), BorderLayout.SOUTH);        
      // 创建一个按钮,按钮上的文本为"East",并将其添加到JFrame的EAST区域        
      frame.add(new JButton("East"), BorderLayout.EAST);        
      // 创建一个按钮,按钮上的文本为"West",并将其添加到JFrame的WEST区域        
      frame.add(new JButton("West"), BorderLayout.WEST);        
      // 创建一个按钮,按钮上的文本为"Center",并将其添加到JFrame的CENTER区域        
      frame.add(new JButton("Center"), BorderLayout.CENTER);        
      // 设置JFrame的大小为宽度300像素,高度200像素
      frame.setSize(300, 200);        
      // 设置JFrame的默认关闭操作,当关闭窗口时退出应用程序       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
      // 设置JFrame可见,即显示窗口         
      frame.setVisible(true);
  2. FlowLayout(流式布局)

    • (组件按照添加顺序从左到右排列,当一行排满时自动换行。

    • 示例代码:

      java 复制代码
      JFrame frame = new JFrame("FlowLayout Example");
      frame.setLayout(new FlowLayout());
      frame.add(new JButton("Button 1"));
      frame.add(new JButton("Button 2"));
      frame.add(new JButton("Button 3"));
      frame.setSize(300, 200);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
  3. GridLayout(网格布局)

    • 将容器划分为指定行数和列数的网格,组件按顺序填充网格。

    • 示例代码:

      java 复制代码
      JFrame frame = new JFrame("GridLayout Example");
      frame.setLayout(new GridLayout(2, 3)); // 2行3列
      frame.add(new JButton("Button 1"));
      frame.add(new JButton("Button 2"));
      frame.add(new JButton("Button 3"));
      frame.add(new JButton("Button 4"));
      frame.add(new JButton("Button 5"));
      frame.setSize(300, 200);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);
  4. GridBagLayout

    • 提供更灵活的布局方式,允许组件跨越多个行和列。

    • 示例代码:

      java 复制代码
      JFrame frame = new JFrame("GridBagLayout Example");
      frame.setLayout(new GridBagLayout());
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = 0;
      gbc.gridy = 0;
      frame.add(new JButton("Button 1"), gbc);
      gbc.gridx = 1;
      gbc.gridy = 0;
      frame.add(new JButton("Button 2"), gbc);
      gbc.gridx = 0;
      gbc.gridy = 1;
      gbc.gridwidth = 2;
      frame.add(new JButton("Button 3"), gbc);
      frame.setSize(300, 200);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setVisible(true);

自定义布局

如果默认的布局管理器不满足需求,可以通过实现 LayoutManager 接口来自定义布局。自定义布局需要实现 LayoutManager 接口中的方法,如 addLayoutComponentremoveLayoutComponentlayoutContainer 等。

注意事项

  • 在设置布局管理器后,添加的组件将按照新的布局管理器进行排列。
  • 如果不需要布局管理器,可以将布局管理器设置为 null,此时需要手动设置组件的位置和大小。
java 复制代码
JFrame frame = new JFrame("Null Layout Example");
frame.setLayout(null);
JButton button = new JButton("Button");
button.setBounds(50, 50, 100, 30); // 手动设置位置和大小
frame.add(button);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

通过 setLayout 方法,可以灵活地控制 JFrame 中组件的排列方式,满足不同的界面设计需求。

面板与布局的嵌套:

我们都知道一个窗口只有一种布局方式,如果想让你的窗口既有流水布局,又有网格布局等,要怎么操作呢?这个时候就要用到面板了,面板是个很小的容器,也是组件可以添加在窗口中。

简单例子:

java 复制代码
package pdsu__zjh;

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

public class Textt {
    public static void main(String[] args) {
        // 创建一个JFrame窗口
        JFrame frame = new JFrame();
        // 设置窗口的位置和大小(x坐标500, y坐标500, 宽度500, 高度400)
        frame.setBounds(500, 500, 500, 400);
        // 使窗口可见(注意:应在所有组件添加完成后再调用此方法)
        frame.setVisible(true);

        // 创建GridLayout布局管理器(默认2行1列)
        GridLayout gridLayout = new GridLayout();
        // 设置布局的行数为2(列数会根据添加的组件数量自动计算)
        gridLayout.setRows(2);
        // 将JFrame的布局管理器设置为GridLayout
        frame.setLayout(gridLayout);

        // 创建第一个面板(使用AWT的Panel类)
        Panel panel1 = new Panel();
        // 设置面板背景颜色为粉色
        panel1.setBackground(Color.PINK);

        // 创建第二个面板(使用AWT的Panel类)
        Panel panel2 = new Panel();
        // 设置面板背景颜色为青色
        panel2.setBackground(Color.CYAN);

        // 将面板1添加到JFrame中(GridLayout的第一行)
        frame.add(panel1);
        // 将面板2添加到JFrame中(GridLayout的第二行)
        frame.add(panel2);
    }
}

监听器:

监听器的概念

在Java中,监听器(Listener)是一种设计模式,用于监听特定事件的发生。当事件发生时,监听器会触发相应的处理逻辑。监听器通常用于GUI编程、网络编程等场景,用于处理用户交互、数据变化等事件。

监听器的类型

Java中常见的监听器类型包括:

  • ActionListener:用于处理按钮点击等动作事件。
  • MouseListener:用于处理鼠标点击、移动等事件。
  • KeyListener:用于处理键盘按键事件。
  • WindowListener:用于处理窗口事件,如窗口打开、关闭等。
  • ItemListener:用于处理复选框、下拉列表等组件的状态变化事件。

监听器的使用步骤

  1. 实现监听器接口:创建一个类并实现相应的监听器接口,重写接口中的方法。
  2. 注册监听器:将监听器对象注册到需要监听的组件上。
  3. 处理事件:在监听器的方法中编写事件处理逻辑。
  4. 还有一种是使用内部类,将1和2步骤写在一起,用匿名内部类的格式

示例代码

以下是一个使用ActionListener的简单示例,监听按钮点击事件:

java 复制代码
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonClickListener {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Click Example");
        JButton button = new JButton("Click Me");

        // 创建监听器对象
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button clicked!");
            }
        };

        // 注册监听器
        button.addActionListener(listener);

        frame.add(button);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

自定义监听器

除了使用Java提供的标准监听器接口,还可以自定义监听器接口和实现类。以下是一个自定义监听器的示例:

java 复制代码
// 自定义监听器接口,定义了事件处理方法
interface MyEventListener {
    // 定义一个方法,用于处理事件,参数message表示事件相关的信息
    void onEvent(String message);
}

// 事件源类,负责触发事件并通知监听器
class EventSource {
    // 声明一个监听器对象,用于存储注册的监听器
    private MyEventListener listener;

    // 设置监听器的方法,将传入的监听器对象赋值给成员变量listener
    public void setEventListener(MyEventListener listener) {
        this.listener = listener;
    }

    // 触发事件的方法,当调用此方法时会通知已注册的监听器处理事件
    public void triggerEvent(String message) {
        // 检查是否有已注册的监听器
        if (listener != null) {
            // 如果有监听器,则调用监听器的onEvent方法,并传递事件信息message
            listener.onEvent(message);
        }
    }
}

// 监听器实现类,实现了MyEventListener接口,处理具体的事件逻辑
class MyEventListenerImpl implements MyEventListener {
    // 实现接口中的onEvent方法,用于处理接收到的事件
    @Override
    public void onEvent(String message) {
        // 简单地打印出接收到的事件信息
        System.out.println("Event received: " + message);
    }
}

public class CustomListenerExample {
    public static void main(String[] args) {
        // 创建一个事件源对象
        EventSource source = new EventSource();
        // 为事件源设置一个监听器,这里创建了一个监听器实现类的实例并传入
        source.setEventListener(new MyEventListenerImpl());

        // 触发事件,调用事件源的triggerEvent方法并传递事件信息
        source.triggerEvent("Hello, Custom Listener!");
    }
}

使用自定义监听器

java 复制代码
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

// 自定义监听器接口
interface MyButtonListener {
    void onButtonClicked(String message);
}

// 自定义JFrame类,包含按钮和监听器注册机制
class MyFrame extends JFrame {
    private JButton button;
    private MyButtonListener listener;

    public MyFrame(String title) {
        super(title);
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());

        // 创建按钮
        button = new JButton("点击我");
        add(button);

        // 为按钮添加内置的ActionListener
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // 当按钮被点击时,触发自定义监听器的事件
                if (listener != null) {
                    listener.onButtonClicked("按钮被点击了!");
                }
            }
        });
    }

    // 注册自定义监听器的方法
    public void setMyButtonListener(MyButtonListener listener) {
        this.listener = listener;
    }
}

// 主类:演示如何使用自定义监听器
public class CustomListenerInFrameExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            // 创建自定义窗口
            MyFrame frame = new MyFrame("自定义监听器示例");
            
            // 注册自定义监听器
            frame.setMyButtonListener(new MyButtonListener() {
                @Override
                public void onButtonClicked(String message) {
                    // 实现自定义事件处理逻辑
                    JOptionPane.showMessageDialog(
                        frame, 
                        message, 
                        "事件通知", 
                        JOptionPane.INFORMATION_MESSAGE
                    );
                }
            });
            
            frame.setVisible(true);
        });
    }
}

总结

Java中的监听器机制为事件驱动编程提供了强大的支持。通过实现和注册监听器,可以有效地处理各种用户交互和系统事件。无论是使用标准监听器接口还是自定义监听器,都可以根据具体需求灵活地设计和实现事件处理逻辑。

滚动面板和列表

面板:

1. Panel(AWT 组件)

  • AWT 组件 :属于java.awt包,是 AWT 库中最基本的容器组件。
  • 重量级 :每个Panel对应一个原生窗口句柄,依赖底层操作系统绘制。
  • 简单功能:主要用于组织和布局其他组件,不支持复杂 UI 特性。
  • 有限定制:外观由操作系统决定,难以实现自定义样式(如透明效果)。
  • 事件模型:使用 AWT 事件模型,处理方式较繁琐。

核心方法:

  • add(Component comp):添加子组件。
  • setLayout(LayoutManager mgr):设置布局管理器。
  • setBackground(Color c):设置背景颜色。

示例代码:

java

复制代码
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class PanelExample {
    public static void main(String[] args) {
        Frame frame = new Frame("AWT Panel示例");
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        // 创建Panel并设置布局
        Panel panel = new Panel();
        panel.setLayout(new FlowLayout());
        
        // 添加组件到Panel
        panel.add(new Button("按钮1"));
        panel.add(new Button("按钮2"));
        
        frame.add(panel);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

2. JPanel(Swing 组件)

特点:

  • Swing 组件 :属于javax.swing包,是 Swing 库中常用的轻量级容器。
  • 轻量级:不依赖原生窗口句柄,由 Java 代码绘制,跨平台一致性好。
  • 丰富功能:支持双缓冲、透明效果、边框装饰等现代 UI 特性。
  • 高度可定制:可自定义外观、添加事件监听器、使用 Swing 提供的各种 UI 组件。
  • 事件模型:与 Swing 事件模型集成,处理更简洁(如使用匿名内部类)。

核心方法:

  • add(Component comp):添加子组件。
  • setLayout(LayoutManager mgr):设置布局管理器。
  • setOpaque(boolean isOpaque):设置是否透明。
  • setBorder(Border border):设置边框样式。

示例代码:

java

java 复制代码
package pdsu__zjh;

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

public class Textt {
    public static void main(String[] args) {
    	JFrame frame=new JFrame("Hallow!,World");
    	frame.setBounds(500, 500, 500, 500);
    	frame.setAlwaysOnTop(true);//将窗口置顶
    	ScrollPane scollPane=new ScrollPane();
    	frame.add(scollPane);
    	GridLayout gridLayout=new GridLayout();
    	gridLayout.setRows(20);
    	Panel panel=new Panel();
    	panel.setLayout(gridLayout);
    	for (int i = 0; i < 20; i++) {
			panel.add(new Button("按钮"+i));
		}
    	scollPane.add(panel);
    	
    	
    	frame.setVisible(true);
    }
}

主要区别对比

特性 JPanel (Swing) Panel (AWT)
包路径 javax.swing java.awt
组件类型 轻量级(Java 纯代码实现) 重量级(依赖原生窗口系统)
透明效果 支持setOpaque(false) 不支持,始终完全不透明
边框装饰 支持各种边框(BorderFactory 无内置边框支持
双缓冲 默认启用,减少闪烁 不支持,可能有绘制闪烁问题
事件处理 更简洁(如匿名内部类) 较繁琐(需实现接口)
布局管理器 完全支持所有布局管理器 支持基本布局,但对复杂布局支持有限
推荐场景 现代 Java GUI 应用(JFrame、JDialog) 传统 AWT 应用或简单工具

选择建议

  • 优先使用 JPanel

    • 如果你的应用是基于 Swing 的。
    • 需要透明效果、自定义边框或其他现代 UI 特性。
    • 需要更好的跨平台一致性。
  • 使用 Panel

    • 在纯 AWT 应用中,或需要与旧代码兼容时。
    • 对 UI 要求简单,不需要复杂的视觉效果。
  • 注意事项

    • 避免在同一个界面中混用 AWT 和 Swing 组件,可能导致绘制问题和性能下降。
    • 使用 Swing 组件时,确保在事件调度线程(EDT)中创建和操作 UI,避免线程安全问题。

常见应用场景

  • JPanel

    • 创建复杂的表单界面(如注册页面)。
    • 实现分区域布局(如左侧菜单 + 右侧内容)。
    • 作为自定义组件的基类(如游戏面板)。
  • Panel

    • 简单的工具窗口(如计算器)。
    • 与 AWT 绘图 API 结合使用(如Graphics)。
    • 旧 Java 应用的维护和扩展。

2 滚动面板

Swing组件不能使用**setDefaultCloseOperation()方法,如果想要关闭就要设置事件**

1. JScrollPane(Swing 组件)

特点:

  • Swing 组件 :属于 Swing 包(javax.swing),支持现代 UI 特性(如双缓冲、透明效果)。
  • 可定制性强:支持水平和垂直滚动条的精细控制,可自定义滚动条样式、显示策略。
  • 事件驱动:与 Swing 事件模型集成,适合复杂交互场景。
  • 线程安全:建议在事件调度线程(EDT)中操作,避免 UI 更新冲突。
  • 轻量级:不依赖底层窗口系统,跨平台一致性好。

核心方法:

  • setViewportView(Component view):设置需要滚动显示的组件。
  • setHorizontalScrollBarPolicy(int policy):设置水平滚动条的显示策略。
  • setVerticalScrollBarPolicy(int policy):设置垂直滚动条的显示策略。
  • getHorizontalScrollBar()/getVerticalScrollBar():获取滚动条实例进行定制。

示例代码(修正后的版本):

java

java 复制代码
import javax.swing.*;
import java.awt.*;

public class JScrollPaneExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("JScrollPane示例");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            // 创建内容面板
            JPanel contentPanel = new JPanel();
            contentPanel.setLayout(new GridLayout(20, 1)); // 20行1列
            for (int i = 0; i < 20; i++) {
                contentPanel.add(new JButton("按钮" + i));
            }
            
            // 创建JScrollPane并设置内容面板
            JScrollPane scrollPane = new JScrollPane(contentPanel);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            
            frame.add(scrollPane);
            frame.setSize(400, 300);
            frame.setVisible(true);
        });
    }
}

2. ScrollPane(AWT 组件)

特点:

  • AWT 组件 :属于 AWT 包(java.awt),依赖底层窗口系统绘制。
  • 简单直接:功能相对基础,适合简单滚动需求。
  • 重量级:每个组件对应一个原生窗口句柄,可能影响性能。
  • 有限定制:滚动条样式和行为由操作系统决定,定制性差。
  • 兼容性:与 AWT 事件模型集成,在纯 AWT 应用中使用更方便。

核心方法:

  • add(Component comp):添加需要滚动显示的组件(自动处理滚动)。
  • setScrollbarDisplayPolicy(int policy):设置滚动条显示策略。
  • getHAdjustable()/getVAdjustable():获取滚动条的调整器(用于手动控制)。

示例代码:

java

java 复制代码
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ScrollPaneExample {
    public static void main(String[] args) {
        Frame frame = new Frame("ScrollPane示例");
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        // 创建AWT ScrollPane
        ScrollPane scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
        
        // 创建内容面板
        Panel contentPanel = new Panel();
        contentPanel.setLayout(new GridLayout(20, 1));
        for (int i = 0; i < 20; i++) {
            contentPanel.add(new Button("按钮" + i)); // AWT Button
        }
        
        // 添加内容到ScrollPane
        scrollPane.add(contentPanel);
        frame.add(scrollPane);
        
        frame.setSize(400, 300);
        frame.setVisible(true);
    }
}

3.主要区别对比

特性 JScrollPane (Swing) ScrollPane (AWT)
包路径 javax.swing java.awt
组件类型 轻量级(Java 纯代码实现) 重量级(依赖原生窗口系统)
添加内容方式 setViewportView(component) add(component)
滚动条定制 高度可定制(颜色、样式、策略) 由操作系统决定,定制性差
事件处理 与 Swing 事件模型集成 与 AWT 事件模型集成
线程安全性 需要在 EDT 中操作 无需特殊处理(但可能有线程问题)
布局管理器支持 支持复杂布局(如嵌套面板) 简单布局,依赖容器默认布局
推荐场景 现代 Java GUI 应用(JFrame、JDialog) 传统 AWT 应用或简单工具

4. 选择建议

  • 优先使用 JScrollPane:如果你的应用是基于 Swing 的,需要更好的 UI 定制性和跨平台一致性。
  • 使用 ScrollPane:在纯 AWT 应用中,或需要与旧代码兼容时。
  • 注意事项:避免在同一个界面中混用 AWT 和 Swing 组件,可能导致绘制问题和性能下降。

列表组件:

我只介绍一下AWT中的列表组件:

在 Java AWT(Abstract Window Toolkit)中,列表组件主要提供两种:List(下拉列表框)和Choice(单选下拉菜单)。它们都是用户界面中常用的选择组件,但功能和使用场景略有不同。

1. List 组件

java.awt.List 是一个可滚动的多行选择列表,支持单选或多选。

特点:

  • 显示多个选项,可通过滚动条浏览。
  • 支持单选(默认)或多选(通过setMultipleMode(true)启用)。
  • 用户可通过鼠标或键盘选择一个或多个项目。

核心方法:

  • add(String item):添加选项。
  • select(int index):选择指定索引的选项。
  • getSelectedIndex():获取选中项的索引(单选模式)。
  • getSelectedIndexes():获取所有选中项的索引(多选模式)。
  • setMultipleMode(boolean b):启用 / 禁用多选模式。

示例代码:

java

java 复制代码
import java.awt.*;
import java.awt.event.*;

public class ListExample {
    public static void main(String[] args) {
        Frame frame = new Frame("AWT List 示例");
        frame.setSize(300, 200);
        
        // 创建List组件(默认单选)
        List list = new List(5); // 显示5行
        list.add("选项1");
        list.add("选项2");
        list.add("选项3");
        list.add("选项4");
        list.add("选项5");
        
        // 添加按钮获取选中项
        Button button = new Button("获取选中项");
        button.addActionListener(e -> {
            int selectedIndex = list.getSelectedIndex();
            if (selectedIndex >= 0) {
                System.out.println("选中项: " + list.getItem(selectedIndex));
            }
        });
        
        frame.add(list, BorderLayout.CENTER);
        frame.add(button, BorderLayout.SOUTH);
        
        // 添加窗口关闭事件
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        frame.setVisible(true);
    }
}

2. Choice 组件

java.awt.Choice 是一个单行的下拉选择菜单,用户点击后展开选项列表。

特点:

  • 只显示当前选中项,点击后弹出选项列表。
  • 仅支持单选。
  • 占用空间小,适合选项较多的场景。

核心方法:

  • add(String item):添加选项。
  • select(int index):选择指定索引的选项。
  • select(String item):选择指定文本的选项。
  • getSelectedIndex():获取选中项的索引。
  • getSelectedItem():获取选中项的文本。

示例代码:

java

java 复制代码
import java.awt.*;
import java.awt.event.*;

public class ChoiceExample {
    public static void main(String[] args) {
        Frame frame = new Frame("AWT Choice 示例");
        frame.setSize(300, 200);
        
        // 创建Choice组件
        Choice choice = new Choice();
        choice.add("红色");
        choice.add("绿色");
        choice.add("蓝色");
        choice.add("黄色");
        
        // 添加按钮获取选中项
        Button button = new Button("获取颜色");
        button.addActionListener(e -> {
            String selectedColor = choice.getSelectedItem();
            System.out.println("选中的颜色: " + selectedColor);
        });
        
        frame.add(choice, BorderLayout.NORTH);
        frame.add(button, BorderLayout.SOUTH);
        
        // 添加窗口关闭事件
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        
        frame.setVisible(true);
    }
}

3. List vs Choice 对比

特性 List Choice
显示方式 多行列表,可滚动 单行下拉菜单,点击展开
选择模式 支持单选和多选 仅支持单选
默认行为 直接显示所有选项(部分可见) 仅显示当前选中项
适用场景 选项较少,需快速浏览和选择 选项较多,节省空间
常用方法 getSelectedIndexes()(多选) getSelectedItem()(单选)

4. 事件处理

两者都可通过ItemListener监听选择变化:

java

复制代码
list.addItemListener(e -> {
    if (e.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("选中: " + list.getSelectedItem());
    }
});

choice.addItemListener(e -> {
    if (e.getStateChange() == ItemEvent.SELECTED) {
        System.out.println("选中: " + choice.getSelectedItem());
    }
});

5. 注意事项

  • AWT 组件的线程安全:虽然 AWT 不是严格线程安全的,但简单应用通常无需特殊处理。对于复杂场景,建议在事件调度线程中操作 UI。
  • Swing 替代方案 :如果需要更现代的 UI 组件,可使用 Swing 的JListJComboBox,它们提供了更丰富的功能和更好的外观控制。

如果你需要更多自定义选项(如自定义渲染器或复杂布局),建议转向 Swing 或 JavaFX。

常见组件:

组件就是AWT为我们设置好的一些可以直接使用的界元素:按钮,文本框,标签,我们可以用这些帮我们写好的组件来快速拼凑出功能强大的程序

标签组件:

标签组件的基本概念

在Java中,标签组件通常用于在图形用户界面(GUI)中显示文本图像 。标签组件是不可编辑的,主要用于提供信息或描述其他组件。Java提供了多种标签组件,最常用的是JLabel类,它属于javax.swing包。

创建标签组件

使用JLabel类可以轻松创建标签组件。可以通过构造函数传递文本或图像来初始化标签。以下是一个简单的示例,展示如何创建一个文本标签:

java 复制代码
import javax.swing.JFrame;
import javax.swing.JLabel;

public class LabelExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Label Example");
        JLabel label = new JLabel("Hello, World!");
        
        frame.add(label);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

设置标签的文本和图像

JLabel类提供了多种方法来设置标签的文本和图像。可以使用setText()方法设置文本,使用setIcon()方法设置图像。以下示例展示了如何同时设置文本和图像:

java 复制代码
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class LabelWithImage {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Label with Image");
        JLabel label = new JLabel("Java Logo");
        
        ImageIcon icon = new ImageIcon("java_logo.png");
        label.setIcon(icon);
        
        frame.add(label);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

标签的对齐方式

JLabel类允许设置文本和图像的对齐方式。可以使用setHorizontalAlignment()setVerticalAlignment()方法来控制标签内容的对齐方式。以下示例展示了如何设置标签的水平和垂直对齐方式:

java 复制代码
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;

public class LabelAlignment {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Label Alignment");
        JLabel label = new JLabel("Centered Text", SwingConstants.CENTER);
        
        label.setVerticalAlignment(SwingConstants.CENTER);
        
        frame.add(label);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

标签的字体和颜色

可以通过setFont()方法设置标签的字体,通过setForeground()方法设置文本颜色。以下示例展示了如何设置标签的字体和颜色:

java 复制代码
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class LabelFontAndColor {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Label Font and Color");
        JLabel label = new JLabel("Styled Text");
        
        Font font = new Font("Serif", Font.BOLD, 18);
        label.setFont(font);
        label.setForeground(Color.BLUE);
        
        frame.add(label);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

标签的事件处理

虽然标签组件通常不处理用户输入,但可以通过添加事件监听器来实现一些交互功能。例如,可以为标签添加鼠标点击事件监听器:

java 复制代码
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class LabelClickEvent {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Label Click Event");
        JLabel label = new JLabel("Click Me!");
        
        label.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                label.setText("Clicked!");
            }
        });
        
        frame.add(label);
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

通过以上方法,可以在Java应用程序中灵活使用标签组件,实现各种界面设计需求。

小结:

在这里我调试了许久,总结的有,如果要添加标签,最好先添加在JPanel页面中,然后再将JPanel添加进入JFrame中,并且他们的布局方式也不一样,JFrame用的是BorderLayout,JPanel用的是FlowLayout布局方式,详细可以看之前写的内容。

按钮组件

在Java中,按钮组件通常通过JButton类来实现,它是javax.swing包的一部分。JButton用于创建可点击的按钮,用户可以通过点击按钮来触发特定的事件。

创建按钮

要创建一个按钮,可以使用JButton类的构造函数。最简单的形式是创建一个带有文本标签的按钮。

java 复制代码
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;

public class ButtonExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        JButton button = new JButton("Click Me");
        frame.add(button);

        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

添加事件监听器

按钮通常需要与用户交互,因此需要为按钮添加事件监听器。可以使用ActionListener接口来处理按钮点击事件。

java 复制代码
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        JButton button = new JButton("Click Me");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Button clicked!");
            }
        });
        frame.add(button);

        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

设置按钮属性

JButton类提供了多种方法来设置按钮的属性,例如设置按钮的文本、图标、工具提示等。

java 复制代码
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import java.awt.FlowLayout;

public class ButtonExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        JButton button = new JButton("Click Me");
        button.setToolTipText("This is a button");
        button.setIcon(new ImageIcon("icon.png"));
        frame.add(button);

        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

按钮布局

按钮可以放置在容器的不同位置,通常使用布局管理器来控制按钮的位置和大小。常见的布局管理器包括FlowLayoutBorderLayoutGridLayout等。

java 复制代码
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;

public class ButtonExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());

        JButton button1 = new JButton("North");
        JButton button2 = new JButton("South");
        JButton button3 = new JButton("East");
        JButton button4 = new JButton("West");
        JButton button5 = new JButton("Center");

        frame.add(button1, BorderLayout.NORTH);
        frame.add(button2, BorderLayout.SOUTH);
        frame.add(button3, BorderLayout.EAST);
        frame.add(button4, BorderLayout.WEST);
        frame.add(button5, BorderLayout.CENTER);

        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

通过以上方法,可以在Java应用程序中创建和使用按钮组件,并根据需要设置其属性和事件处理逻辑。

菜单栏和弹出菜单

菜单:顾名思义就是包含各种基本操作的组件,程序中我们经常使用下拉菜单:

菜单的层级结构:

java 复制代码
MenuBar (菜单栏)
├─ Menu (文件)
│  ├─ MenuItem (新建)
│  ├─ MenuItem (打开)
│  └─ MenuItem (保存)
├─ Menu (编辑)
│  ├─ MenuItem (复制)
│  ├─ MenuItem (粘贴)
│  └─ Menu (查找)
│     └─ MenuItem (查找下一个)
└─ Menu (帮助)
   └─ MenuItem (关于)

下面是AWT中的菜单介绍:

在Java中,AWT(Abstract Window Toolkit)提供了创建图形用户界面(GUI)的基本工具。AWT中的菜单、弹出菜单和菜单栏是构建用户界面的重要组件。以下是对这些组件的详细介绍。

菜单栏(MenuBar)

菜单栏是窗口顶部的水平条,通常包含多个菜单。在AWT中,MenuBar类用于创建菜单栏。菜单栏可以添加到FrameDialog中。

java 复制代码
import java.awt.*;

public class MenuBarExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("MenuBar Example");
        MenuBar menuBar = new MenuBar();

        Menu fileMenu = new Menu("File");
        Menu editMenu = new Menu("Edit");

        menuBar.add(fileMenu);
        menuBar.add(editMenu);

        frame.setMenuBar(menuBar);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

菜单(Menu)

菜单是菜单栏中的一个下拉列表,包含多个菜单项。Menu类用于创建菜单。菜单可以包含其他菜单(子菜单)或菜单项(MenuItem)。

java 复制代码
import java.awt.*;

public class MenuExample {
    public static void main(String[] args) {
       JFrame frame = new JFrame("MenuBar Example");
        MenuBar menuBar = new MenuBar();
      
        Menu fileMenu = new Menu("File");
        Menu editMenu = new Menu("Edit");

        menuBar.add(fileMenu);
        menuBar.add(editMenu);

        frame.setMenuBar(menuBar);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

弹出菜单(PopupMenu)

弹出菜单是用户右键点击时显示的菜单。PopupMenu类用于创建弹出菜单。弹出菜单可以添加到任何组件中,通常与鼠标事件结合使用。

java 复制代码
import java.awt.*;
import java.awt.event.*;

public class PopupMenuExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("PopupMenu Example");
        PopupMenu popupMenu = new PopupMenu();

        MenuItem cutItem = new MenuItem("Cut");
        MenuItem copyItem = new MenuItem("Copy");
        MenuItem pasteItem = new MenuItem("Paste");

        popupMenu.add(cutItem);
        popupMenu.add(copyItem);
        popupMenu.add(pasteItem);

        frame.add(popupMenu);
        frame.addMouseListener(new MouseAdapter() {
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON3) {
                    popupMenu.show(frame, e.getX(), e.getY());
                }
            }
        });

        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

菜单项(MenuItem)

菜单项是菜单中的单个选项,用户可以选择执行特定操作。MenuItem类用于创建菜单项。菜单项可以添加到菜单或弹出菜单中。

java 复制代码
import java.awt.*;
import java.awt.event.*;

public class MenuItemExample {
    public static void main(String[] args) {
        Frame frame = new Frame("MenuItem Example");
        MenuBar menuBar = new MenuBar();

        Menu fileMenu = new Menu("File");
        MenuItem openItem = new MenuItem("Open");
        MenuItem saveItem = new MenuItem("Save");

        openItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Open item clicked");
            }
        });

        saveItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.out.println("Save item clicked");
            }
        });

        fileMenu.add(openItem);
        fileMenu.add(saveItem);
        menuBar.add(fileMenu);
        frame.setMenuBar(menuBar);
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
}

通过以上示例,可以了解如何在Java中使用AWT创建菜单栏、菜单、弹出菜单和菜单项。这些组件是构建用户界面的基础,能够帮助用户与应用程序进行交互。

弹出对话框:

弹出窗口:

JDialog:

继承自java.awt.Dialog类,他是从一个窗体弹出来的另一个窗体,他们JFrame类似,需要调用getContentPane将窗体转换为容器,然后在容器中设置窗体的内容。

JDialog:可以当作JFrame使用,但是必须从属于JFrame

构造函数

  • JDialog();
  • JDialog(Frame f); //指定父窗口
  • JDialog(Frame f,String title); //指定父窗口+标题
  • JDialog关闭窗口的时候不能用**DISPOSE_ON_CLOS,**所以关闭大窗口会连着小的一起关闭,因为JDialog从属于JFrame.

下面演示:

java 复制代码
package pdsu__zjh;
import javax.swing.*;
import javax.swing.JFrame;
public class Textt {
	
	public static void main(String []args) {
		
			JFrame jf=new JFrame();
			jf.setBounds(400,250,600,550);//设置位置,长,宽;
		    
		    jf.setVisible(true);//设置是否显示
		    jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//关闭方式
		    
		    JDialog jDialog=new JDialog();
		    jDialog.setBounds(400,250,400,250);
		    jDialog.setVisible(true);
		    jDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		    
  }	
}

效果演示:

弹出对话框

使用JOptionPane创建弹出对话框

Java中可以通过JOptionPane类来创建各种类型的弹出对话框。JOptionPane提供了多种静态方法来显示消息对话框、确认对话框、输入对话框等。

java 复制代码
import javax.swing.JOptionPane;

public class DialogExample {
    public static void main(String[] args) {
        // 显示消息对话框
        JOptionPane.showMessageDialog(null, "这是一个消息对话框", "消息", JOptionPane.INFORMATION_MESSAGE);

        // 显示确认对话框
        int response = JOptionPane.showConfirmDialog(null, "你确定要继续吗?", "确认", JOptionPane.YES_NO_OPTION);
        if (response == JOptionPane.YES_OPTION) {
            System.out.println("用户选择了是");
        } else {
            System.out.println("用户选择了否");
        }

        // 显示输入对话框
        String input = JOptionPane.showInputDialog(null, "请输入你的名字:", "输入", JOptionPane.QUESTION_MESSAGE);
        if (input != null) {
            System.out.println("你输入的名字是:" + input);
        }
    }
}

自定义对话框

如果需要更复杂的对话框,可以继承JDialog类来创建自定义对话框。这种方式允许完全控制对话框的布局和行为。

java 复制代码
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class CustomDialog extends JDialog {
    public CustomDialog(JFrame parent) {
        super(parent, "自定义对话框", true);
        setLayout(new FlowLayout());
        add(new JLabel("这是一个自定义对话框"));
        JButton closeButton = new JButton("关闭");
        closeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });
        add(closeButton);
        pack();
        setLocationRelativeTo(parent);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("主窗口");
        frame.setSize(300, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        CustomDialog dialog = new CustomDialog(frame);
        dialog.setVisible(true);
    }
}

使用JFileChooser选择文件

JFileChooser类可以用于创建文件选择对话框,允许用户选择文件或目录。

java 复制代码
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileNameExtensionFilter;

public class FileChooserExample {
    public static void main(String[] args) {
        JFileChooser fileChooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("文本文件", "txt");
        fileChooser.setFileFilter(filter);
        int returnValue = fileChooser.showOpenDialog(null);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            System.out.println("选择的文件是:" + fileChooser.getSelectedFile().getAbsolutePath());
        }
    }
}

使用JColorChooser选择颜色

JColorChooser类可以用于创建颜色选择对话框,允许用户选择颜色。

java 复制代码
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import java.awt.Color;

public class ColorChooserExample {
    public static void main(String[] args) {
        Color selectedColor = JColorChooser.showDialog(null, "选择颜色", Color.WHITE);
        if (selectedColor != null) {
            System.out.println("选择的颜色是:" + selectedColor);
        }
    }
}

通过以上方法,可以在Java应用程序中轻松创建各种类型的弹出对话框,满足不同的用户交互需求。

窗口修饰和自定义形状

一、窗口修饰(去除标题栏、边框)

步骤

  1. frame.setUndecorated(true) 移除默认修饰
  2. 手动添加标题栏 / 按钮
  3. 实现窗口拖动逻辑

示例代码

java

复制代码
JFrame frame = new JFrame();
frame.setUndecorated(true); // 先移除默认修饰

// 添加自定义标题栏和关闭按钮
JPanel titleBar = new JPanel();
titleBar.add(new JLabel("自定义标题"));
titleBar.add(new JButton("X"));

// 实现拖动功能(略,见之前示例)

二、自定义窗口形状

步骤

  1. setUndecorated(true)
  2. setShape(shape) 设置形状
  3. 确保内容绘制与形状一致

示例代码(圆形窗口)

java

复制代码
JFrame frame = new JFrame();
frame.setUndecorated(true); // 必须先移除默认修饰

// 创建圆形面板
JPanel panel = new JPanel() {
    @Override
    protected void paintComponent(Graphics g) {
        g.fillOval(0, 0, getWidth(), getHeight());
    }
};

frame.setContentPane(panel);
frame.pack();

// 设置窗口形状为圆形(在pack之后)
frame.setShape(new Ellipse2D.Double(0, 0, frame.getWidth(), frame.getHeight()));

三、透明窗口

步骤

  1. setUndecorated(true)
  2. setOpacity(0.5f) 设置透明度(0.0-1.0)
  3. 内容面板设为透明

示例代码

java

复制代码
frame.setUndecorated(true);
frame.setOpacity(0.8f); // 80%透明度

JPanel panel = new JPanel();
panel.setBackground(new Color(255, 255, 255, 100)); // 半透明白色
frame.setContentPane(panel);

四、关键注意事项

  1. 顺序 :必须先 setUndecorated(true),再设置形状 / 透明度

  2. 系统检查 :使用前检查系统支持:

    java

    复制代码
    boolean supportsShape = GraphicsEnvironment.getLocalGraphicsEnvironment()
        .getDefaultScreenDevice()
        .isWindowTranslucencySupported(WindowTranslucency.PERPIXEL_TRANSPARENT);
  3. 性能:复杂形状 / 透明度可能影响性能

  4. 拖动逻辑 :移除修饰后需手动实现窗口拖动(见之前示例中的 WindowDragListener

多面板和分割面板:

在 Java 的 Swing GUI 编程里,多面板和分割面板是组织和管理界面的重要组件。下面为你详细介绍它们的概念、用法和区别。

多面板(Multi-Panel)

多面板并非 Java 的标准术语,不过在实际应用中,它指的是将多个面板组合到一个容器里的布局方式。这种方式能够让界面结构清晰,便于管理。

常见实现方式

  1. 嵌套 JPanel:可以把多个 JPanel 添加到一个父容器中,每个子面板负责管理特定区域的组件。
  2. 卡片布局(CardLayout):这是一种特殊的布局管理器,它能让多个组件共享同一显示空间,组件之间可以像卡片一样切换。
  3. 选项卡面板(JTabbedPane):它会创建带有选项卡的界面,每个选项卡下面都可以放置不同的面板。

示例代码

下面是一个嵌套 JPanel 的例子:

复制代码
import javax.swing.*;
import java.awt.*;

public class MultiPanelExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("多面板示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);

        // 创建主面板,使用边界布局
        JPanel mainPanel = new JPanel(new BorderLayout());

        // 顶部面板 - 包含按钮
        JPanel topPanel = new JPanel();
        topPanel.add(new JButton("按钮1"));
        topPanel.add(new JButton("按钮2"));

        // 中部面板 - 包含文本区域
        JPanel centerPanel = new JPanel();
        centerPanel.add(new JTextArea(10, 30));

        // 将子面板添加到主面板
        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(centerPanel, BorderLayout.CENTER);

        // 将主面板添加到窗口
        frame.setContentPane(mainPanel);
        frame.setVisible(true);
    }
}

分割面板(JSplitPane)

JSplitPane 是 Swing 提供的标准组件,其主要功能是创建一个可调整的分割线,把容器分为两个区域。用户能够通过拖动分割线来改变两个区域的大小。

关键特性

  1. 方向支持:支持水平分割(HORIZONTAL_SPLIT)和垂直分割(VERTICAL_SPLIT)。
  2. 连续重绘:在拖动分割线时,可以选择实时重绘界面或者在拖动结束后再重绘。
  3. 固定比例:能够设置分割线的位置,既可以使用像素值,也可以使用相对于容器大小的比例。

示例代码

下面是一个使用 JSplitPane 的例子:

java

复制代码
import javax.swing.*;
import java.awt.*;

public class SplitPaneExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("分割面板示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);

        // 创建左侧面板
        JPanel leftPanel = new JPanel();
        leftPanel.add(new JList<>(new String[]{"项目1", "项目2", "项目3"}));

        // 创建右侧面板
        JPanel rightPanel = new JPanel();
        rightPanel.add(new JTextArea(20, 30));

        // 创建水平分割面板
        JSplitPane splitPane = new JSplitPane(
                JSplitPane.HORIZONTAL_SPLIT,
                leftPanel,
                rightPanel
        );

        // 设置分割线位置(相对于容器宽度的比例)
        splitPane.setDividerLocation(0.3);

        // 设置连续重绘,使拖动更流畅
        splitPane.setContinuousLayout(true);

        // 将分割面板添加到窗口
        frame.setContentPane(splitPane);
        frame.setVisible(true);
    }
}

多面板与分割面板的主要区别

特性 多面板(嵌套 JPanel) 分割面板(JSplitPane)
布局方式 需要手动管理每个面板的大小和位置 自动管理两个区域,可通过拖动分割线调整
用户交互 面板大小固定,用户无法动态调整 用户可以实时调整两个区域的大小
应用场景 适合界面布局固定的情况,例如表单、工具栏 适合需要动态调整空间分配的场景,如图文混排、资源管理器
实现复杂度 需要处理多个面板的布局,相对复杂 只需设置一次,自动处理大部分布局逻辑

SWing和Awt的区别

1. 历史与定位

  • AWT(1995 年)

    • Java 最早的 GUI 库,属于 Java 基础类库(JRE)的一部分。
    • 称为 "重量级" 组件,依赖底层操作系统的原生窗口系统(如 Windows 的 Win32 API)。
  • Swing(1997 年)

    • 作为 AWT 的扩展,属于 Java Foundation Classes (JFC)。
    • 称为 "轻量级" 组件,完全由 Java 代码实现,不依赖原生窗口系统。

2. 核心架构差异

特性 AWT(重量级) Swing(轻量级)
组件实现 依赖原生窗口系统(如 Windows/Linux) 纯 Java 实现,跨平台一致性好
渲染方式 由操作系统负责绘制 由 Java 虚拟机(JVM)负责绘制
内存占用 高(每个组件对应一个原生窗口句柄) 低(共享一个窗口句柄)
性能 受限于操作系统绘制效率 通常更高,但复杂 UI 可能有性能开销
外观一致性 与操作系统风格一致 可定制外观(如 Nimbus、Metal)

3. 组件对比

组件类型 AWT 类 Swing 等效类
窗口 Frame, Dialog JFrame, JDialog
面板 Panel JPanel
按钮 Button JButton
标签 Label JLabel
文本框 TextField JTextField
滚动面板 ScrollPane JScrollPane
菜单 MenuBar, Menu, MenuItem JMenuBar, JMenu, JMenuItem
对话框 FileDialog JFileChooser

4. 功能特性对比

特性 AWT Swing
透明效果 不支持 支持(如setOpaque(false)
自定义边框 无内置支持 丰富的边框选项(BorderFactory
双缓冲 需手动实现 默认启用,减少闪烁
事件处理 基于接口(如ActionListener 支持匿名内部类和 Lambda 表达式
数据模型 无统一数据模型 支持 MVC 模式(如TableModel
组件丰富度 基础组件 提供更多高级组件(如JTable, JTree
主题支持 依赖操作系统 支持多种主题(如 Nimbus、Windows 风格)

5. 线程安全性

  • AWT

    • 非线程安全,但早期 Java 版本允许在任意线程更新 UI(可能导致绘制异常)。
  • Swing

    • 严格要求在事件调度线程(Event Dispatch Thread, EDT)中操作 UI,否则可能出现竞态条件。
    • 使用SwingUtilities.invokeLater()SwingUtilities.invokeAndWait()确保线程安全。

java

复制代码
// 示例:在EDT中创建Swing UI
SwingUtilities.invokeLater(() -> {
    JFrame frame = new JFrame("线程安全示例");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new JLabel("Hello, Swing!"));
    frame.pack();
    frame.setVisible(true);
});

6. 应用场景

  • 选择 AWT

    • 开发简单工具或小程序。
    • 需要与操作系统原生组件深度集成。
    • 维护旧 Java 项目(如 JDK 1.1 时代的代码)。
  • 选择 Swing

    • 开发跨平台的桌面应用。
    • 需要丰富的 UI 组件(如表格、树状结构)。
    • 需要自定义外观或动画效果。
    • 开发复杂的企业级应用(如 IDE、数据可视化工具)。

7. 现代替代方案

虽然 Swing 和 AWT 仍被广泛使用,但 Java 的 GUI 生态已发展出更现代的框架:

  • JavaFX(自 Java 8 引入)

    • 官方推荐的下一代 GUI 框架,支持 FXML、CSS 样式、3D 图形和多媒体。
    • 逐渐取代 Swing 成为 Java 桌面应用的首选。
  • 第三方框架

    • Apache Pivot:基于 Batik 的轻量级框架,支持多种 UI 风格。
    • MigLayout:增强的布局管理器,简化复杂布局的实现。
    • JGoodies Forms:提供更灵活的表单布局解决方案。

总结

维度 AWT Swing
年代 早期(JDK 1.0) 后期(JDK 1.2+)
技术路线 重量级,依赖原生系统 轻量级,纯 Java 实现
外观控制 受限(与系统一致) 高度可定制
性能 低(原生调用开销) 高(Java 优化)
学习曲线 简单(基础 API) 较复杂(更多概念)
推荐场景 简单工具、原生集成 复杂 UI、跨平台应用
相关推荐
jllllyuz15 分钟前
matlab实现蚁群算法解决公交车路径规划问题
服务器·前端·数据库
小屁孩大帅-杨一凡1 小时前
一个简单点的js的h5页面实现地铁快跑的小游戏
开发语言·前端·javascript·css·html
读心悦1 小时前
CSS 布局系统深度解析:从传统到现代的布局方案
前端·css
椒盐螺丝钉1 小时前
CSS盒子模型:Padding与Margin的适用场景与注意事项
前端·css
萧鼎2 小时前
构建全栈 Web 应用的新选择:NextPy 技术详解与实战指南
前端
这个一个非常哈2 小时前
VUE篇之自定义组件使用v-model
前端·javascript·vue.js
purpleseashell_Lili3 小时前
react 基本写法
java·服务器·前端
哎哟喂_!3 小时前
Node.js 循环依赖问题详解:原理、案例与解决方案
前端·chrome·node.js
热爱前端的小君同学3 小时前
长按拖拽移动的vue3组件
前端·javascript·vue.js
Rhys..3 小时前
如何禁止chrome自动更新
前端·chrome