Why is only one component appearing

51 views Asked by At

I have a JFrame and for some reason only one component is appearing

public JFrame mainMenuFrame = new JFrame();
    public JLabel welcomeText1 = new JLabel();
    public JLabel welcomeText2 = new JLabel("What would you like to do?");

    public void mainMenuWindow() {
        
        setNameFrame.dispose();
        
        welcomeText1.setPreferredSize(new Dimension(300, 200));
        welcomeText1.setHorizontalAlignment(JLabel.CENTER);
        welcomeText1.setVerticalAlignment(JLabel.TOP);
        welcomeText1.setFont(new Font("Arial", Font.PLAIN, 15));
        
        welcomeText2.setPreferredSize(new Dimension(200, 200));
        welcomeText2.setHorizontalAlignment(JLabel.CENTER);
        welcomeText2.setVerticalAlignment(JLabel.CENTER);
        welcomeText2.setFont(new Font("Arial", Font.PLAIN, 15));
        
        mainMenuFrame.add(welcomeText1);
        mainMenuFrame.add(welcomeText2);
        mainMenuFrame.revalidate();
        mainMenuFrame.repaint();

        mainMenuFrame.setTitle(game);
        mainMenuFrame.setLayout(new FlowLayout());
        mainMenuFrame.getContentPane();
        mainMenuFrame.pack();
        mainMenuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainMenuFrame.setSize(new Dimension(300, 200));
        mainMenuFrame.setLocationRelativeTo(null);
        mainMenuFrame.setResizable(false);
        mainMenuFrame.setVisible(true);
    }

I have tried changing the component type but it seems it will only display one component

1

There are 1 answers

3
Basil Bourque On

tl;dr

Specify your layout manager before adding components.

Mind your layout manager

To recap the Comments:

  • Every new JFrame defaults to using BorderLayout as its layout manager.
  • BorderLayout contains a limit of one single component in each of its five regions.
  • You added a component multiple times. Given that BorderLayout contains at most one component in a region, successive add calls replace the previous component with the next component.

In this example, the two component replaces the previously added one component. We added two components, but only see one.

package work.basil.example.swing;

import javax.swing.*;

public class OneComponent
{
    private static void createAndShowGUI ( )
    {
        // Window
        JFrame.setDefaultLookAndFeelDecorated ( true );

        JFrame frame = new JFrame ( "Adding Components In Swing" );
        frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );

        // Widgets
        JLabel one = new JLabel ( "One" );
        JLabel two = new JLabel ( "Two" );

        // Arrange
        frame.getContentPane ( ).add ( one );
        frame.getContentPane ( ).add ( two );

        // Display.
        frame.pack ( );
        frame.setVisible ( true );
    }

    public static void main ( String[] args )
    {
        javax.swing.SwingUtilities.invokeLater ( new Runnable ( )
        {
            public void run ( ) { OneComponent.createAndShowGUI ( ); }
        } );
    }
}

The solution is to specify your desired layout manager before adding widgets.

In our revised example, up top we specify a FlowLayout rather than go with the default BorderLayout. Only after setting the layout manager do we add any components.

Now when run we now see both added components, the second flowing after the first as expected with a FlowLayout.

Tip: Organize your code in three or four sections: Window/JFrame, Content/Widgets, and Arrange/Display.

package work.basil.example.swing;

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

public class OneComponent
{
    private static void createAndShowGUI ( )
    {
        // Window
        JFrame.setDefaultLookAndFeelDecorated ( true );

        JFrame frame = new JFrame ( "Adding Components In Swing" );
        frame.setLayout ( new FlowLayout ( ) );  // ⬅️ Specify desired layout manager, to replace default `BorderLayout`. 
        frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );

        // Widgets
        JLabel one = new JLabel ( "One" );
        JLabel two = new JLabel ( "Two" );

        // Arrange
        frame.getContentPane ( ).add ( one );
        frame.getContentPane ( ).add ( two );

        // Display.
        frame.pack ( );
        frame.setVisible ( true );
    }

    public static void main ( String[] args )
    {
        javax.swing.SwingUtilities.invokeLater ( new Runnable ( )
        {
            public void run ( ) { OneComponent.createAndShowGUI ( ); }
        } );
    }
}

(Running in Java 21.)