Java 当一个子面板中的timetask计划启动时,UI冻结
我有一个多面板框架,用于不同的显示目的,其中一个用于显示定时任务执行的时间倒计时字符串:Java 当一个子面板中的timetask计划启动时,UI冻结,java,multithreading,swing,Java,Multithreading,Swing,我有一个多面板框架,用于不同的显示目的,其中一个用于显示定时任务执行的时间倒计时字符串: private class TimerPad extends JPanel { private int timeLeft = 60; private String prefix = "Time Left: "; TimerPad() { setDoubleBuffered(true); } public void start() {
private class TimerPad extends JPanel {
private int timeLeft = 60;
private String prefix = "Time Left: ";
TimerPad() {
setDoubleBuffered(true);
}
public void start() {
new java.util.Timer().schedule(new TimerTask() {
@Override
public void run() {
if (gameStatus == BoardStatus.JUDGING) {
this.cancel();
} else if (timeLeft == 0) {
submitCards(cardsSouth);
this.cancel();
} else {
timeLeft--;
repaint();
}
}
}, 1000, 1000);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
.....
}
@Override
public Dimension getPreferredSize() {
return new Dimension(240, 50);
}
}
此面板添加到主框架中,当外部请求时,会触发其start()方法。现在,计时器似乎只有在正常的60秒过后才能正常工作,但当我使用按钮(即提交)尝试提前取消任务时,所有GUI都被冻结。。。我试图为任务包装一个运行程序,但结果是相同的…您应该使用而不是通用的
java.util.Timer
,以避免违反swing线程规则。在这种情况下,没有太多组件更新,因此两个计时器都应该起作用(我刚刚尝试过)。它看起来像是在计时器停止(按钮动作)后,所有者帧失去焦点(而不是说冻结),并且由于我在那里打开了另一个主模式帧,我无法找回计时器所有者……在这种情况下没有太多组件更新,因此,这两个计时器都应该起作用
——它与要更新的组件数量无关。应使用摆动计时器在EDT上更新摆动组件。是的,其他计时器大部分时间都可以工作,但是你会遇到随机问题,因为你不能复制随机问题,你会浪费大量的时间来调试问题。阅读上的Swing教程。请看一下这个精彩的答案,由@trashgood创建的。使用javax.swing.Timer
,所有更新都将在EDT
上进行。对于您正在使用的java.util.Timer
,程序员有责任将所有与GUI相关的更新放在EDT
上,而您在任何地方都没有这样做。此外,Swing
组件默认使用,在JPanel
实例上没有理由调用setDoubleBuffered(true)
,至少:-)