私は持っている:
- JButton を含む JFrame。
- アニメーションを表示する別の Canvas サブクラス。
そして、JButton を押すと、Canvas サブクラスをアニメーションとして表示する新しい JFrame を表示したいと考えています。
私が現在直面している問題は、新しい JFrame が表示されることですが、何もレンダリングする機会がなく、メイン フレームの JButton が押されたままです。この背後にあるロジックは、EDT が JButton をリリース済みとして表示するなどのジョブを完了していないため、アニメーション メソッドを実行する機会がなく、デッドロックに陥っているということです。
このロジックは、私が新しいスレッドを作成することでこの作業を行っていたため、以前はうまく機能していましたが、最近 Java、スレッド、および Swing について詳しく学んで、すべての Swing 関連のイベントを 1 つのスレッド (EDT) で処理する必要があることを知りました。 .
これは、以前にどのように機能させたかについて私を混乱させますが、invokeLaterを使用すると問題が解決すると信じています。JFrame を表示してアニメーションを表示するジョブはキューの最後に配置され、JButton の解放などを許可するためです。しかし、私は運がありませんでした。私は何かを完全に誤解していますか?
ありがとう!
(また、JPanel とは対照的に Canvas クラスの使用についてコメントしないでください。私には理由があります)。
サンプルコード:
Test5 (メイン メソッドを持つクラス)。
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);
}
}