Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Swing : why must resize frame, so that can show components have added

I have a simple Swing GUI. (and not only this, all swing GUI I have written). When run it, it doesn't show anything except blank screen, until I resize the main frame, so every components have painted again, and I can show them.

Here is my simple code :

public static void main(String[] args) {
        JFrame frame = new JFrame("JScroll Pane Test");
        frame.setVisible(true);
        frame.setSize(new Dimension(800, 600));

        JTextArea txtNotes = new JTextArea();
        txtNotes.setText("Hello World");
        JScrollPane scrollPane = new JScrollPane(txtNotes);
        frame.add(scrollPane);
}

So, my question is : how can when I start this class, the frame will appear all components I have added, not until I resize frame.

Thanks :)

like image 531
hqt Avatar asked Dec 01 '22 21:12

hqt


2 Answers

  • Do not add components to JFrame after the JFrame is visible (setVisible(true))

  • Not really good practice to call setSize() on frame rather call pack() (Causes JFrame to be sized to fit the preferred size and layouts of its subcomponents) and let LayoutManager handle the size.

  • Use EDT (Event-Dispatch-Thread)

  • call JFrame#setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) as said by @Gilbert Le Blanc (+1 to him) or else your EDT/Initial thread will remain active even after JFrame has been closed

Like so:

public static void main(String[] args) {
        //Create GUI on EDT Thread
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                  JFrame frame = new JFrame("JScroll Pane Test");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

                  JTextArea txtNotes = new JTextArea();
                  txtNotes.setText("Hello World");
                  JScrollPane scrollPane = new JScrollPane(txtNotes);
                  frame.add(scrollPane);//add components

                  frame.pack();
                  frame.setVisible(true);//show (after adding components)
            }
        });
}
like image 52
David Kroukamp Avatar answered Dec 19 '22 00:12

David Kroukamp


Your simple code is missing a few things.

You have to invoke SwingUtilities to put the Swing components on the event dispatch thread.

You should call the setDefaultCloseOperation on the JFrame.

You have to call the JFrame methods in the correct order. The setSize or pack method is called, then the setVisible method is called last.

public class SimpleFrame implements Runnable {

    @Override
    public void run() {
        JFrame frame = new JFrame("JScroll Pane Test");

        JTextArea txtNotes = new JTextArea();
        txtNotes.setText("Hello World");
        JScrollPane scrollPane = new JScrollPane(txtNotes);
        frame.add(scrollPane);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
        frame.setSize(new Dimension(800, 600));
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new SimpleFrame());
    }

}
like image 22
Gilbert Le Blanc Avatar answered Dec 19 '22 00:12

Gilbert Le Blanc