首页 > Java > java教程 > 正文

Java Swing:利用JOptionPane启动动态计时器应用界面

聖光之護
发布: 2025-11-21 11:44:02
原创
869人浏览过

Java Swing:利用JOptionPane启动动态计时器应用界面

本文详细介绍了如何利用java swing的`joptionpane`组件作为应用程序的入口,根据用户选择(例如“设置”选项)来启动一个新的`jframe`窗口。该新窗口将展示一个实时更新的数字时钟,并允许用户控制计时器的启停以及显示文本的颜色,通过`javax.swing.timer`实现时间动态更新,并遵循swing的事件调度线程(edt)最佳实践。

在Java Swing应用程序开发中,我们经常需要提供一个初始的用户交互点,例如一个简单的对话框,让用户选择进入不同的功能模块。JOptionPane是实现这一目的的理想选择。本文将指导您如何从JOptionPane启动一个功能更丰富的JFrame,其中包含一个动态更新的计时器。

一、使用JOptionPane作为应用入口

JOptionPane可以在非事件调度线程(EDT)中安全地调用,因此通常在main方法中进行初始化。showOptionDialog方法允许我们自定义对话框的选项按钮。当用户点击其中一个选项时,该方法会返回一个整数值,代表被点击按钮的索引或预定义的常量。

在我们的场景中,我们需要一个包含“Settings”和“Close”两个选项的对话框。当用户选择“Settings”时,将启动一个新的JFrame。

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class DynamicClockApp {
    private static final String SETTINGS = "Settings";
    private static final String CLOSE = "Close";

    private JButton startButton;
    private JButton stopButton;
    private JFrame frame;
    private JLabel timeLabel;
    private Timer swingTimer; // 使用javax.swing.Timer

    public DynamicClockApp() {
        // 初始化Swing Timer,每秒触发一次ActionEvent
        // setDelay(0) 会在第一次触发后立即执行,然后按延迟时间继续
        swingTimer = new Timer(1000, this::updateTimer);
        swingTimer.setInitialDelay(0); // 确保计时器立即开始更新
    }

    /**
     * 构建并显示主应用程序界面(JFrame)。
     */
    private void buildAndDisplayGui() {
        frame = new JFrame("动态计时器应用");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出程序

        // 创建显示时间的标签
        timeLabel = new JLabel(getCurrentTime(), SwingConstants.CENTER);
        timeLabel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
        timeLabel.setForeground(Color.RED); // 初始颜色为红色
        timeLabel.setFont(new Font("SansSerif", Font.BOLD, 48)); // 设置字体大小
        timeLabel.setToolTipText("计时器当前已停止。");

        frame.add(timeLabel, BorderLayout.CENTER); // 将标签添加到窗口中央
        frame.add(createControlButtons(), BorderLayout.PAGE_END); // 将控制按钮添加到窗口底部

        frame.pack(); // 调整窗口大小以适应其组件
        frame.setLocationByPlatform(true); // 让操作系统决定窗口位置
        frame.setVisible(true); // 显示窗口
    }

    /**
     * 创建并返回包含控制按钮的面板。
     */
    private JPanel createControlButtons() {
        JPanel panel = new JPanel();
        startButton = new JButton("启动");
        startButton.setMnemonic(KeyEvent.VK_S); // 设置快捷键 Alt+S
        startButton.setToolTipText("启动计时器。");
        startButton.addActionListener(this::startTimer); // 添加启动事件监听
        panel.add(startButton);

        stopButton = new JButton("停止");
        stopButton.setMnemonic(KeyEvent.VK_P); // 设置快捷键 Alt+P
        stopButton.setToolTipText("停止计时器。");
        stopButton.addActionListener(this::stopTimer); // 添加停止事件监听
        stopButton.setEnabled(false); // 初始状态下停止按钮禁用
        panel.add(stopButton);

        return panel;
    }

    /**
     * 获取当前时间,并格式化为 HH:mm:ss。
     */
    private String getCurrentTime() {
        return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH));
    }

    /**
     * 启动计时器。
     */
    private void startTimer(ActionEvent event) {
        timeLabel.setToolTipText(null);
        timeLabel.setForeground(Color.BLACK); // 启动时颜色变为黑色
        startButton.setEnabled(false); // 启动按钮禁用
        swingTimer.start(); // 启动Swing计时器
        stopButton.setEnabled(true); // 停止按钮启用
    }

    /**
     * 停止计时器。
     */
    private void stopTimer(ActionEvent event) {
        swingTimer.stop(); // 停止Swing计时器
        timeLabel.setForeground(Color.RED); // 停止时颜色变为红色
        timeLabel.setToolTipText("计时器当前已停止。");
        startButton.setEnabled(true); // 启动按钮启用
        stopButton.setEnabled(false); // 停止按钮禁用
    }

    /**
     * 更新时间标签的文本。
     */
    private void updateTimer(ActionEvent event) {
        timeLabel.setText(getCurrentTime());
    }

    public static void main(String[] args) {
        // 显示选项对话框
        int choice = JOptionPane.showOptionDialog(null,
                "请选择操作:",
                "选项对话框",
                JOptionPane.YES_NO_OPTION, // 只有两个选项
                JOptionPane.QUESTION_MESSAGE,
                null,
                new String[]{SETTINGS, CLOSE}, // 自定义按钮文本
                SETTINGS); // 默认选中按钮

        // 根据用户选择进行处理
        if (choice == JOptionPane.YES_OPTION) { // 如果选择了“Settings”
            // 尝试设置系统默认外观,以使界面更符合操作系统风格
            String systemLookAndFeel = UIManager.getSystemLookAndFeelClassName();
            try {
                UIManager.setLookAndFeel(systemLookAndFeel);
            } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException x) {
                System.out.println("警告 (已忽略): 无法设置系统外观。");
            }

            // 在事件调度线程中构建并显示GUI
            EventQueue.invokeLater(() -> new DynamicClockApp().buildAndDisplayGui());
        } else { // 如果选择了“Close”或关闭了对话框
            System.exit(0); // 退出应用程序
        }
    }
}
登录后复制

