0

When I run my program, I need to add an image to my GUI during run time. As far as I know, getting the image from the source file works:

public ImageIcon getImage()
{
    ImageIcon image = null;

    if (length > 6.0)
    {
        //TODO
    } else {

        try
        {
            image = new ImageIcon(ImageIO.read( new File("car.png")));
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, "An Error occured! Image not found.", "Error", JOptionPane.ERROR_MESSAGE);
        }

    }

    return image;
}

I then add the image to a JLabel using the .setIcon() method, but nothing changes on the GUI.

public void addCarImage(Car newCar, int spaceNo)
{
    ImageIcon carImage;

    carImage = newCar.getImage();

    JOptionPane.showMessageDialog(null, "Car", "Car", JOptionPane.INFORMATION_MESSAGE, carImage);

    carList[spaceNo - 1] = newCar;
    carLabel[spaceNo - 1].setIcon(carImage);

}

The JOptionPane message was added to see if the image will actually load, and it does.

Any ideas? I've used google to look for solutions, such as repaint()/revalidate()/updateUI() and they didn't work.

Edit - carLabels are added like so (before adding images). JLabels are initially blank.

carLabel = new JLabel[12];

    for (int i = 0; i < carLabel.length; i++)
    {
        carLabel[i] = new JLabel();
    }


carPanel.setLayout(new GridLayout(3, 4));

for (int i = 0; i < 12; i++)
    {
         carPanel.add(carLabel[i]);
    }
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
Edd B
  • 25
  • 6
  • That would depend. How are the contents of carLabel added to the screen? – MadProgrammer Apr 29 '14 at 21:02
  • Edited post. I don't need to re-add the JLabels, do I? – Edd B Apr 29 '14 at 21:14
  • 1
    Post an [MCVE](http://stackoverflow.com/help/mcve) so we can test it out. Also probably not the cause, but why create a new image every time. If it's only one image for all the cars, just load it at startup and use that same icon for all the labels. – Paul Samsotha Apr 30 '14 at 01:23
  • @peeskillet offered some good advice re an example. Some other tips: 1) One way to get image(s) for an example is to hot-link to the images seen in [this answer](http://stackoverflow.com/a/19209651/418556). 2) By the time of deployment, those resources will likely become an [tag:embedded-resource]. That being the case, the resource must be accessed by `URL` instead of `File`. See the [info page](http://stackoverflow.com/tags/embedded-resource/info) for the tag, for a way to form an `URL`. – Andrew Thompson Apr 30 '14 at 05:13

2 Answers2

3

Please make sure you do it on the swing thread. Also, make sure image was loaded correctly.

Here is a simple code that I used to test and it is fine.

public class Main {
public static void main(String[] args) {
    final JFrame frame = new JFrame("TEST");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    final JLabel label = new JLabel();
    ImageIcon icon = null;

    try {
        icon = new ImageIcon(ImageIO.read(new File("C:\\images\\errorIcon.png")));
    } catch (IOException e) {
        e.printStackTrace();
    }

    frame.getContentPane().setLayout(new BorderLayout());
    frame.getContentPane().add(label, BorderLayout.CENTER);
    frame.setSize(200,200);

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            frame.setVisible(true);
        }
    });


    try {
        Thread.currentThread().sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    final ImageIcon finalIcon = icon;
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            if(finalIcon != null && finalIcon.getImageLoadStatus() == MediaTracker.COMPLETE){
               label.setIcon(finalIcon);
            }
        }
    });
}

}

Yarik.

YaRiK
  • 698
  • 6
  • 13
  • When you say make sure the image loads correctly, do you mean make sure it doesn't come back null? Because I checked that and it works. Or am I loading it onto the JLabel incorrectly? Also, what do you mean by doing it on the swing thread? – Edd B Apr 29 '14 at 22:30
  • The icon will not be null but it may fail to load the image. See my if statement where I check for load status. You set image correctly by it was not clear fro the code that you are doing it on the EDT. For that purpose I wrote an example where I do some work on the main thread but update UI on EDT using SwingUtils.invokeLater – YaRiK Apr 30 '14 at 14:19
  • you are ingenious, SwingUtilities.invokeLater(new Runnable()) is what I've been looking for for more than 3 hours... thanks for saving my sanity – Yahya Nov 27 '16 at 21:32
0

carLabel[i].repaint() after setting the value should work

Troveldom
  • 356
  • 1
  • 10