讲师中心 微信公众号
AI工具推荐 视频效率加速

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

云芳同学_3596

云芳同学_3596

发布时间:2025-11-21 11:44:02

|

926人浏览过

|

来源于php中文网

原创

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免费学习笔记(深入)”;

直播间话术巡检-windows
直播间话术巡检-windows

直播话术巡检系统(Windows版) — 实时语音转写、关键词检测、场景自动切换、告警推送、大屏可视化。支持 Windows VB-Cable 虚拟声卡音频采集,阿里云 ASR 实时识别。一键启动脚本,自动安装环境。

下载

1. JFrame的基本设置

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

  • 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应用程序的基础。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6124

2023.10.24

java中calendar类的用法
java中calendar类的用法

Java Video类是JavaFX库中的一个类,用于创建和操作视频对象。它提供了方法来加载、播放、暂停、停止和控制视频的音量、速度和循环等属性。想了解更多Java中类的相关内容,可以阅读本专题下面的文章。

1955

2024.02.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4318

2023.08.10

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3279

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2838

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

1488

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2599

2023.08.02

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

3310

2023.08.08

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

20

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn