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

时间:2017-11-22 18:23:40

标签: java swing user-interface event-dispatch-thread swingutilities

我有一个应该更新程序数据和GUI的while循环,但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
        }   
    }
}

我尝试过使用SwingUtilities.invokeLater()Swing Timer,但我并没有真正理解SwingUtilities.invokeLater()如何工作或如何在EDT上使用Swing Timer。我的问题是如何在while循环中与程序数据同时进行GUI更新?

以下是我尝试的invokeLater()代码:

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();
    }
});

1 个答案:

答案 0 :(得分:1)

  1. 看起来你的while循环在EDT上,这就是为什么它在执行时冻结GUI。 永远不要在EDT上致电Thread.sleep

  2. 所有SwingUtilities.invokeLater都会将Runnable置于队列中,以便EDT在某个时间点运行它。 SwingUtilities.invokeLater应该从非EDT线程运行。不需要使用SwingUtilities.invokeLater启动Swing Timer。您可以直接从EDT开始。

  3. Swing计时器使用一个单独的线程,该线程在EDT线程上运行并定期调用指定的ActionListener

  4. 您可以使用swing计时器替换while循环(假设间隔为1秒)并在game.getCompTotal() < 17呼叫中检查actionPerformed条件。