Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当一个子面板中的timetask计划启动时,UI冻结_Java_Multithreading_Swing - Fatal编程技术网

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)
,至少:-)