模式切换
Swing 程序设计
Swing 是 Java 提供的一个图形用户界面(GUI)工具包,用于开发跨平台的桌面应用程序。Swing 提供了一套丰富的控件和布局管理器,能够帮助开发者设计和实现高效、友好的图形界面。Swing 完全基于 Java 类库,因此能跨平台运行,不依赖于操作系统。
Swing 概述
Swing 特点
- 轻量级组件:Swing 控件是“轻量级”的,即它们不依赖于操作系统的本地窗口组件,而是完全使用 Java 代码来实现其外观。
- 跨平台支持:Swing 是用 Java 编写的,程序可以在不同操作系统上运行,而不需要修改代码。
- 高度可定制:Swing 提供了丰富的 API,可以自定义界面组件的外观和行为。例如,开发者可以定制按钮的样式,或修改文本框的显示方式。
- 多样的组件和布局:Swing 提供了各种各样的 GUI 组件(按钮、文本框、表格等),并且支持不同的布局管理器,使得界面布局更加灵活。
- 事件驱动:Swing 程序的运行是基于事件驱动的,即用户的操作(如点击按钮、输入文本)触发特定的事件,程序通过监听事件来做出响应。
Swing 包
Swing 组件包含在 javax.swing
包中,其中包含了最常用的 GUI 组件,如 JButton
、JTextField
、JLabel
等。此外,Swing 还提供了多种布局管理器和事件处理机制。
java
import javax.swing.*;
常用 Swing 组件概述
Swing 提供了多种组件来构建图形用户界面,常见的包括:
- JButton:按钮组件。
- JLabel:标签组件。
- JTextField:单行文本框。
- JTextArea:多行文本框。
- JCheckBox:复选框。
- JRadioButton:单选按钮。
- JComboBox:下拉列表框。
- JTable:表格组件。
- JTree:树形组件。
这些组件可以用于构建各种用户界面。
常用窗体
JFrame 窗体
JFrame
是 Swing 中用于创建窗口的类。它是一个顶层容器,可以包含菜单、按钮、文本框等其他 GUI 组件。
创建一个简单的 JFrame 窗口:
java
import javax.swing.*;
public class SimpleFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("My First Swing Application");
frame.setSize(400, 300); // 设置窗口大小
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 窗口关闭时退出程序
frame.setVisible(true); // 显示窗口
}
}
JDialog 窗体
JDialog
是一个对话框窗口,可以用于弹出窗口,通常用于获取用户的输入或显示提示信息。
创建一个简单的 JDialog 对话框:
java
import javax.swing.*;
public class SimpleDialog {
public static void main(String[] args) {
JDialog dialog = new JDialog();
dialog.setTitle("Simple Dialog");
dialog.setSize(300, 200);
dialog.setVisible(true);
}
}
标签组件与图标
标签的使用
JLabel
用于显示文字或图标,常用于标记界面上的其他组件或提供信息。
java
JLabel label = new JLabel("Hello, Swing!");
图标的使用
JLabel
还可以显示图标。图标可以使用 ImageIcon
类来加载。
java
ImageIcon icon = new ImageIcon("icon.png");
JLabel label = new JLabel("Hello, Swing!", icon, JLabel.CENTER);
常用布局管理器
布局管理器用于管理组件在容器中的排列方式。Swing 提供了几种常见的布局管理器:
绝对布局
绝对布局是指将组件的尺寸和位置完全由开发者控制。Swing 默认情况下使用流式布局而非绝对布局,因而开发者需要明确设置组件的位置和尺寸。
java
JPanel panel = new JPanel();
panel.setLayout(null); // 设置为绝对布局
JButton button = new JButton("Click Me");
button.setBounds(50, 50, 100, 30); // 设置按钮位置和大小
panel.add(button);
流布局管理器
流布局(FlowLayout)是最常见的布局之一,它将组件按顺序排列,默认从左到右,逐行排列。
java
JPanel panel = new JPanel(new FlowLayout());
panel.add(new JButton("Button 1"));
panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));
边界布局管理器
边界布局(BorderLayout)将容器分成五个区域:北、南、东、西和中间。可以将组件放置在这些区域中。
java
JPanel panel = new JPanel(new BorderLayout());
panel.add(new JButton("North"), BorderLayout.NORTH);
panel.add(new JButton("South"), BorderLayout.SOUTH);
panel.add(new JButton("Center"), BorderLayout.CENTER);
网格布局管理器
网格布局(GridLayout)将容器划分为网格,将组件按行和列排列。
java
JPanel panel = new JPanel(new GridLayout(2, 2)); // 2 行 2 列
panel.add(new JButton("Button 1"));
panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));
panel.add(new JButton("Button 4"));
网格组布局管理器
网格组布局(GridBagLayout)是一个复杂的布局管理器,允许用户更灵活地控制组件的大小、位置和对齐方式。
java
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0; gbc.gridy = 0;
panel.add(new JButton("Button 1"), gbc);
常用面板
JPanel 面板
JPanel
是一个容器,用来放置其他组件。它本身不显示任何内容,但是可以设置布局并承载其他组件。
java
JPanel panel = new JPanel();
panel.add(new JButton("Button"));
JScrollPane 面板
JScrollPane
用于将一个组件(如长文本框、表格等)放入滚动面板,以便当内容超出面板显示范围时,可以滚动查看。
java
JTextArea textArea = new JTextArea(10, 20);
JScrollPane scrollPane = new JScrollPane(textArea);
按钮组件
提交按钮组件
JButton
用于创建按钮,可以用来执行某些操作,如提交表单、提交数据等。
java
JButton submitButton = new JButton("Submit");
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Form Submitted");
}
});
单选按钮组件
JRadioButton
用于创建单选按钮。多个单选按钮可以组合在一起,只能选择其中一个。
java
JRadioButton radioButton = new JRadioButton("Option 1");
ButtonGroup group = new ButtonGroup();
group.add(radioButton);
复选框组件
JCheckBox
用于创建复选框,允许用户选择或取消选择。
java
JCheckBox checkBox = new JCheckBox("Accept Terms");
列表组件
下拉列表框组件
JComboBox
是下拉列表框组件,允许用户从一个预定义的选项中选择一个。
java
String[] items = {"Item 1", "Item 2", "Item 3"};
JComboBox<String> comboBox = new JComboBox<>(items);
列表框组件
JList
用于显示一个列表,用户可以从中选择一个或多个选项。
java
String[] items = {"Item 1", "Item 2", "Item 3"};
JList<String> list = new JList<>(items);
文本组件
文本框组件
JTextField
用于创建单行文本框,常用于输入文本。
java
JTextField textField = new JTextField(20);
密码框组件
JPasswordField
用于创建密码输入框,输入的内容以星号显示。
java
JPasswordField passwordField = new JPasswordField(20);
文本域组件
JTextArea
用于创建多行文本框,常用于显示或输入长文本。
java
JTextArea textArea = new JTextArea(5, 20);
常用事件监听器
Swing 是事件驱动的,所有的操作和交互都会触发事件。为了响应这些事件,我们需要使用事件监听器。
监听事件简介
事件监听器是 Java 中的一个接口,用来处理用户与界面组件交互时触发的事件。常见的事件包括鼠标点击、键盘输入、焦点变化等。监听器会监控这些事件,并调用相应的回调方法来响应事件。
步骤:
- 创建一个事件监听器类并实现相应的接口。
- 在组件上注册该监听器。
例如,我们可以监听按钮的点击事件,监听文本框的内容变化等。
动作事件监听器
ActionListener
用于处理用户触发的动作事件,最常见的就是按钮的点击事件。它的核心方法是 actionPerformed(ActionEvent e)
。
示例:
java
import javax.swing.*;
import java.awt.event.*;
public class ActionListenerExample {
public static void main(String[] args) {
JFrame frame = new JFrame("ActionListener Example");
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.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
当按钮被点击时,会输出 "Button clicked!"。
焦点事件监听器
FocusListener
用于监听组件获取或失去焦点的事件。它有两个方法:
focusGained(FocusEvent e)
:组件获得焦点时调用。focusLost(FocusEvent e)
:组件失去焦点时调用。
示例:
java
import javax.swing.*;
import java.awt.event.*;
public class FocusListenerExample {
public static void main(String[] args) {
JFrame frame = new JFrame("FocusListener Example");
JTextField textField = new JTextField(20);
textField.addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
System.out.println("Text field gained focus");
}
@Override
public void focusLost(FocusEvent e) {
System.out.println("Text field lost focus");
}
});
frame.add(textField);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
当文本框获取焦点时,输出“Text field gained focus”,当失去焦点时,输出“Text field lost focus”。
Swing 表格组件
利用 JTable 类直接创建表格
JTable
是 Swing 中用来显示表格数据的组件。它可以用来显示数据、编辑数据和对数据进行排序等操作。
创建表格
java
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
public class JTableExample {
public static void main(String[] args) {
JFrame frame = new JFrame("JTable Example");
String[][] data = {
{"John", "25", "Engineer"},
{"Jane", "22", "Designer"},
{"Mark", "30", "Manager"}
};
String[] columnNames = {"Name", "Age", "Occupation"};
JTable table = new JTable(data, columnNames);
JScrollPane scrollPane = new JScrollPane(table); // 为表格加滚动条
frame.add(scrollPane);
frame.setSize(400, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
定制表格
我们可以通过自定义 TableModel
和 TableCellRenderer
来定制表格的显示和行为。
java
DefaultTableModel model = new DefaultTableModel(data, columnNames);
table.setModel(model);
操控表格
JTable
提供了修改数据、获取选中行、列等功能。
java
int selectedRow = table.getSelectedRow(); // 获取选中行的索引
String cellValue = (String) table.getValueAt(selectedRow, 0); // 获取指定单元格的值
表格模型与表格
利用表格模型创建表格
TableModel
是表格数据的核心,它定义了如何操作表格中的数据。通常我们会使用 DefaultTableModel
类来实现 TableModel
接口。
java
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model);
维护表格模型
可以通过调用 setValueAt()
、addRow()
等方法来动态地修改表格数据。
java
model.setValueAt("New Name", 0, 0); // 修改第0行第0列的数据
model.addRow(new Object[] {"Tom", "28", "Developer"}); // 添加一行数据
提供行标题栏的表格
可以通过 JTable
的 getTableHeader()
方法获得表格头部信息。行标题栏用于显示列的名称。
java
JTable table = new JTable(data, columnNames);
table.setTableHeader(new JTableHeader(new TableColumnModel())); // 设置表头
Swing 树组件
简单的树
树形组件(JTree
)用于展示分层结构的数据。最常见的用法是文件系统视图。
java
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class TreeExample {
public static void main(String[] args) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
DefaultMutableTreeNode child1 = new DefaultMutableTreeNode("Child 1");
DefaultMutableTreeNode child2 = new DefaultMutableTreeNode("Child 2");
root.add(child1);
root.add(child2);
JTree tree = new JTree(root);
JFrame frame = new JFrame("JTree Example");
frame.add(new JScrollPane(tree));
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
处理选中节点事件
可以通过添加 TreeSelectionListener
来处理树的选中节点事件。
java
tree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
System.out.println("Selected Node: " + node.getUserObject());
}
});
遍历树节点
我们可以使用递归方法来遍历树的节点,获取树的所有节点信息。
java
private void traverseTree(DefaultMutableTreeNode node) {
System.out.println(node.getUserObject());
for (int i = 0; i < node.getChildCount(); i++) {
traverseTree((DefaultMutableTreeNode) node.getChildAt(i));
}
}
定制树
可以通过自定义 TreeCellRenderer
来定制树的显示方式。
java
tree.setCellRenderer(new MyTreeCellRenderer());
维护树模型
DefaultTreeModel
类用于管理树的节点数据。你可以通过调用 insertNodeInto()
或 removeNodeFromParent()
等方法动态修改树结构。
java
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
model.insertNodeInto(new DefaultMutableTreeNode("New Node"), parentNode, index);
处理展开节点事件
TreeExpansionListener
用于监听树节点展开或收缩事件。
java
tree.addTreeExpansionListener(new TreeExpansionListener() {
@Override
public void treeExpanded(TreeExpansionEvent event) {
System.out.println("Node expanded: " + event.getPath());
}
@Override
public void treeCollapsed(TreeExpansionEvent event) {
System.out.println("Node collapsed: " + event.getPath());
}
});
Swing 其他高级组件
高级组件面板
分割面板
JSplitPane
用于分割面板并允许用户调整面板大小。
java
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
选项卡面板
JTabbedPane
用于实现标签式布局。
java
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Tab 1", panel1);
tabbedPane.addTab("Tab 2", panel2);
桌面面板和内部窗体
JDesktopPane
用于管理多个内部窗体。
java
JDesktopPane desktopPane = new JDesktopPane();
JInternalFrame internalFrame = new JInternalFrame("Internal Frame", true, true, true, true);
desktopPane.add(internalFrame);
菜单
创建菜单栏
JMenuBar
和 JMenu
用于创建菜单栏和菜单项。
java
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
fileMenu.add(new JMenuItem("Open"));
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
创建弹出式菜单
java
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem item1 = new JMenuItem("Item 1");
popupMenu.add(item1);
frame.setComponentPopupMenu(popupMenu);
定制个性化菜单
可以通过自定义 JMenuItem
来实现个性化的菜单项。
工具栏
JToolBar
用于创建图标工具栏。
java
JToolBar toolBar = new JToolBar();
toolBar.add(new JButton("New"));
frame.add(toolBar, BorderLayout.NORTH);
文件选择器
文件选择对话框
JFileChooser
用于显示文件选择对话框。
java
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog(frame);
if (result == JFileChooser.APPROVE_OPTION) {
System.out.println(fileChooser.getSelectedFile());
}
使用文件过滤器
java
FileNameExtensionFilter filter = new FileNameExtensionFilter("Text files", "txt");
fileChooser.setFileFilter(filter);
进度条
JProgressBar
用于显示任务进度。
java
JProgressBar progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
frame.add(progressBar);
系统托盘
系统托盘显示应用图标。通过 SystemTray
类来实现。
java
SystemTray tray = SystemTray.getSystemTray();
TrayIcon icon = new TrayIcon(image, "Tray Example");
tray.add(icon);
桌面集成控件
Swing 提供了桌面集成控件,可以与操作系统的窗口管理系统进行交互。
高级事件处理
键盘事件
通过 KeyListener
接口来处理键盘事件。
java
textField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("Key pressed: " + e.getKeyChar());
}
});
鼠标事件
MouseListener
用于处理鼠标事件。
java
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Mouse clicked");
}
});
窗体事件
WindowListener
用于监听窗体事件(如焦点变化、窗体状态变化等)。
java
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
System.out.println("Window activated");
}
});
捕获窗体焦点变化事件
java
frame.addWindowFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
System.out.println("Window gained focus");
}
});
捕获窗体状态变化事件
java
frame.addWindowStateListener(new WindowStateListener() {
@Override
public void windowStateChanged(WindowEvent e) {
System.out.println("Window state changed");
}
});
捕获其他窗体事件
WindowListener
的其他方法可以用来处理窗体的关闭、最小化等事件。
选项事件
选项事件用于监听组件选中状态的变化,如单选按钮、复选框等。
java
checkbox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println("Checkbox selected: " + (e.getStateChange() == ItemEvent.SELECTED));
}
});
表格模型事件
用于监听表格数据的增删改。
java
table.getModel().addTableModelListener(e -> {
System.out.println("Table data changed");
});
AWT 绘图
Java 绘图
AWT 提供了 Graphics
类来实现图形的绘制,Graphics2D
提供了更强大的绘制功能。
Graphics
用于基本绘图,绘制线条、矩形、圆形等。
java
public void paint(Graphics g) {
g.drawRect(50, 50, 100, 100); // 绘制矩形
}
Graphics2D
用于高级绘图,如变换、抗锯齿、填充等。
java
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.fillOval(50, 50, 100, 100);
绘制图形
可以使用 drawLine
、drawRect
、drawOval
等方法绘制图形。
绘图颜色与画笔属性
设置颜色
java
g.setColor(Color.RED);
g.fillRect(50, 50, 100, 100);
画笔属性
可以设置线条的宽度、样式等。
java
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(new BasicStroke(5));
g2d.drawLine(50, 50, 200, 200);
绘制文本
设置字体
java
Font font = new Font("Serif", Font.PLAIN, 20);
g.setFont(font);
显示文字
java
g.drawString("Hello, Swing!", 50, 50);
绘制图片
通过 drawImage()
方法来绘制图像。
java
Image img = Toolkit.getDefaultToolkit().getImage("image.png");
g.drawImage(img, 0, 0, this);
图像处理
放大与缩小
使用 getScaledInstance()
方法来缩放图像。
图像翻转
使用图形变换(如 AffineTransform
)来实现翻转。
图像旋转
使用 AffineTransform
来旋转图像。
图像倾斜
通过 shear
变换来倾斜图像。