Search code examples
javamacosjframe

Java JFrame not showing label


I am trying to use JFrame and I want to add a label but when I try to put one in nothing happens. I have tried using every method I can find on the internet but none of them work. my code

import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.*;

public class main {
    public static void main(String[] args) {
        JFrame root = new JFrame();
        JLabel label = new JLabel();
        label.setText("Hello World!");
        root.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        root.setResizable(false);
        root.setSize(500,500);
        root.setVisible(true);
        root.add(label);
        label.setVisible(true);
        label.setPreferredSize(new Dimension(300, 150));
        label.setOpaque(true);
        



    }
}

Thanks!


Solution

  • The simple answer is to move root.setVisible(true); to the end of the method...

    JFrame root = new JFrame();
    JLabel label = new JLabel();
    label.setText("Hello World!");
    root.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    root.setResizable(false);
    root.setSize(500, 500);
    //root.setVisible(true);
    root.add(label);
    //label.setVisible(true);
    label.setPreferredSize(new Dimension(300, 150));
    //label.setOpaque(true);
    root.setVisible(true);
    

    Swing is lazy. If you modify the UI once it's realised on the screen, you need to manually trigger a new layout and paint pass.

    The "long" answer is, don't do:

    • root.setResizable(false); - as a user, I will personally dislike you
    • root.setSize(500, 500);
    • label.setPreferredSize(new Dimension(300, 150));

    You're manipulating workflows which are, generally better handled by the layout manager APIs

    For (a really arbitrary) example

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    
    public class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame root = new JFrame();
                    JPanel content = new JPanel(new BorderLayout());
                    content.setBorder(new EmptyBorder(250, 250, 250, 250));
                    root.setContentPane(content);
                    JLabel label = new JLabel();
                    label.setText("Hello World!");
                    root.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    root.add(label);
                    root.pack();
                    root.setLocationRelativeTo(null);
                    root.setVisible(true);
                }
            });
        }
    
    }
    

    Remember, you are dealing with a very dynamic environment, where ever possible you want to make use of "hints" over using "absolute" values, this will provide you with far more flexibility when it comes to operating in environments which you didn't originally code for