java在程序运行时保持JPanel中的计时器处于活动状态
我在一个叫做MainFrame的类中创建了一个GUI。GUI的一个JPanel以秒为单位显示当前时间和日期。当用户决定使用GUI分析数据时,它会调用一个处理数据的类。当数据处理发生时,计时器暂停,然后在数据处理结束时恢复。即使程序正在运行,如何让计时器持续运行?计时器是它自己的线程,但我不知道从哪里开始JPanel的线程。 下面是一些代码裁剪
应用程序。java(启动整个GUI的应用程序)
public class App {
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainFrame();
}
});
}
}
大型机(处理JPanel和dataprocess impl的类)
public class MainFrame extends JFrame {
private DataProcess dataProcess = null;
...
...
private StatusPanel statusPanel;
...
...
public MainFrame() {
...
setJMenuBar(createFrameMenu());
initializeVariables();
constructLayout();
createFileChooser();
constructAppWindow();
}
private void initializeVariables() {
this.dataProcess = new DataProcess();
...
this.statusPanel = new StatusPanel();
...
}
private void constructLayout() {
JPanel layoutPanel = new JPanel();
layoutPanel.setLayout(new GridLayout(0, 3));
layoutPanel.add(dataControlsPanel());
setLayout(new BorderLayout());
add(layoutPanel, BorderLayout.CENTER);
add(statusPanel, BorderLayout.PAGE_END);
}
状态面板(显示计时器等的面板)
public class StatusPanel extends JPanel {
private static final long serialVersionUID = 1L;
private JLabel statusLabel;
private JLabel timeLabel;
private Timer timer;
public StatusPanel() {
initializeVariables();
constructLayout();
startTimer();
}
private void constructLayout() {
setLayout(new FlowLayout(FlowLayout.CENTER));
add(statusLabel);// , FlowLayout.CENTER
add(timeLabel);
}
public void startTimer() {
this.timer.start();
}
public void stopTimer() {
this.timer.setRunning(false);
}
private void initializeVariables() {
this.statusLabel = new JLabel();
this.timeLabel = new JLabel();
this.statusLabel.setText(StringConstants.STATUS_PANEL_TEXT);
this.timer = new Timer(timeLabel);
}
}
计时器。java(StatusPanel中使用的计时器)
public class Timer extends Thread {
private boolean isRunning;
private JLabel timeLabel;
private SimpleDateFormat timeFormat;
public Timer(JLabel timeLabel) {
initializeVariables(timeLabel);
}
private void initializeVariables(JLabel timeLabel) {
this.timeLabel = timeLabel;
this.timeFormat = new SimpleDateFormat("HH:mm:ss dd-MM-yyyy");
this.isRunning = true;
}
@Override
public void run() {
while (isRunning) {
Calendar calendar = Calendar.getInstance();
Date currentTime = calendar.getTime();
timeLabel.setText(timeFormat.format(currentTime));
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void setRunning(boolean isRunning) {
this.isRunning = isRunning;
}
}
数据处理是通过使用actionlisteners在dataControlsPanel中完成的
# 1 楼答案
首先,你的计时器应该是
javax.swing.Timer
或“Swing”计时器。这是专门针对Swing事件线程构建的,因此应该避免当前代码显示的许多Swing线程问题,例如:timeLabel.setText(timeFormat.format(currentTime));
这会从后台线程发出Swing调用,这是危险的代码。下一个 处理代码应该进入SwingWorker。当worker执行时,可以通过调用计时器上的stop()
暂停Swing计时器,或者简单地让计时器继续运行。当SwingWorker完成了它的操作(我通常会在SwingWorker中添加一个PropertyChangeListener来监听),监听它的state
属性是否更改为SwingWorker.StateValue.DONE
,调用get()
来提取它所持有的任何数据,更重要的是捕获可能抛出的任何异常例如: