Question

My code is

JFrame frame=new JFrame("Change pic");
ImageIcon image=new ImageIcon("image.jpg");
ImageIcon image1=new ImageIcon("image1.jpg");
frame.setSize(image.getIconWidth(),image.getIconHeight());
frame.add(new JLabel(image));
Thread.sleep(3000);
frame.add(new JLabel(image1));
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

When using the above code the first image("image") doesn't appear and only the second image("image 2") appears. And even when not using the line Thread.sleep(3000) it gives the same result. But when i'm writing my code as

JFrame frame=new JFrame("Change pic");
ImageIcon image=new ImageIcon("image.jpg");
ImageIcon image1=new ImageIcon("image1.jpg");
frame.setSize(image.getIconWidth(),image.getIconHeight());
frame.add(new JLabel(image));
frame.setVisible(true);
Thread.sleep(3000);
frame.add(new JLabel(image1));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Then the first image ("image") appears on top of the second image("image1") and i could only see the second image when I extend the Frame to the right?

So my question is why for the second code the first image("image") appears on the top? And what changes do i have to make so the second image("image1") replaces the first image("image") after 3 second?

Sorry, if the question is dumb. And any help will be appreciated. Actually, I'm trying to develop a remote desktop sharing application and I'm stuck here.

Was it helpful?

Solution

  1. JFrame has a default BorderLayout. Add components without specifying a BorderLayout position will automatically add it to the BorderLayout.CENTER. Each position can only have one component. The last component you add will be the only one visible. See more at How to Use BorderLayout

  2. Avoid using Thread.sleep. If you want animation, use a javax.swing.Timer. See more at How to use Swing Timers. Using this method, you can do something like this

    JLabel iconLabel = new JLabel(image);
    ...
    Timer timer = new Timer(3000, new ActionListener(){
         public void actionPerformed(ActionEvent e) {
             iconLabel.setIcon(image1);
         }
    }); 
    timer.setRepeats(false);
    timer.start();
    

    Instead of trying to add a new label, just change the icon.

  3. Also don't set the size of your frame. Just pack it. The image will set the preferred size of the JLabel for you and packing the frame will assure the icon is fully visible.

As an aside, when you add components after the container is visible, you need to revalidate() and repaint() the container.


Try running this example. Just put in your path to the image icons.

import java.awt.event.*;
import javax.swing.*;

public class ChangeIcon {

    public ChangeIcon() {
        final ImageIcon image = new ImageIcon("image.jpg");
        final ImageIcon image1 = new ImageIcon("image1.jpg");
        final JLabel iconLabel = new JLabel(image);

        Timer timer = new Timer(3000, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                iconLabel.setIcon(image1);
            }
        });
        timer.setRepeats(false);
        timer.start();

        JFrame frame = new JFrame();
        frame.add(iconLabel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ChangeIcon();
            }
        });
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top