Question

I hope this isn’t a stupid first question; I can’t seem to find an answer anyway.

I have this JFrame constructor where a JPanel is added to the JFrame. The JPanel paints a Rectangle in the JFrame, and that’s fine. However, if I add an ImageIcon object as in the code below (for later use), the rectangle isn’t painted. It does appear if I resize the window though.

One solution is to put the setVisible(true) as the last line, or to instantiate the ImageIcon above the constructor, but I really want to understand this. It doesn’t make sense to me that an object not even used can cause this behaviour. Thanks.

public class AJFrame extends JFrame {

    ImageIcon ii;

    public AJFrame() {
        setSize(400,400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);

        ImageIcon ii = new ImageIcon("Untitled.png");

        JPanel jp = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                g.fillRect(0, 0, 50, 50);
            }
        };

        add(jp);
    }

    public static void main(String[] args) {
        AJFrame jf = new AJFrame();
    }
}
Was it helpful?

Solution

All actions within a frame should be done in the EDT (Event Dispatching Thread) of Swing. Therefore the right way to start your frame is

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

So maybe it all comes down to the wrong start of your frame.

The main routine of a Java program is not started within the EDT. All Swing actions that are not within the EDT could produce strange refresh/visibility issues.

Here is the complete sourcecode:

public class AJFrame extends JFrame {

    ImageIcon ii;

    public AJFrame() {
        setSize(400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        //setVisible(true);

        //ImageIcon ii = new ImageIcon("Untitled.png");
        JPanel jp = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                g.fillRect(0, 0, 50, 50);
            }
        };

        add(jp);
    }

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