二、构建动态计时器界面

当用户在JOptionPane中选择“Settings”后,我们将创建一个新的JFrame来承载动态计时器。

立即学习Java免费学习笔记(深入)”;

1. JFrame的基本设置

JFrame是Swing的顶级容器,用于创建应用程序主窗口。

360智图
360智图

AI驱动的图片版权查询平台

360智图 143
查看详情 360智图
  • frame = new JFrame("动态计时器应用");:创建标题为“动态计时器应用”的窗口。
  • frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);:设置当用户关闭窗口时,应用程序随之退出。
  • frame.pack();:根据组件的首选大小调整窗口尺寸。
  • frame.setLocationByPlatform(true);:让操作系统决定窗口的初始位置。
  • frame.setVisible(true);:使窗口可见。

2. 时间显示标签(JLabel)

JLabel用于显示文本信息。

  • timeLabel = new JLabel(getCurrentTime(), SwingConstants.CENTER);:创建一个标签,初始显示当前时间,并居中对齐。
  • timeLabel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));:为标签添加边距。
  • timeLabel.setForeground(Color.RED);:设置文本颜色,初始为红色,表示计时器停止。
  • timeLabel.setFont(new Font("SansSerif", Font.BOLD, 48));:设置字体样式和大小,使其更醒目。
  • timeLabel.setToolTipText("计时器当前已停止。");:当鼠标悬停时显示提示信息。

3. Swing计时器(javax.swing.Timer)

为了实现每秒更新时间的功能,我们使用javax.swing.Timer。

  • swingTimer = new Timer(1000, this::updateTimer);:创建一个Timer实例,每1000毫秒(即1秒)触发一次ActionEvent。this::updateTimer是Java 8的方法引用,它简洁地指定了当计时器触发时要执行的方法。
  • swingTimer.setInitialDelay(0);:设置首次触发的延迟为0,确保计时器启动后立即更新一次时间。
  • swingTimer.start();和swingTimer.stop();:分别用于启动和停止计时器。

4. 控制按钮(JButton)

我们添加“启动”和“停止”按钮来控制计时器的状态。

  • startButton = new JButton("启动");和stopButton = new JButton("停止");:创建按钮。
  • startButton.addActionListener(this::startTimer);和stopButton.addActionListener(this::stopTimer);:为按钮添加事件监听器,同样使用方法引用。
  • 按钮的setEnabled(true/false)方法用于控制按钮的可用状态,以提供更好的用户体验。例如,计时器运行时“启动”按钮应禁用,而“停止”按钮应启用。
  • setMnemonic(KeyEvent.VK_S);:设置助记符(快捷键),用户可以通过Alt+S(Windows/Linux)或Ctrl+S(macOS)来触发按钮。

三、关键注意事项与最佳实践

  1. 事件调度线程 (EDT):Swing组件的创建和更新必须在事件调度线程上进行。EventQueue.invokeLater(() -> new DynamicClockApp().buildAndDisplayGui());确保了在main方法中启动的GUI操作被正确地调度到EDT上执行,从而避免潜在的线程安全问题和UI冻结。
  2. javax.swing.Timer vs. java.util.Timer:在Swing应用中,始终使用javax.swing.Timer。它专门设计用于与Swing的EDT集成,其回调总是在EDT上执行,无需额外的线程处理。而java.util.Timer在单独的线程中运行,如果直接用于更新Swing组件,可能会导致线程安全问题。
  3. 日期时间API:使用java.time包(从Java 8开始引入)来处理日期和时间,例如LocalTime.now()获取当前时间,DateTimeFormatter进行格式化,这比旧的java.util.Date和java.util.Calendar更加现代和易用。
  4. 外观和感觉 (Look and Feel):UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());可以尝试将应用程序的界面设置为与操作系统默认风格一致,提升用户体验。
  5. 布局管理器:JFrame的默认布局管理器是BorderLayout,它将容器分为东、南、西、北、中五个区域。示例中将timeLabel放在BorderLayout.CENTER,将按钮面板放在BorderLayout.PAGE_END(底部)。

四、总结

通过本文,我们学习了如何利用JOptionPane作为Java Swing应用程序的初始交互点,并根据用户选择动态启动一个功能丰富的JFrame。这个JFrame展示了一个实时更新的数字时钟,并通过javax.swing.Timer实现了每秒更新,同时提供了启动和停止计时器的功能,并根据状态改变显示文本的颜色。整个过程遵循了Swing的EDT最佳实践,确保了应用的稳定性和响应性。这些技术是构建用户友好且响应迅速的Swing应用程序的基础。

以上就是Java Swing:利用JOptionPane启动动态计时器应用界面的详细内容,更多请关注php中文网其它相关文章!

Windows激活工具
Windows激活工具

Windows激活工具是正版认证的激活工具,永久激活,一键解决windows许可证即将过期。可激活win7系统、win8.1系统、win10系统、win11系统。下载后先看完视频激活教程,再进行操作,100%激活成功。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号