Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPanel doesn't update until resize Jframe

Tags:

I subclass JPanel to overwrite paintComponent(Graphics), I want to draw an image onto jpanel in a jframe.

But my image hasn't shown up until I make a change to jframe's size. This is my code:

public class ImagePanel extends JPanel{

    public void setImage(BufferedImage bi)
    {
        image = bi;
        revalidate();
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if(image != null)
        {
            g.drawImage(image, 0, 0, this);
        }
    }
}
like image 430
nautilusvn Avatar asked Jun 17 '12 07:06

nautilusvn


People also ask

Does JPanel need JFrame?

Both JFrame and JPanel are important as a swing GUI cannot exist without these top-level containers. JFrame and JPanel both provide different methods to perform different GUI related functions.

How do I stop JFrame from resizing?

Making a Frame Non-Resizable: use setResizable(false) to freeze a frame's size. : JFrame Window « Swing « Java Tutorial. 14.80. 1. 14.80.

Does JPanel extend JComponent?

The BasicPanelUI can also install default settings for the JPanel font, foreground and background colors, and border. Generally if you want to draw something manually you'll extend JComponent and override the paintComponent() method. When people extend JPanel they rarely override any JPanel methods.

Can a JPanel contain JFrame?

JFrame is the window; it can have one or more JPanel instances inside it. JPanel is not the window.


2 Answers

Verify that you invoke setVisible() after adding components and calling pack(), as discussed in this related example. You may also need to adopt an appropriate layout. Invoking repaint(), as suggested here, may fix the symptom but not the underlying cause.

like image 98
trashgod Avatar answered Sep 19 '22 06:09

trashgod


If you want to "refresh" the JPanel then you should call repaint(), which will call your paintComponent(). This should fix your problem:

public void setImage(BufferedImage bi)
{
    image = bi;
    EventQueue.invokeLater(new Runnable()
    {
        public void run()
        {
            repaint();
        }
    });
}

Its good practice to update and change the GUI using the EDT. Heres more info on the EDT if you're interested:

How does the event dispatch thread work?

repaint doesn't need to be called from the EDT. If you're changing the GUI, such as setting text to a JLabel, it should be inside of the EDT. Heres more information on what can be called outside of the EDT (courtesy of nIcE cOw):

Safe to use Component.repaint() outside EDT?

like image 22
John Avatar answered Sep 19 '22 06:09

John