0

0

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

聖光之護

聖光之護

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

|

906人浏览过

|

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

皮卡智能
皮卡智能

AI驱动高效视觉设计平台

下载

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

相关文章

Windows激活工具
Windows激活工具

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

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

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

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

1566

2023.10.24

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

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

325

2024.02.29

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

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

765

2023.08.10

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

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

1496

2023.07.26

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

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

1169

2023.07.27

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

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

835

2023.08.01

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

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

462

2023.08.02

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

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

2361

2023.08.08

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.5万人学习

Git 教程
Git 教程

共21课时 | 4.1万人学习

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

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