我在一个框架内有一个JPanel。 JPanel的内容应该在每次调用paintComponent
(由repaint()
调用)时更新,但是当我按照下面这样调用时,我只看到一个白色窗口。
(请原谅那些破损的缩进,Eclipse会使用标签做各种奇怪的事情。)
private static void handleGUI()
{
JFrame frame = new JFrame("Animation");
frame.setPreferredSize(new Dimension(100, 100));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Board b = new Board();
frame.getContentPane().add(b);
frame.pack();
frame.setVisible(true);
while(true)
{
System.out.println("Repainting panel");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
b.repaint();
}
}
public class Board extends JPanel
{
public Board() { t=0; }
private int t;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
++t;
/* Variables snipped */
g.setColor(Color.white);
g.drawOval(0, 0, width, height);
BufferedImage image = ImageIO.read(new File(imagePath));
g.drawImage(image, x(t), y(t));
/* There's some more image and rectangle drawing ahead */
}
}
答案 0 :(得分:6)
你的代码有几个问题,上面已经提到了一个问题(1 + rep - 虽然它看起来好像你现在在paintComponent方法中有代码做了绘图),你的paintComponent方法是有缺陷的,但是不仅如此,你还有一个while(true)循环和Swing主线程中的Thread.sleep,EDT,这将使Swing和你的整个GUI进入休眠状态。最好使用Swing Timer。另外,你说,
每次调用paintComponent(由repaint()调用)都应该更新JPanel的内容,
您确定要将程序逻辑放在paintComponent方法中吗?这通常是不受欢迎的,因为程序员没有完全控制何时调用此方法。当你调用重绘时(但不总是),它可能被调用,并且当你不希望它被调用时,可能会由于来自操作系统的消息而被调用。
此外,您永远不想读取paintComponent方法中的文件,因为这会将您的绘画减慢到一个ca.l。
我建议这些更改:
1)创建一个周期为1000的Swing Timer,并在其ActionListener的actionPerformed方法中读入您的图像(如果图像有任何显着大小,最好在后台线程中)并将图像读入类字段,说叫图像。
2)在同一个Timer的actionPerformed方法中,增加t。
3)读入图像后,在绘图JPanel上调用重绘,并让绘图JPanel使用图像变量来绘制图像。如果您使用后台线程读取图像,请小心,因为您需要在完全读入图像时让此线程通知GUI。如果使用SwingWorker执行此操作,则可以添加侦听的PropertyChangeListener到SwingWorker的状态值并在此更改为StateValue.DONE时触发。
如果其中任何一项不清楚或令人困惑,请要求澄清。
编辑:如果图像不是太大,您可能希望一次读取它们,或者在需要一堆时进行批量读取。在使用它们之前,不需要立即读取图像。
答案 1 :(得分:2)
不要让线程睡眠。使用Swing Timer来设置重绘事件。
答案 2 :(得分:1)
你的paintComponent只调用super.paintComponent。所以JPanel自己画的时候会是浅灰色,或是白色或浅棕色,或者取决于你的外观和感觉。