
本文详细介绍了如何在java swing应用中,利用`joptionpane`对话框作为入口,根据用户选择启动一个新的窗体。教程将演示如何在新窗体中实现一个动态更新的数字时钟,并集成开始/停止计时器、以及根据计时器状态改变显示颜色等功能,同时强调swing应用中事件调度线程(edt)的重要性及`javax.swing.timer`的正确使用。
在Java Swing应用程序开发中,我们经常需要通过一个初始的对话框来引导用户进行操作,例如选择进入不同的功能模块。JOptionPane是实现这一目的的强大工具。本教程将引导您完成一个示例,该示例从一个JOptionPane开始,根据用户的选择来启动一个新的Swing窗体,并在新窗体中展示一个带有计时器控制功能的动态时钟。
在构建此类应用时,主要涉及以下几个关键点:
应用程序的入口点是main方法。在这里,我们首先通过JOptionPane向用户提供“设置”和“关闭”两个选项。
import java.awt.EventQueue;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TimerApplication {
private static final String SETTINGS = "Settings";
private static final String CLOSE = "Close";
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”
// 尝试设置系统外观(Look and Feel)
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException |
IllegalAccessException |
InstantiationException |
UnsupportedLookAndFeelException x) {
System.out.println("警告:未能设置系统外观 (已忽略)。");
}
// 在EDT上创建并显示新的计时器窗体
EventQueue.invokeLater(() -> new TimerFrame().buildAndDisplayGui());
} else { // 用户选择了“Close”或关闭了对话框
System.exit(0); // 退出应用程序
}
}
}解释:
新窗体 (TimerFrame,这里为了避免与javax.swing.Timer冲突,使用TimerFrame作为类名) 将包含一个显示时间的JLabel和控制计时器的“开始”/“停止”按钮。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer; // 注意这里是javax.swing.Timer
class TimerFrame {
private JButton startButton;
private JButton stopButton;
private JFrame frame;
private JLabel theWatch;
private Timer timer; // Swing Timer
public TimerFrame() {
// 初始化Swing Timer,每1000毫秒(1秒)触发一次
timer = new Timer(1000, this::updateTimer);
// 第一次触发立即执行,然后每秒执行
timer.setInitialDelay(0);
}
public void buildAndDisplayGui() {
frame = new JFrame("计时器应用");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口时退出应用
// 创建显示时间的标签
theWatch = new JLabel(getCurrentTime(), SwingConstants.CENTER);
theWatch.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30)); // 添加边距
theWatch.setForeground(Color.red); // 初始颜色为红色
theWatch.setToolTipText("计时器当前已停止。"); // 停止时的提示信息
frame.add(theWatch, BorderLayout.CENTER); // 将标签添加到窗体中央
frame.add(createButtons(), BorderLayout.PAGE_END); // 将按钮面板添加到窗体底部
frame.pack(); // 根据组件的首选大小调整窗体大小
frame.setLocationByPlatform(true); // 窗体位置由平台决定
frame.setVisible(true); // 显示窗体
}
private JPanel createButtons() {
JPanel panel = new JPanel();
startButton = new JButton("开始");
startButton.setMnemonic(KeyEvent.VK_A); // 设置助记符 (Alt+A)
startButton.setToolTipText("启动计时器。");
startButton.addActionListener(this::startTimer); // 绑定启动事件
panel.add(startButton);
stopButton = new JButton("停止");
stopButton.setMnemonic(KeyEvent.VK_O); // 设置助记符 (Alt+O)
stopButton.setToolTipText("停止计时器。");
stopButton.addActionListener(this::stopTimer); // 绑定停止事件
stopButton.setEnabled(false); // 初始时停止按钮禁用
panel.add(stopButton);
return panel;
}
// 获取当前时间并格式化
private String getCurrentTime() {
return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH));
}
// 启动计时器
private void startTimer(ActionEvent event) {
theWatch.setToolTipText(null); // 清除提示信息
theWatch.setForeground(Color.black); // 启动时颜色变为黑色
startButton.setEnabled(false); // 禁用开始按钮
timer.start(); // 启动Swing Timer
stopButton.setEnabled(true); // 启用停止按钮
}
// 停止计时器
private void stopTimer(ActionEvent event) {
timer.stop(); // 停止Swing Timer
theWatch.setForeground(Color.red); // 停止时颜色变为红色
theWatch.setToolTipText("计时器当前已停止。"); // 设置停止提示信息
startButton.setEnabled(true); // 启用开始按钮
stopButton.setEnabled(false); // 禁用停止按钮
}
// 更新时间标签
private void updateTimer(ActionEvent event) {
theWatch.setText(getCurrentTime());
}
}为了运行上述代码,您需要将TimerApplication.java和TimerFrame.java(或将TimerFrame作为内部类)放在同一个项目中。
// TimerApplication.java
import java.awt.EventQueue;
import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TimerApplication {
private static final String SETTINGS = "Settings";
private static final String CLOSE = "Close";
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) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException |
IllegalAccessException |
InstantiationException |
UnsupportedLookAndFeelException x) {
System.out.println("警告:未能设置系统外观 (已忽略)。");
}
EventQueue.invokeLater(() -> new TimerFrame().buildAndDisplayGui());
} else {
System.exit(0);
}
}
}
// TimerFrame.java (可以作为单独文件或 TimerApplication 的内部类)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
class TimerFrame {
private JButton startButton;
private JButton stopButton;
private JFrame frame;
private JLabel theWatch;
private Timer timer;
public TimerFrame() {
timer = new Timer(1000, this::updateTimer);
timer.setInitialDelay(0); // 确保计时器启动后立即更新一次
}
public void buildAndDisplayGui() {
frame = new JFrame("计时器应用");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theWatch = new JLabel(getCurrentTime(), SwingConstants.CENTER);
theWatch.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
theWatch.setForeground(Color.red);
theWatch.setToolTipText("计时器当前已停止。");
frame.add(theWatch, BorderLayout.CENTER);
frame.add(createButtons(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtons() {
JPanel panel = new JPanel();
startButton = new JButton("开始");
startButton.setMnemonic(KeyEvent.VK_A);
startButton.setToolTipText("启动计时器。");
startButton.addActionListener(this::startTimer);
panel.add(startButton);
stopButton = new JButton("停止");
stopButton.setMnemonic(KeyEvent.VK_O);
stopButton.setToolTipText("停止计时器。");
stopButton.addActionListener(this::stopTimer);
stopButton.setEnabled(false);
panel.add(stopButton);
return panel;
}
private String getCurrentTime() {
return LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss", Locale.ENGLISH));
}
private void startTimer(ActionEvent event) {
theWatch.setToolTipText(null);
theWatch.setForeground(Color.black);
startButton.setEnabled(false);
timer.start();
stopButton.setEnabled(true);
}
private void stopTimer(ActionEvent event) {
timer.stop();
theWatch.setForeground(Color.red);
theWatch.setToolTipText("计时器当前已停止。");
startButton.setEnabled(true);
stopButton.setEnabled(false);
}
private void updateTimer(ActionEvent event) {
theWatch.setText(getCurrentTime());
}
}本教程演示了如何利用JOptionPane作为应用程序的启动入口,并根据用户选择动态地创建和显示一个新的Swing窗体。通过集成javax.swing.Timer和现代日期时间API,我们成功实现了一个带有开始/停止功能的动态数字时钟。理解并正确应用EDT原则是开发健壮Swing应用程序的关键。
以上就是从JOptionPane启动新Swing窗口:构建动态计时器应用的详细内容,更多请关注php中文网其它相关文章!
Windows激活工具是正版认证的激活工具,永久激活,一键解决windows许可证即将过期。可激活win7系统、win8.1系统、win10系统、win11系统。下载后先看完视频激活教程,再进行操作,100%激活成功。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号