4

My question here is how can I display an image into a JPanel? Other topics here asking something similar aren't clear to my about how can I do that.

I have a directory in my project folder that have image files Project Folder/GUI/img, specifically gray.png and green.png which I want to display in a JPanel.

I tried with the following code using ImageIcon and JLabel that I found in other post:

ImageIcon image = new ImageIcon("GUI/img/gray.png");
JLabel label = new JLabel(image);

//JPanel panel is already initialized by the IDE
panel.add(label)

But doesn't work... The JPanel remain empty without displaying any image. How can I do that?

Additional to this, I want that the image inside the JPanel change (gray.png for green.png) when some action is performed, for example pressing a button. I can archive that by the same method for display the image in the JPanel right?

Thanks in advance!

EDIT: Here's an example of a test code for get this. The initialization is done automatically by the IDE.

import java.awt.Image;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class Sample extends javax.swing.JFrame {

    public Sample() {
        initComponents();
    }

    //Initialization
    private void initComponents() {

        PanelImage = new javax.swing.JPanel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });

        javax.swing.GroupLayout PanelImageLayout = new javax.swing.GroupLayout(PanelImage);
        PanelImage.setLayout(PanelImageLayout);
        PanelImageLayout.setHorizontalGroup(
            PanelImageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );
        PanelImageLayout.setVerticalGroup(
            PanelImageLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 100, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(61, 61, 61)
                .addComponent(PanelImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(239, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(45, 45, 45)
                .addComponent(PanelImage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(155, Short.MAX_VALUE))
        );

        pack();
    }                    

    private void formWindowOpened(java.awt.event.WindowEvent evt) {                                  
        try {
            DisplayImage(PanelImage, "/GUI/img/gray.png");
        } catch (Exception ex) {
            Logger.getLogger(Sample.class.getName()).log(Level.SEVERE, null, ex);
        }
    }                                 

    //For display the url image in a JPanel
    private void DisplayImage(JPanel jp, String url) throws IOException, Exception {
        try {
            Image image=ImageIO.read(this.getClass().getResource(url));
            ImageIcon imageicon=new ImageIcon(image);
            JLabel label=new JLabel(imageicon);
            jp.add(label);
        } catch (IOException ex) {
            throw new IOException();
        } catch (Exception ex) {
            throw new Exception();
        }
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(Sample.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Sample().setVisible(true);
            }
        });
    }

    // Variables declaration                  
    private javax.swing.JPanel PanelImage;                
}

The private void DisplayImage(JPanel jp, String url) is what I need to work for display the image, from the url String url in the JPanel jp

FiroKun
  • 335
  • 2
  • 3
  • 14
  • 2
    Post a complete minimal example reproducing the problem. – JB Nizet Apr 04 '16 at 06:26
  • 3
    Try using `ImageIO.read(new File("GUI/img/gray.png"))`, this will throw an exception if the image can't be loaded for some reason, which `ImageIcon` won't. See [Reading/Loading an Image](http://docs.oracle.com/javase/tutorial/2d/images/loadimage.html) for more details – MadProgrammer Apr 04 '16 at 06:31
  • 1
    @JBNizet in examples involving images, i like to add the following advice - One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). – Andrew Thompson Apr 04 '16 at 08:24
  • Looks like adding component problem (no relayout has been triggered). Try to revalidate and repaint your panel (`panel.revalidate();` and `panel.repaint();`) after you've added your lable to panel. – Sergiy Medvynskyy Apr 04 '16 at 09:03
  • @SergiyMedvynskyy tried both methods `panel.revalidate()` and `panel.repaint()` with no effect. The panel still doesn't display the image. – FiroKun Apr 04 '16 at 18:19
  • @JBNizet I'll edit the post to include a example reproducing the problem. Thanks! – FiroKun Apr 04 '16 at 18:35

3 Answers3

2

Looking for pieces of code in Google I ended up with a solution... And was applying the same pattern that previous comments refer. The code that gave me the solution was:

label.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/gray.png")))

With that, I made then the method that I wanted to implement:

private static void DisplayImage(JPanel jp, String url) {
    JLabel jl=new JLabel();
    jl.setIcon(new javax.swing.ImageIcon(getClass().getResource(url)));
    jp.add(jl);
}

Maybe this is not the perfect and most-correct solution, but works perfect to my, that is what I want.

Thanks all for the answers and suggestions!

FiroKun
  • 335
  • 2
  • 3
  • 14
1

I had a similar issue when I was working on creating Minesweeper. I ended up finding a solution and getting it to work by first loading an Image and then creating an ImageIcon from that Image.

Image myImage = ImageIO.read(getClass().getResource("image_path.jpg"));
    myImage = myImage.getScaledInstance(30, 30, java.awt.Image.SCALE_SMOOTH);
    ImageIcon myImageIcon = new ImageIcon(myImage);
brs
  • 109
  • 5
  • [The Perils of Image.getScaledInstance()](https://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html) – MadProgrammer Apr 04 '16 at 07:00
  • Application resources will become embedded resources by the time of deployment, so it is wise to start accessing them as if they were, right now. An [tag:embedded-resource] must be accessed by URL rather than file. See the [info. page for embedded resource](http://stackoverflow.com/tags/embedded-resource/info) for how to form the URL. Above (as seen in this answer) is an example of loading an image by URL. (so ..nice work on that part @22ninjas). – Andrew Thompson Apr 04 '16 at 08:21
  • @22ninjas I tried that code with no effect. I create an `Image` object from `ImageIO` and then pass it to a `ImageIcon`, latter to a `JLabel` and added the `JLabel` to the `JPanel` and nothing, the image doesn't display in the panel. Maybe I'm making a mistake in the process, but implementing by that way doesn't work to my. – FiroKun Apr 04 '16 at 18:25
1

you have to use ImageIcon(this.getClass().getResource("/Gui/img/gray.png"));

here is example its working.

import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ExImage extends JPanel
{

    public ExImage()
    {
    ImageIcon imageIcon = new ImageIcon(this.getClass().getResource("/gray.png"));
    JLabel label = new JLabel(imageIcon);
    add(label);
    }

    public static void main(String[] args)
    {
    JFrame frame = new JFrame();
    frame.add(new ExImage());
    frame.setVisible(true);
    frame.setPreferredSize(new Dimension(200, 300));
    }
}
shimbu shambu
  • 125
  • 2
  • 10
  • Let me see if I understand this, `ExImage` is a java class that I need to create with that code, and from the main `JFrame`, which has the main interface, call the `ExImage` constructor for represent the image from the url inside a `JPanel` contained inside the `JFrame`? – FiroKun Apr 04 '16 at 18:40