【问题标题】:How do I make this java for loop pause for 1/2 a second between each iteration?如何在每次迭代之间使这个 java for 循环暂停 1/2 秒?
【发布时间】:2025-11-27 06:25:02
【问题描述】:
private class MultipleGensListener implements ActionListener
   {
    public void actionPerformed(ActionEvent e)
        {
            for(int i = 0; i < 25; i++)
            {
                game.runSimulationOneGen();
                changeGrid();
            }
        }
   }

//这是循环。 changeGrid 方法在 GUI 上显示游戏网格,但 // 只有第 25 次迭代在屏幕上可见。我希望每个人都成为 // 在循环继续之前大约半秒可见。 // 我在这里看到了一些与我要问的问题非常接近的问题, // 但我真的不明白如何将它应用到我的程序中.. // 感谢您的帮助。

【问题讨论】:

    标签: java swing loops timer delay


    【解决方案1】:

    如果模拟执行的代码很快并且不会消耗太多 CPU 和时间,那么可以考虑使用 Swing Timer 来执行循环和延迟。否则,您将需要使用后台线程,例如可以使用 SwingWorker 对象。

    例如如果同时使用 Swing Timer 和 SwingWorker:

       private class MultipleGensListener implements ActionListener {
          protected static final int MAX_INDEX = 25;
    
          public void actionPerformed(ActionEvent e) {
             int timerDelay = 500; // ms delay
             new Timer(timerDelay, new ActionListener() {
                int index = 0;
    
                public void actionPerformed(ActionEvent e) {
                   if (index < MAX_INDEX) { // loop only MAX_INDEX times
                      index++;
    
                      // create the SwingWorker and execute it
                      new SwingWorker<Void, Void>() {
                         @Override
                         protected Void doInBackground() throws Exception {
                            game.runSimulationOneGen(); // this is done in background thread.
                            return null;
                         }
    
                         @Override
                         protected void done() {
                            changeGrid(); // this is called on EDT after background thread done.
                         }
                      }.execute(); // execute the SwingWorker
                   } else {
                      ((Timer) e.getSource()).stop(); // stop the timer
                   }
                }
             }).start(); // start the Swing timer
          }
       }
    

    【讨论】:

    • @hovercraft,嗯,你是对的……没想到 +1
    • @Hovercraft Full Of Eels 没有别的东西只同意这一点,以避免 Thread.sleep(int inside ActionListener) +1, uuuupssss 这两个帖子丢失了.... :-)
    • 哇,你们真快!我是java新手,很抱歉我的无知。但是你能给我更多的细节或链接到我可以阅读使用它的地方吗?谢谢!
    • @Bryan:Swing 教程是你需要去的地方。请查看:How to use Swing TimersConcurrency in Swing
    • 使用 SwingwWorker() 找不到在线符号。我需要为此导入什么?
    【解决方案2】:

    永远不要阻塞 GUI 事件线程

    您可以为此使用计时器并让它只触发 25 次

    final Timer t = new Timer(500,null);
    t.addActionListener(new ActionListener(){
         int i=0;
         public void actionPerformed(ActionEvent e){
             game.runSimulationOneGen();//run 1 iteration per tick
             changeGrid();
             if(i>25){t.stop();}
             i++;
         }
    });
    t.setRepeats(true);
    t.start();
    

    顺便说一句,只显示最后一次迭代的原因是 gui 更新(重绘)是在一个单独的事件中完成的,但是要让另一个事件触发你需要从你没有的侦听器方法返回

    我展示的 Timer 是一个更精细的迭代,它允许其他事件在迭代之间运行,从而允许 gui 显示更改

    【讨论】:

    • 谢谢,这对我来说比气垫船更容易理解。但是当调用计时器“t”时,我会收到一个错误
    • 我已经编辑了代码,所以它可以在我的机器上编译(这是直接用 SO 编写的代码的问题;))
    • @ratchet 怪胎仍然不适合我。我不知道为什么。就像编译器不将 t 识别为计时器,并且希望我在每个实例中都重新声明它。感谢您的帮助。
    • @Brian 小心 java.util.Timerjavax.swing.Timer
    • @Brian 如果它很快,那么这个解决方案会更好。如果您有import java.util.*import javax.swing.*,如果您在代码中的某处使用Timer,您将收到一些错误消息。我不确定到底是哪条消息。为了安全起见,您可以输入final javax.swing.Timer t = new javax.swing.Timer(500, null);。否则,您会收到什么错误消息?
    【解决方案3】:

    查看我的帖子,显示这两种方法java.swing.Timer#setDelay(int)

    Thread.sleep(int)的正确用法

    java wait cursor display problem

    【讨论】: