0

I have this JFrame containing a children of JPanel wherein it displays the image which is declared in this manner.

BufferedImage image = ImageIO.read(filename);

The program displays the image properly. But the only thing is, it requires to resize the frame to display the image.

Is there a possible way to display the image once the frame appears?

mre
  • 43,520
  • 33
  • 120
  • 170
Cyril Horad
  • 1,555
  • 3
  • 23
  • 35
  • 2
    May be this happens because you are adding image after showing the frame. As solution you should first add image then make frame visible or you can also call repaint() after adding image. – Harry Joy Jul 06 '11 at 13:01
  • @Cyril Horad, if would help if you provided more sample code. – mre Jul 06 '11 at 13:06
  • Can you make the comment an answer for clear the thread. Thanks. I'll accept the answer. – Cyril Horad Jul 06 '11 at 13:06
  • Perhaps, you could try implementing the paint method again in your own class that extends JPanel like this: http://pastebin.com/3ZwVvr2v and making sure that super.paintComponent(g) is called upon creation of your JPanel so that the JFrame is drawn with the image. – Kevin Gurney Jul 06 '11 at 13:06
  • Could you also post the code where you drawing image? – Serhiy Jul 06 '11 at 13:07
  • @little, it may seemed odd. But I've tried making a method returning BufferedImage from the same code line above. And on the paint(Graphics g) method, I used that method and it worked. – Cyril Horad Jul 06 '11 at 13:07
  • 2
    @Cyril Horad, you should never explicitly invoke `paint(...)` or override it. – mre Jul 06 '11 at 13:09
  • @Cyril Horad paint(...) is delegated for Awt and BasicXxxUI, for painting in the Swing is there paintComponent(...) as sugested @Kevin Gurney and @little bunny foo foo too – mKorbel Jul 06 '11 at 13:24
  • @Cyril Horad, please see my edit. – mre Jul 06 '11 at 15:19

2 Answers2

3

You should override paintComponent(Graphics g) and draw the image therein. In this case, you should do this for the JPanel component (I think? If not, do this for the JComponent(s) you're referring to). Also, since Swing is not thread-safe, ensure these modifications are performed in the EDT.

EXAMPLE

public class Demo{
    private static BufferedImage bi;
    
    public static void main(String[] args){
        try{
            loadImage();
            
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run(){
                    createAndShowGUI();
                }
            });
        }
        catch (IOException e){
            // handle exception
        }
    }
    
    private static void loadImage() throws IOException{
        bi = ImageIO.read(new File("src/resource/braveheart.PNG"));
    }
    
    private static void createAndShowGUI(){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final JPanel panel = new JPanel(){
            @Override
            protected void paintComponent(Graphics g){
                Graphics g2 = g.create();
                g2.drawImage(bi, 0, 0, getWidth(), getHeight(), null);
                g2.dispose();
            }
            
            @Override
            public Dimension getPreferredSize(){
                return new Dimension(bi.getWidth(), bi.getHeight());
            }
        };
        
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

OUTPUT

enter image description here

It's important to keep in mind that this example ignores rendering hints, so when you maximize the JFrame, the image quality will be very poor. :)

EDIT

When answering this question, I assumed you had a basic understanding of Swing. I suppose I assumed too much. It is important to mention that all components should be added to the top-level container before it's been realized (i.e. made visible). This will ensure that everything is rendered without having to resize your frame. As others have suggested, you could have simply used a JLabel to render the image, and then added it to your JPanel. Instead, I promoted custom painting, which is perfectly acceptable, and to me, cleaner.

Community
  • 1
  • 1
mre
  • 43,520
  • 33
  • 120
  • 170
  • What's the differences between paint(Graphics g) with paintComponent(Graphics g)? – Cyril Horad Jul 06 '11 at 13:37
  • 1
    @Cyril Horad, `paint(...)` handles painting the content, borders, and children of any Swing component, whereas `paintComponent(...)` is used for rendering the Swing component, and is overridden when custom rendering is desired. – mre Jul 06 '11 at 13:41
  • @little bunny foo foo for little bit complicated way +1 – mKorbel Jul 06 '11 at 13:43
  • @camickr, I'm not sure how overriding `paintComponent(...)` is "reinventing the wheel"? It's definitely lower-level than using a `JLabel`, but it's certainly not reinventing the wheel. To me, by using a `JLabel`, all you're doing is delegating the image rendering to another component. – mre Jul 06 '11 at 14:35
  • 1
    Why are you promoting custom painting over using a JLabel? I always thought one of the goals of programming was to NOT reinvent the wheel. – camickr Jul 06 '11 at 14:38
  • 2
    Any time you extend a class it is custom code. Adding custom code when the functionality is supported directly is "reinventing the wheel" to me. Also this question is not about how to do painting it is about how to show the image when the frame is displayed. No where in your answer do you mention the real problem is the usage of setVisible(). Now the poster thinks the solution is the paintComponent() method, not about invoking setVisible after components have been added to the frame – camickr Jul 06 '11 at 14:42
  • @camickr, I guess I assumed that OP had a basic understanding of Swing. There's nothing wrong with the approach I promoted, in fact I think it's more preferable, but that's just a matter of opinion. I'm sorry our views on this do not align. – mre Jul 06 '11 at 14:43
  • @camickr, are you done? if you find my answer insufficient, feel free to chime in and provide an answer of your own. there's absolutely nothing wrong with my answer. although I didn't explicitly address certain problems, I implicitly answered them. – mre Jul 06 '11 at 14:52
  • 2
    When displaying text do you use a JLabel, or do you create a custom component and use the Graphics.drawString() method? I'm guessing you use a JLabel, so why do you favour custom painting of an image instead of letting a JLabel do all the work for you? I'm not trying to be a pain in the butt here. I honestly don't understand the difference. – camickr Jul 06 '11 at 15:24
1

for dispaly Image or ImageIcon is better look for JLabel (basic stuff)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • +1, I agree, use existing components instead of reinventing the wheel. – camickr Jul 06 '11 at 14:33
  • @camickr, funny how you up-vote this (because this answer aligns with your opinion), although @mKorbel neglected to address the original problem. this is why I take your criticism with a grain of salt. :) – mre Jul 06 '11 at 14:58
  • 1
    @little bunny foo foo, it's not funny at all. That is the point of upvoting an answer. You vote for what you think is the best approach. I believe using a JLabel to display an image is better than using custom code. Whether this solves the problem or not, it is still a true statement. Whenever I make a comment I gave a reason for a comment so people can can make an informed decision. Stating something is "more preferable" without giving any reasons means nothing :) – camickr Jul 06 '11 at 19:04
  • @camickr, hahahaha I find it to be hilarious. – mre Jul 06 '11 at 19:13
  • @camickr @little bunny foo foo, please last turn off light, Rob ++ – mKorbel Jul 06 '11 at 19:20
  • @mKorbel, lmao...whatever dude. you're both ridiculous. – mre Jul 06 '11 at 19:58