Java Swing 与 JavaFX 入门:从文件比较工具到事件处理与应用开发
1. Swing 基础:创建文件比较工具
Swing 是 Java 中用于创建图形用户界面(GUI)的强大工具。即使你对 Swing 了解有限,也可以用它来创建实用的应用程序。下面我们将创建一个基于 Swing 的文件比较工具。
1.1 创建项目文件与导入必要包
首先,创建一个名为
SwingFC.java
的文件,并输入以下注释和导入语句:
/*
Try This 16-1
A Swing-based file comparison utility.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
1.2 定义
SwingFC
类
接下来,定义
SwingFC
类,该类实现了
ActionListener
接口:
class SwingFC implements ActionListener {
JTextField jtfFirst; // holds the first file name
JTextField jtfSecond; // holds the second file name
JButton jbtnComp; // button to compare the files
JLabel jlabFirst, jlabSecond; // displays prompts
JLabel jlabResult; // displays results and error messages
}
在这个类中,
jtfFirst
和
jtfSecond
用于存储要比较的两个文件的名称,
jbtnComp
是用于触发比较操作的按钮,
jlabFirst
和
jlabSecond
用于显示提示信息,
jlabResult
用于显示比较结果或错误信息。
1.3 编写
SwingFC
构造函数
SwingFC() {
// Create a new JFrame container.
JFrame jfrm = new JFrame("Compare Files");
// Specify FlowLayout for the layout manager.
jfrm.setLayout(new FlowLayout());
// Give the frame an initial size.
jfrm.setSize(200, 190);
// Terminate the program when the user closes the application.
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create the text fields for the file names.
jtfFirst = new JTextField(14);
jtfSecond = new JTextField(14);
// Set the action commands for the text fields.
jtfFirst.setActionCommand("fileA");
jtfSecond.setActionCommand("fileB");
// Create the Compare button.
JButton jbtnComp = new JButton("Compare");
// Add action listener for the Compare button.
jbtnComp.addActionListener(this);
// Create the labels.
jlabFirst = new JLabel("First file: ");
jlabSecond = new JLabel("Second file: ");
jlabResult = new JLabel("");
// Add the components to the content pane.
jfrm.add(jlabFirst);
jfrm.add(jtfFirst);
jfrm.add(jlabSecond);
jfrm.add(jtfSecond);
jfrm.add(jbtnComp);
jfrm.add(jlabResult);
// Display the frame.
jfrm.setVisible(true);
}
在构造函数中,我们创建了一个新的
JFrame
容器,并设置了布局管理器、初始大小和关闭操作。同时,创建了文本字段、按钮和标签,并将它们添加到
JFrame
中。需要注意的是,我们只给按钮添加了动作监听器,因为只有在点击按钮时才需要获取文本字段的内容。
1.4 实现
actionPerformed
方法
// Compare the files when the Compare button is pressed.
public void actionPerformed(ActionEvent ae) {
int i=0, j=0;
// First, confirm that both file names have
// been entered.
if(jtfFirst.getText().equals("")) {
jlabResult.setText("First file name missing.");
return;
}
if(jtfSecond.getText().equals("")) {
jlabResult.setText("Second file name missing.");
return;
}
// Compare files. Use try-with-resources to manage the files.
try (FileInputStream f1 = new FileInputStream(jtfFirst.getText());
FileInputStream f2 = new FileInputStream(jtfSecond.getText()))
{
// Check the contents of each file.
do {
i = f1.read();
j = f2.read();
if(i != j) break;
} while(i != -1 && j != -1);
if(i != j)
jlabResult.setText("Files are not the same.");
else
jlabResult.setText("Files compare equal.");
} catch(IOException exc) {
jlabResult.setText("File Error");
}
}
当点击比较按钮时,
actionPerformed
方法会被调用。该方法首先检查两个文本字段是否都输入了文件名,如果没有则显示相应的错误信息。然后,使用
try-with-resources
语句打开两个文件,并逐字节比较它们的内容。最后,根据比较结果在
jlabResult
中显示相应的信息。
1.5 添加
main
方法
public static void main(String args[]) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new SwingFC();
}
});
}
main
方法使用
SwingUtilities.invokeLater
方法在事件调度线程上创建并显示
SwingFC
实例。
2. 使用匿名内部类或 Lambda 表达式处理事件
在前面的例子中,我们使用了简单直接的方式处理事件,即让主类实现监听器接口并将所有事件发送到该类的实例。但还有其他处理事件的方法,如使用匿名内部类和 Lambda 表达式。
2.1 匿名内部类
匿名内部类是没有名称的内部类,它可以在需要时“即时”生成。使用匿名内部类可以更方便地实现某些类型的事件处理程序。例如,为一个
JButton
添加动作监听器:
jbtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
// Handle action event here.
}
});
在这个例子中,我们创建了一个实现
ActionListener
接口的匿名内部类,并将其作为参数传递给
addActionListener
方法。
2.2 Lambda 表达式
对于定义了函数式接口的事件监听器,还可以使用 Lambda 表达式来处理事件。例如,为一个
JButton
添加动作监听器:
jbtn.addActionListener((ae) -> {
// Handle action event here.
});
如果事件可以用单个表达式处理,则可以使用更简洁的表达式 Lambda。例如:
jbtnUp.addActionListener((ae) -> jlab.setText("You pressed Up."));
使用 Lambda 表达式可以使代码更加简洁。
3. 创建 Swing 小程序
除了应用程序,Swing 还可以用于创建小程序。Swing 小程序与 AWT 小程序类似,但有一个重要区别:Swing 小程序继承自
JApplet
而不是
Applet
。
3.1 示例代码
// A simple Swing-based applet
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
This HTML can be used to launch the applet:
<applet code="MySwingApplet" width=200 height=80>
</applet>
*/
public class MySwingApplet extends JApplet {
JButton jbtnUp;
JButton jbtnDown;
JLabel jlab;
// Initialize the applet.
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable () {
public void run() {
makeGUI(); // initialize the GUI
}
});
} catch(Exception exc) {
System.out.println("Can't create because of "+ exc);
}
}
// This applet does not need to override start(), stop(),
// or destroy().
// Set up and initialize the GUI.
private void makeGUI() {
// Set the applet to use flow layout.
setLayout(new FlowLayout());
// Make two buttons.
jbtnUp = new JButton("Up");
jbtnDown = new JButton("Down");
// Add action listener for Up button.
jbtnUp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
jlab.setText("You pressed Up.");
}
});
// Add action listener for Down button.
jbtnDown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
jlab.setText("You pressed down.");
}
});
// Add the buttons to the content pane.
add(jbtnUp);
add(jbtnDown);
// Create a text-based label.
jlab = new JLabel("Press a button.");
// Add the label to the content pane.
add(jlab);
}
}
在这个例子中,
MySwingApplet
类继承自
JApplet
。
init
方法使用
SwingUtilities.invokeAndWait
方法在事件调度线程上初始化 GUI。
makeGUI
方法创建了两个按钮和一个标签,并为按钮添加了动作监听器。
4. JavaFX 简介
随着计算领域的快速发展,Java 的 GUI 框架也在不断演进。Swing 虽然成功,但在满足现代应用程序对“视觉效果”的要求方面可能存在困难。为了更好地处理现代 GUI 的需求和设计进步,JavaFX 应运而生。
4.1 JavaFX 发展历程
JavaFX 的发展经历了两个主要阶段。最初的 JavaFX 基于一种名为 JavaFX Script 的脚本语言,但该语言已被弃用。从 JavaFX 2.0 版本开始,JavaFX 用 Java 本身进行编程,并提供了全面的 API。自 JDK 7 更新 4 以来,JavaFX 就与 Java 捆绑在一起。最新版本的 JavaFX 是 JavaFX 8,它与 JDK 8 版本号对齐。
4.2 JavaFX 关键技能与概念
- 舞台(Stage)、场景(Scene)、节点(Node)和场景图(Scene Graph) :理解这些概念是构建 JavaFX 应用程序的基础。
- 生命周期方法 :了解 JavaFX 应用程序的生命周期方法,如启动、停止等。
- 应用程序的一般形式 :掌握 JavaFX 应用程序的基本结构。
- 启动应用程序 :学会如何启动 JavaFX 应用程序。
- 创建标签、按钮、处理事件、使用复选框、列表视图、文本字段等 :掌握这些基本组件的使用方法。
- 添加效果和应用变换 :为应用程序添加视觉效果和变换。
总结
通过本文,我们学习了如何使用 Swing 创建文件比较工具、处理事件、创建小程序,以及 JavaFX 的基本概念和发展历程。Swing 提供了丰富的组件和功能,能够帮助我们创建出美观、易用的 GUI 应用程序。而 JavaFX 则为现代 GUI 开发提供了更强大的支持。希望这些知识能帮助你在 Java GUI 开发的道路上更进一步。
常见问题解答
| 问题 | 答案 |
|---|---|
| AWT 组件和 Swing 组件的特点是什么? | 一般来说,AWT 组件是重量级的,Swing 组件是轻量级的。 |
| Swing 组件的外观和感觉可以改变吗?如何改变? | 可以,通过特定的功能可以改变 Swing 组件的外观和感觉。 |
| 应用程序最常用的顶级容器是什么? |
最常用的顶级容器是
JFrame
。
|
| 顶级容器有多个面板,组件添加到哪个面板? | 组件添加到内容面板。 |
| 如何构造一个包含特定消息的标签? |
可以使用
JLabel
类,例如
JLabel label = new JLabel("Select an entry from the list");
|
| 与 GUI 组件的所有交互必须在哪个线程上进行? | 必须在事件调度线程上进行。 |
JButton
的默认动作命令是什么?如何更改动作命令?
|
默认动作命令是按钮的文本,可使用
setActionCommand
方法更改。
|
| 按下按钮会生成什么事件? | 按下按钮会生成动作事件。 |
| 如何创建一个具有 32 列的文本字段? |
使用
JTextField
类,例如
JTextField textField = new JTextField(32);
|
JTextField
可以设置动作命令吗?如何设置?
|
可以,使用
setActionCommand
方法设置。
|
| 哪个 Swing 组件创建复选框?复选框被选中或取消选中时会生成什么事件? |
使用
JCheckBox
组件创建复选框,会生成项事件。
|
JList
可以显示用户可选择的项目列表吗?
|
可以,
JList
用于显示用户可选择的项目列表。
|
用户在
JList
中选择或取消选择项目时会生成什么事件?
| 会生成列表选择事件。 |
JList
的选择模式如何设置?如何获取第一个选中项目的索引?
|
使用
setSelectionMode
方法设置选择模式,使用
getSelectedIndex
方法获取第一个选中项目的索引。
|
| 创建基于 Swing 的小程序需要继承哪个类? |
需要继承
JApplet
类。
|
通常,基于 Swing 的小程序使用
invokeAndWait
方法创建初始 GUI 吗?
| 通常是这样的。 |
流程图:文件比较工具流程
graph TD;
A[启动程序] --> B[输入文件名];
B --> C{文件名是否都输入};
C -- 是 --> D[点击比较按钮];
C -- 否 --> E[显示文件名缺失信息];
D --> F[打开文件];
F --> G[逐字节比较文件内容];
G --> H{文件内容是否相同};
H -- 是 --> I[显示文件相同信息];
H -- 否 --> J[显示文件不同信息];
E --> B;
流程图:Swing 小程序初始化流程
graph TD;
A[启动小程序] --> B[调用 init 方法];
B --> C[使用 invokeAndWait 初始化 GUI];
C --> D[创建按钮和标签];
D --> E[为按钮添加动作监听器];
E --> F[显示 GUI];
Java Swing 与 JavaFX 入门:从文件比较工具到事件处理与应用开发
5. 实践操作与拓展
在掌握了 Swing 和 JavaFX 的基础知识后,我们可以通过一些实践操作来进一步巩固所学知识,并进行拓展。
5.1 为文件比较工具添加复选框
可以为之前创建的文件比较工具添加一个复选框,当选中该复选框时,程序将显示文件中首次出现不匹配的位置。以下是实现步骤:
1. 在
SwingFC
类中添加一个
JCheckBox
成员变量:
JCheckBox jchkShowMismatch;
-
在
SwingFC构造函数中创建并添加该复选框:
// Create the check box
jchkShowMismatch = new JCheckBox("Show position of mismatch");
jfrm.add(jchkShowMismatch);
-
修改
actionPerformed方法,当选中复选框时,记录并显示不匹配位置:
public void actionPerformed(ActionEvent ae) {
int i = 0, j = 0;
int mismatchPosition = -1;
// First, confirm that both file names have
// been entered.
if (jtfFirst.getText().equals("")) {
jlabResult.setText("First file name missing.");
return;
}
if (jtfSecond.getText().equals("")) {
jlabResult.setText("Second file name missing.");
return;
}
// Compare files. Use try-with-resources to manage the files.
try (FileInputStream f1 = new FileInputStream(jtfFirst.getText());
FileInputStream f2 = new FileInputStream(jtfSecond.getText())) {
int position = 0;
do {
i = f1.read();
j = f2.read();
if (i != j) {
if (jchkShowMismatch.isSelected()) {
mismatchPosition = position;
}
break;
}
position++;
} while (i != -1 && j != -1);
if (i != j) {
if (jchkShowMismatch.isSelected() && mismatchPosition != -1) {
jlabResult.setText("Files are not the same. Mismatch at position: " + mismatchPosition);
} else {
jlabResult.setText("Files are not the same.");
}
} else {
jlabResult.setText("Files compare equal.");
}
} catch (IOException exc) {
jlabResult.setText("File Error");
}
}
5.2 修改
JList
选择模式
可以修改
JList
的选择模式,使其允许用户选择多个项目。以下是实现步骤:
1. 创建一个
JList
并设置其选择模式为多选:
import javax.swing.*;
import java.awt.*;
public class MultiSelectJListExample {
public MultiSelectJListExample() {
JFrame jfrm = new JFrame("Multi-Select JList");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(300, 200);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
JList<String> jlist = new JList<>(items);
jlist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
JScrollPane jsp = new JScrollPane(jlist);
jfrm.add(jsp);
jfrm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MultiSelectJListExample());
}
}
在上述代码中,通过
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
方法将
JList
的选择模式设置为多选。
5.3 将帮助类转换为 Swing GUI 程序
可以将之前的帮助类转换为基于 Swing 的 GUI 程序,使用
JList
显示关键字,当用户选择一个关键字时,显示其语法。以下是实现步骤:
1. 创建一个
JList
并添加关键字:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HelpGUI {
JList<String> jlist;
JLabel jlab;
public HelpGUI() {
JFrame jfrm = new JFrame("Help GUI");
jfrm.setLayout(new FlowLayout());
jfrm.setSize(300, 200);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
String[] keywords = {"for", "while", "switch"};
jlist = new JList<>(keywords);
JScrollPane jsp = new JScrollPane(jlist);
jfrm.add(jsp);
jlab = new JLabel("<html>Select an entry from the list</html>");
jfrm.add(jlab);
jlist.addListSelectionListener(e -> {
int index = jlist.getSelectedIndex();
if (index != -1) {
String keyword = keywords[index];
String syntax = "";
switch (keyword) {
case "for":
syntax = "<html>for (initialization; condition; increment)<br>{<br> // code block<br>}</html>";
break;
case "while":
syntax = "<html>while (condition)<br>{<br> // code block<br>}</html>";
break;
case "switch":
syntax = "<html>switch (expression)<br>{<br> case value1:<br> // code block<br> break;<br> case value2:<br> // code block<br> break;<br> default:<br> // code block<br>}</html>";
break;
}
jlab.setText(syntax);
}
});
jfrm.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new HelpGUI());
}
}
在上述代码中,使用
JList
显示关键字,当用户选择一个关键字时,根据关键字显示其语法。
6. 总结与展望
通过前面的学习和实践,我们已经掌握了使用 Swing 创建文件比较工具、处理事件、创建小程序,以及 JavaFX 的基本概念和发展历程。Swing 提供了丰富的组件和功能,能够帮助我们创建出美观、易用的 GUI 应用程序。而 JavaFX 则为现代 GUI 开发提供了更强大的支持。
在未来的学习和开发中,我们可以进一步深入研究 JavaFX 的高级特性,如动画效果、3D 图形等,以创建更加炫酷的 GUI 应用程序。同时,也可以结合其他 Java 技术,如多线程、网络编程等,开发出功能更加丰富的应用程序。
常见问题解答(续)
| 问题 | 答案 |
|---|---|
| 如何为文件比较工具添加复选框并显示不匹配位置? |
1. 在类中添加
JCheckBox
成员变量;2. 在构造函数中创建并添加该复选框;3. 修改
actionPerformed
方法,记录并显示不匹配位置。
|
如何将
JList
的选择模式设置为多选?
|
使用
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
方法。
|
| 如何将帮助类转换为 Swing GUI 程序? |
1. 创建
JList
并添加关键字;2. 为
JList
添加选择监听器,根据选择的关键字显示其语法。
|
流程图:添加复选框后的文件比较工具流程
graph TD;
A[启动程序] --> B[输入文件名];
B --> C{文件名是否都输入};
C -- 是 --> D[点击比较按钮];
C -- 否 --> E[显示文件名缺失信息];
D --> F{是否选中显示不匹配位置复选框};
F -- 是 --> G[打开文件并记录不匹配位置];
F -- 否 --> H[打开文件];
G --> I[逐字节比较文件内容];
H --> I;
I --> J{文件内容是否相同};
J -- 是 --> K[显示文件相同信息];
J -- 否 --> L{是否选中显示不匹配位置复选框};
L -- 是 --> M[显示文件不同信息及不匹配位置];
L -- 否 --> N[显示文件不同信息];
E --> B;
流程图:将帮助类转换为 Swing GUI 程序流程
graph TD;
A[启动程序] --> B[创建 JList 并添加关键字];
B --> C[创建 JLabel 显示提示信息];
C --> D[为 JList 添加选择监听器];
D --> E{用户是否选择关键字};
E -- 是 --> F[根据关键字显示语法];
E -- 否 --> G[等待用户选择];
超级会员免费看
2708

被折叠的 条评论
为什么被折叠?



