问题
I have a while loop that is supposed to update the program data and the GUI, but the GUI part freezes until the while loop is done executing.
Here is my code:
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
}
}
}
I have tried using SwingUtilities.invokeLater()
and a Swing Timer
but I do not really get how SwingUtilities.invokeLater()
works or how to use a Swing Timer
on the EDT. My question is how can I have the GUI update at the same time as the program data in the while loop?
Here is my attempted invokeLater()
code:
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:
Looks like your while loop is on EDT and thats why it freezes GUI while it is executing. Never call
Thread.sleep
on EDT.All
SwingUtilities.invokeLater
does is puts theRunnable
on a queue so that EDT would run it at some point in time. TheSwingUtilities.invokeLater
should be run from a non EDT thread. Starting Swing Timer withSwingUtilities.invokeLater
is not required. You can start it directly from EDT.Swing timer uses a separate thread that runs and periodically calls specified
ActionListener
on EDT thread.
You can replace the while
loop with swing timer (lets say with 1sec interval) and check game.getCompTotal() < 17
condition inside its actionPerformed
call.
来源:https://stackoverflow.com/questions/47441539/updating-swing-gui-with-while-loop-and-delay