我有:
- 一个带有 JButton 的 JFrame。
- 一个单独的 Canvas 子类来显示动画。
我希望在按下 JButton 时调出一个新的 JFrame,显示 Canvas 子类的动画。
我现在面临的问题是新的 JFrame 出现了,但是它没有机会渲染任何东西,并且主框架上的 JButton 保持按下状态。我认为这背后的逻辑是 EDT 还没有完成它的工作,例如显示 JButton 已释放,因此没有机会运行动画方法并最终陷入死锁。
这个逻辑在过去对我很好,因为我通过创建一个新线程来完成这项工作,但是最近了解了更多关于 Java、线程和 Swing 的知识,我开始知道所有与 Swing 相关的事件都必须在一个线程上处理:EDT .
这让我对我之前如何让它工作感到困惑,但让我相信使用 invokeLater 会帮助解决问题;因为使 JFrame 可见并显示动画的工作将放置在队列的末尾,允许 JButton 释放等。但是我没有运气;我完全误解了什么吗?
谢谢!
(也请不要评论我使用 Canvas 类而不是 JPanel,我有我的理由)。
示例代码:
Test5(带有 main 方法的类)。
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*
public class Test5 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Test5().setup();
}
});
}
private void setup() {
JFrame frame = new JFrame("Test");
JButton button = new JButton("Click here");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
newFrame();
}
});
}
});
frame.getContentPane().add(button);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
private void newFrame() {
JFrame newFrame = new JFrame("The new frame");
newFrame.setVisible(true);
newFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
CanvasClass canvas = new CanvasClass();
newFrame.getContentPane().add(canvas);
newFrame.pack();
canvas.runAnimation();
}
}
CanvasClass(画布子类)
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
public class CanvasClass extends Canvas {
int x;
public CanvasClass() {
setSize(new Dimension(550,550));
this.x = (int) (Math.random() * 255);
}
//@Override
public void paint(Graphics g) {
g.setColor(new Color(x, x, x));
g.fillOval(0,0,500,500);
}
void runAnimation() {
while (true) {
randomise();
repaint();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void randomise() {
x = (int) (Math.random() * 255);
}
}