Search code examples
javaswingawtlayout-managerboxlayout

How to center JLabel and JButton in BoxLayout


I want to create simple menu with difficult levels

Screen shot

Next few lines of code is constructor.

super();

setMinimumSize(new Dimension(600, 300));

setMaximumSize(new Dimension(600, 300));

setPreferredSize(new Dimension(600, 300));

setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));

addButtons();

Method addButtons() add buttons which you can see on screenshoot:

add(Box.createVerticalGlue());

addLabel("<html>Current level <b>" + Game.instance()
                                         .getLevelString() +
         "</b></html>");

add(Box.createVerticalGlue());

addButton("Easy");

add(Box.createVerticalGlue());

addButton("Normal");

add(Box.createVerticalGlue());

addButton("Hard");

add(Box.createVerticalGlue());

addButton("Back");

add(Box.createVerticalGlue());

Method addButton()

private void addButton(String text)
{
    JButton button = new JButton(text);
    button.setAlignmentX(JButton.CENTER_ALIGNMENT);
    button.setFocusable(false);

    add(button);
}

And addLabel()

private void addLabel(String text)
{
    JLabel label = new JLabel(text, JLabel.CENTER);

    add(label);
}

I don't know how to align all elements to center. It's problem for me. Additional problem is when I change difficult level text on JLabel can change into, for simple 'Current level EASY'. Then JButtons are moving a lot of pixels right and I don't know why.


Solution

  • Second parameter in the public JLabel(String text, int horizontalAlignment) is for determine the text position of the label. You need to set the JLabel component's aligment by setAlignmentX method.

    private void addLabel(String text) {
        JLabel label = new JLabel(text, JLabel.CENTER);
        label.setAlignmentX(JLabel.CENTER_ALIGNMENT);
        add(label);
    }
    

    Edit:

    Your second issue is weird. I don't know why this is happening but I think creating a second panel for buttons will solve your issue.

    in constructor use border layout:

    super();
    
    //set size
    
    setLayout(new BorderLayout());
    
    addButtons();
    

    addButtons() method:

    //you can use empty border if you want add some insets to the top
    //for example: setBorder(new EmptyBorder(5, 0, 0, 0));
    
    addLabel("<html>Current level <b>" + Game.instance()
                                         .getLevelString() +
         "</b></html>");
    
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.PAGE_AXIS));
    
    buttonPanel.add(Box.createVerticalGlue());
    
    buttonPanel.add(createButton("Easy"));
    
    buttonPanel.add(Box.createVerticalGlue());
    
    //Add all buttons
    
    add(buttonPanel, BorderLayout.CENTER);
    

    createButton() method

    private JButton createButton(String text)
    {
        JButton button = new JButton(text);
        button.setAlignmentX(JButton.CENTER_ALIGNMENT);
        button.setFocusable(false);
    
        return button;
    }
    

    addLabel() method

    private void addLabel(String text)
    {
        JLabel label = new JLabel(text, JLabel.CENTER);
        add(label, BorderLayout.NORTH);
    }