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。
- 用于显示动画的单独画布子类。
我现在面临的问题是,新的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