I am new to using swing. I am trying to get a picture to be displayed in a Jframe when a button is pressed. I cannot figure out how to make this work. This is what I have so far:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;

public class JTresume extends JFrame
{
  
    public static void main (String[] args)
    {   
        final String picPath = "C:/Users/Joe/Pictures/me.jpg";
        
        
        // Set up JFrame
        JTresume f = new JTresume();
        f.setTitle("Resume");
        f.setSize(300, 300);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        
        // Set up two JPanels and add to JFrame 
        JPanel p1 = new JPanel();
        p1.setBackground(Color.red);
        f.add(p1, BorderLayout.NORTH);
        
                
        // Add Buttons to JPanel 1
        JButton button1 = new JButton("Picture");
        p1.add(button1);
        
        button1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                JOptionPane.showMessageDialog(null, "Picture Pressed");
                getImage(picPath);
            }          
        });
        
    } // End MAIN
    
            
    private static void getImage(String x)
    {

        try
        {
            ImageIcon img = new ImageIcon(x);
            JLabel label =  new JLabel("", img, JLabel.CENTER);
            JPanel p2 = new JPanel(new BorderLayout());
            p2.setLayout(null);
            p2.add(label, BorderLayout.CENTER);
         }catch(Exception ie){
            JOptionPane.showMessageDialog(null, "Error! " + ie.getMessage());
         }
    }
   
    
} // END

Thanks to anyone that can help.

p2.setLayout(null);
p2.add(label, BorderLayout.CENTER);

Why set a null layout then try to use a BorderLayout option? If you want a null layout manager then hypou have to supply complete bounds for p2.

ImageIcon img = new ImageIcon(x);

There's a gotcha with new ImageIcon - if it fails for any reason whatsoever it just returns null - no Exceptions are thrown. null is a valid parameter for the image icon in a new JLabel, so that doesn't give you an error either, you jus don't get an image. So, you should always test for your ImageIcon being non-null.

I just realized I did not add the Jpanel p2 to the frame. Since it is in a separate method can I not call a method to add the panel to the frame?

You need to declare the frame outside any one method, so it is accessible to all methods.

OK I see I have to make the frame and panel static so all methods can use it. Is this what you meant by testing the ImageIcon as null? You would not need a try/catch block? Still no luck. Thanks for your input so far!

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.File;

public class JTresume extends JFrame
{
    static JTresume f = new JTresume();
    static JPanel p2 = new JPanel();
    
    public static void main (String[] args)
    {   
        final String picPath = "C:/Users/Joe/Pictures/me.jpg";
        
        
        // Set up JFrame
        f.setTitle("Resume");
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        f.setExtendedState(Frame.MAXIMIZED_BOTH);   // Maximize Frame
        
        // Set up JPanel and add to JFrame 
        JPanel p1 = new JPanel();
        p1.setBackground(Color.red);
        f.add(p1, BorderLayout.NORTH);
        
                
        // Add Buttons to JPanel 1
        JButton button1 = new JButton("Picture");
        p1.add(button1);
        
        button1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                JOptionPane.showMessageDialog(null, "Picture Pressed");
               getImage(picPath);
               f.add(p2);
            }          
        });
        
    } // End MAIN
    
            
    private static void getImage(String x)
    {
        ImageIcon img = new ImageIcon(x);
        
        if(img != null)
        {
            JLabel label = new JLabel("", img, JLabel.CENTER);
            p2.add(label, BorderLayout.CENTER);
        }else
        {
            JOptionPane.showMessageDialog(null, "Error! NO PICTURE FOUND!" );
           
        }
        
        /*
        try
        {
            ImageIcon img = new ImageIcon(x);
            JLabel label =  new JLabel("", img, JLabel.CENTER);
            p2.add(label, BorderLayout.CENTER);
         }catch(Exception ie){
            JOptionPane.showMessageDialog(null, "Error! " + ie.getMessage());
         }*/
    }

Yes, that looks right. Try adding a bit of text to
JLabel label = new JLabel("", img, JLabel.CENTER);
so you can see if the label is being displayed at all...

Added a few things to debug...both system.out.println() get printed...so the image is getting accessed. The text was not displayed on the label. I guess the label is not being shown. p2.removeAll() was added to clear panel as to bring up another picture when another button is pressed. Once I get this working I intend to have a few buttons bring up different pictures. Is that the correct way to do this?

private static void getImage(String x)
    {
        ImageIcon img = new ImageIcon(x);
        System.out.println("Load Image");
        if(img != null)
        {
            System.out.println("Image loaded");
            JLabel label = new JLabel("image here!!!", img, JLabel.CENTER);
            p2.removeAll();
            p2.add(label, BorderLayout.CENTER);
        }else
        {
            JOptionPane.showMessageDialog(null, "Error! NO PICTURE FOUND!" );
           
        }
        
        
    }

What you're doing looks very good to me. I can't see any mistakes, and your approach to debugging is excellent.
Maybe try setting a background color on p2 to confirm that p2 is visible? Maybe try specify a BorderLayout option instead of just f.add(p2);?

Once again, thank you for your help! Changed the color of the panel, and it is visible upon execution of the program. After clicking the button, the image does not show...but when the window is minimized and then maximized again the photo does indeed show up. Does that make any sense?

Maybe missing a revalidate or pack() or one of those things that update the layout manager after adding the second panel? - I don't use BorderLayout in dynamic situations like this, so I'm not sure...

I believe James is correct that the problem lies in the missing revalidate() and repaint() on your panel. When add/remove components from a container, you should validate the container so layout is updated. Repaint will ensure that whole component gets repainted and not just regions that the RepaintManager thinks are dirty.

why remove/add same JComponents on Runtime, remove all code lines and replace that with

myLabel.setIcon(img)

then there no reason for very hard and long events as are revalidate(); with repaint();

if you have problem with image repaint in the Jlabel then change that with flush()


myIcon.getImage().flush();
myLabel.setIcon(myIcon);


more about Icon in the JLabel

commented: Good point. I didn't read enough to see if he really needed to remove at all. +16
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.