49、Java Swing 与 JavaFX 入门:从文件比较工具到事件处理与应用开发

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;
  1. SwingFC 构造函数中创建并添加该复选框:
// Create the check box
jchkShowMismatch = new JCheckBox("Show position of mismatch");
jfrm.add(jchkShowMismatch);
  1. 修改 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[等待用户选择];
下载方式:https://pan.quark.cn/s/c9b9b647468b ### 初级JSP程序设计教程核心内容解析#### 一、JSP基础概述JSP(JavaServer Pages)是由Sun Microsystems公司创建的一种动态网页技术规范,主要应用于构建动态网站及Web应用。JSP技术使得开发者能够将动态数据静态HTML文档整合,从而实现网页内容的灵活性和可变性。##### JSP的显著特性:1. **动态静态内容的分离**:JSP技术支持将动态数据(例如数据库查询结果、实时时间等)嵌入到静态HTML文档中。这种设计方法增强了网页的适应性和可维护性。2. **易用性**:开发者可以利用常规的HTML编辑工具来编写静态部分,并通过简化的标签技术将动态内容集成到页面中。3. **跨平台兼容性**:基于Java平台的JSP具有优良的跨操作系统运行能力,能够在多种不同的系统环境中稳定工作。4. **强大的后台支持**:JSP能够通过JavaBean组件访问后端数据库及其他资源,以实现复杂的数据处理逻辑。5. **执行效率高**:JSP页面在初次被请求时会被转换为Servlet,随后的请求可以直接执行编译后的Servlet代码,从而提升了服务响应的效率。#### 二、JSP指令的运用JSP指令用于设定整个JSP页面的行为规范。这些指令通常放置在页面的顶部,向JSP容器提供处理页面的相关指导信息。##### 主要的指令类型:1. **Page指令**: - **语法结构**:`<%@ page attribute="value" %>` - **功能**:定义整个JSP页面的运行特性,如设定页面编码格式、错误处理机制等。 - **实例**: ...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值