Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.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 调用器未按预期工作(JButton从未释放)_Java_Multithreading_Swing_Event Dispatch Thread_Invokelater - Fatal编程技术网

Java 调用器未按预期工作(JButton从未释放)

Java 调用器未按预期工作(JButton从未释放),java,multithreading,swing,event-dispatch-thread,invokelater,Java,Multithreading,Swing,Event Dispatch Thread,Invokelater,我有: 带有按钮的JFrame。 用于显示动画的单独画布子类。 我希望,在按下JButton时,会出现一个新的JFrame,显示Canvas子类的动画 我现在面临的问题是,新的JFrame出现了,但是它没有机会渲染任何东西,并且主框架上的JButton保持按下状态。我认为这背后的逻辑是EDT还没有完成它的工作,例如显示JButton已发布,因此没有机会运行动画方法并最终陷入死锁。 在过去我通过创建一个新线程来完成这项工作时,这个逻辑对我很好,但是最近我了解了更多关于Java、线程和Swing

我有:

  • 带有按钮的JFrame。
  • 用于显示动画的单独画布子类。
我希望,在按下JButton时,会出现一个新的JFrame,显示Canvas子类的动画

我现在面临的问题是,新的JFrame出现了,但是它没有机会渲染任何东西,并且主框架上的JButton保持按下状态。我认为这背后的逻辑是EDT还没有完成它的工作,例如显示JButton已发布,因此没有机会运行动画方法并最终陷入死锁。

在过去我通过创建一个新线程来完成这项工作时,这个逻辑对我很好,但是最近我了解了更多关于Java、线程和Swing的知识,我知道所有与Swing相关的事件都必须在一个线程上处理:EDT

这让我感到困惑,因为我以前是如何让它工作的,但这让我相信使用invokeLater将有助于解决这个问题;由于使JFrame可见并显示动画的工作将被放置在队列的末尾,从而允许JButton取消释放等。然而,我没有运气;我完全误解了什么吗?

谢谢

(也请不要对我使用Canvas类而不是JPanel发表评论,我有我的理由)

示例代码:

Test5(带main方法的类)

画布类(画布子类)


您实际上在EDT中调用了它,但它在
canvas.runAnimation()中被阻止

将要执行的代码放在一个单独的
线程中(您可以在其中调用sleep),但在
SwingUtilities.invokeLater()中调用
repaint()

或者更好地定义一个
javax.swing.Timer
并在计时器的
actionPerformed()中调用
runAnimation()

更新:

  int delay = 20; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          canvasInstance.randomise();
          canvasInstance.repaint();
      }
  };
  new Timer(delay, taskPerformer).start();

要被调用而不是runAnimation()

您实际上在EDT中调用了它,但它在
canvas.runAnimation()中被阻止

将要执行的代码放在一个单独的
线程中(您可以在其中调用sleep),但在
SwingUtilities.invokeLater()中调用
repaint()

或者更好地定义一个
javax.swing.Timer
并在计时器的
actionPerformed()中调用
runAnimation()

更新:

  int delay = 20; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          canvasInstance.randomise();
          canvasInstance.repaint();
      }
  };
  new Timer(delay, taskPerformer).start();

要被调用而不是runAnimation()

您实际上在EDT中调用了它,但它在
canvas.runAnimation()中被阻止

将要执行的代码放在一个单独的
线程中(您可以在其中调用sleep),但在
SwingUtilities.invokeLater()中调用
repaint()

或者更好地定义一个
javax.swing.Timer
并在计时器的
actionPerformed()中调用
runAnimation()

更新:

  int delay = 20; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          canvasInstance.randomise();
          canvasInstance.repaint();
      }
  };
  new Timer(delay, taskPerformer).start();

要被调用而不是runAnimation()

您实际上在EDT中调用了它,但它在
canvas.runAnimation()中被阻止

将要执行的代码放在一个单独的
线程中(您可以在其中调用sleep),但在
SwingUtilities.invokeLater()中调用
repaint()

或者更好地定义一个
javax.swing.Timer
并在计时器的
actionPerformed()中调用
runAnimation()

更新:

  int delay = 20; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          canvasInstance.randomise();
          canvasInstance.repaint();
      }
  };
  new Timer(delay, taskPerformer).start();


要调用而不是runAnimation()

请向我解释为什么它被阻止?我还以为你只应该有一个线程的摆动组件?非常感谢您的回答,我非常感谢您的详细介绍,因为我不太了解。线程正在runAnimation()中忙于执行while(true)块,因此它没有机会重新绘制内容(重新绘制必须在EDT中执行)。重新绘制会怎么样?按钮还是画布?我不太明白你的建议是什么,你是否可以发布一个代码答案?重新绘制任何组件,处理事件等。EDT正在忙。Brilliant,我真的很感谢你的帮助,我知道EDT正在忙,但我还是不明白使用定时器是如何让我们摆脱这个问题的?你能解释一下为什么它被阻止了吗?我还以为你只应该有一个线程的摆动组件?非常感谢您的回答,我非常感谢您的详细介绍,因为我不太了解。线程正在runAnimation()中忙于执行while(true)块,因此它没有机会重新绘制内容(重新绘制必须在EDT中执行)。重新绘制会怎么样?按钮还是画布?我不太明白你的建议是什么,你是否可以发布一个代码答案?重新绘制任何组件,处理事件等。EDT正在忙。Brilliant,我真的很感谢你的帮助,我知道EDT正在忙,但我还是不明白使用定时器是如何让我们摆脱这个问题的?你能解释一下为什么它被阻止了吗?我还以为你只应该有一个线程的摆动组件?非常感谢您的回答,我非常感谢您的详细介绍,因为我不太了解。线程正在runAnimation()中忙于执行while(true)块,因此它没有机会重新绘制内容(重新绘制必须在EDT中执行)。重新绘制会怎么样?按钮还是画布?我不太明白你的建议是什么,你是否可以发布一个代码答案?重新绘制任何组件,处理事件等。EDT正在忙。Brilliant,我真的很感谢你的帮助,我知道EDT正在忙,但我还是不明白使用定时器是如何让我们摆脱这个问题的?你能解释一下为什么它被阻止了吗?我还以为你只应该有一个线程的摆动组件?非常感谢您的回答,我非常感谢您的详细说明,因为我不太明白。线程正在忙于执行while(true)bloc