ryansin
ryansin

Reputation: 1817

Class extending JPanel doesn't update UI

I have two classes: one which extends JFrame (MyFrame) and one which extends JPanel (MyPanel). The idea is to be able to add an instance of the MyPanel class to an existing, visible instance of MyFrame.

public class MyFrame extends JFrame {
    public MyFrame () {
        setVisible(true);
        JPanel panel = new MyPanel();
        add(panel);
    }
}

public class MyPanel extends JPanel {
    public MyPanel () {
        add(new JButton("Test"));
    }
}

public class Program {
    public static void main (String[] args) {
        new MyFrame();
    } 
}

The code runs and doesn't error, but the UI isn't updated when MyPanel is added to MyFrame.

Upvotes: 0

Views: 170

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347184

Like all the other questions relating to similar issues, move setVisible(true); to the end of the constructor.

Something like...

public class MyFrame extends JFrame {

    public MyFrame() {
        JPanel panel = new MyPanel();
        add(panel);
        pack();
        setVisible(true);
    }
}

Swing layouts are lazy, they won't update until you tell them to (or some other action, like the top level container been resized/reshown occurs)

You should also use pack to give your window a initial size, base on the size requirements of its content.

Having said all that, you really should avoid extending from top level containers like JFrame, lets face it, you're not really adding any new functionality to the class and instead, simply create a new instance when you need it...

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                ex.printStackTrace();
            }

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

Upvotes: 3

Related Questions