在框架内重新绘制JPanel

时间:2011-01-09 19:59:30

标签: java swing animation jpanel

我在一个框架内有一个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 */
}

}

3 个答案:

答案 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自己画的时候会是浅灰色,或是白色或浅棕色,或者取决于你的外观和感觉。