Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.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 使用while循环和延迟更新Swing GUI_Java_Swing_User Interface_Event Dispatch Thread_Swingutilities - Fatal编程技术网

Java 使用while循环和延迟更新Swing GUI

Java 使用while循环和延迟更新Swing GUI,java,swing,user-interface,event-dispatch-thread,swingutilities,Java,Swing,User Interface,Event Dispatch Thread,Swingutilities,我有一个while循环,它应该更新程序数据和GUI,但是GUI部分会冻结,直到while循环执行完毕 这是我的密码: while(game.getCompTotal() < 17) { try { Thread.sleep(2500); } catch (Exception ex){ ex.printStackTrace(); } game.compHit(); // Program data update

我有一个while循环,它应该更新程序数据和GUI,但是GUI部分会冻结,直到while循环执行完毕

这是我的密码:

while(game.getCompTotal() < 17) {
    try {
        Thread.sleep(2500);
    } catch (Exception ex){
        ex.printStackTrace();
    }
    game.compHit();           // Program data update

    updateCardPanels();       // GUI update -- Does not update until the while loop finishes.

    if(game.checkCompBust()){
        if(JOptionPane.showConfirmDialog(this, "Dealer Busted.  Play again?") == JOptionPane.YES_OPTION){
            init();           // Reset
        }   
    }
}
看起来您的while循环在EDT上,这就是它在执行时冻结GUI的原因。不要在EDT上调用Thread.sleep

invokeLater所做的就是将Runnable放在队列中,以便EDT在某个时间点运行它。SwingUtilities.invokeLater应该从非EDT线程运行。不需要使用SwingUtilities.invokeLater启动Swing计时器。您可以直接从EDT开始

Swing timer使用单独的线程运行并定期调用EDT线程上指定的ActionListener


您可以将while循环替换为swing timer,比如1sec interval,并在其actionPerformed调用中检查game.getCompTotal<17条件。

swing timer可以用作伪循环,在计时器的每个刻度上,您都会更新某种状态变量,确定退出条件是否已实现,并更新剩余状态,就像您通常在循环中以其他方式进行更新一样。好的,我想我已经成功了。现在我有一个不同的问题:我如何在继续程序之前等待计时器完成?让计时器在完成后调用一个方法,即满足退出条件
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        Timer t = new Timer(100, new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                updateCardPanels();
            }
        });
        t.setInitialDelay(0);
        t.start();
    }
});