1

好的,我正在运行模拟。我已经在我的模拟 GUI 上实现了两个 JButton,它们是 actionListeners。我想要的是让整个模拟在我按下暂停按钮时暂停,如果我按下恢复按钮则恢复。

有多个线程正在运行,我尝试获取每个线程并在单击暂停按钮时调用它们的 wait() 方法,但我没有成功。

因此,我需要一些关于如何做到这一点的建议。我将 Swing 用于 GUI,监听器工作正常。我确实尝试在 View 类(使用 MVC 模式)的当前线程上调用 sleep() 和 wait() 只是为了看看发生了什么,但这会导致整个应用程序崩溃。

有任何想法吗?

4

4 回答 4

3

您需要为模拟线程提供额外的逻辑,该逻辑将接受来自控制(GUI)线程的“信号”并等待下一个控制信号恢复执行。

例如,您可以volatile boolean isPaused在模拟线程中使用实例字段。将其设置为 true/false 以暂停/恢复模拟线程。在仿真线程中实现相应的逻辑:

public void run() {
    while (true) {
        simulate();
        while (isPaused) {
            Thread.sleep(100);
        }
    }
}
于 2012-12-03T19:45:08.937 回答
2

如果动画使用 Swing Timer,简单的答案是调用stop().

我强烈建议使用Timerfor 动画,因为它可以确保在 EDT 上执行操作。

于 2012-12-04T02:08:01.577 回答
0

我认为您可以创建一个ThreadGroup来存储所有线程,然后尝试使用

ThreadGroup threadGroup = Thread.currentThread( ).getThreadGroup( );

顺便说一句,ExecutorService也是一个不错的选择。

于 2012-12-03T19:40:06.400 回答
0

使用共享对象在两个类之间进行通信。然后让您的 gui 在单击按钮时设置状态对象的值,并在再次单击按钮时再次更改它。这是一些示例代码:

public class Simulation implements Runnable {
  private State myState = null;

  public Simulation(State myState) {
    this.myState = myState;
  }

  public void run() {
    while(myState != null) {
      if (myState.isPaused()) myState.wait();
      // Do other stuff
    }
  }
}

public class MainClass implements ActionListener() {
  private State myState = new MyState();

  private void beginSimulation() {
    Simulation s = new Simulation(this.myState());
    new Thread(s).start();
  }  

  public void actionPerformed(ActionEvent e) {
    if(myState.isPaused()) {
      myState.setPaused(false);
      myState.notify();
    } else {
      myState.setPaused(true);
    }
  }
}

public class MyState() {
  private boolean paused = false;
  public MyState(boolean paused) { this.paused = paused; }
  public boolean getPaused() { return paused; }
  public void setPaused(boolean paused) { this.paused = paused; }
}
于 2012-12-03T19:46:31.213 回答