How can I use BoxLayout to do this?

1.8k Views Asked by At

I've already set up the menu (the centre boxes) perfectly, but I don't know how I can position the label. Currently what is happening is the label is going below the menu options, and the menu options are pushed to the right.

Here is what I want to happen: enter image description here

And here is what is happening: enter image description here

Currently I have my boxes centred with:

this.setAlignmentX(Component.CENTER_ALIGNMENT);

And I have attempted to do the same with my label using:

this.setAlignmentX(Component.BOTTOM_ALIGNMENT);
this.setAlignmentY(Component.LEFT_ALIGNMENT);

Which does nothing.

Sorry the diagram is so bad, I drew it up in MS Paint in about 20 seconds.

Here is the important part of the label

public Label(String text)
{

    this.setHorizontalTextPosition(JLabel.CENTER);
    this.setVerticalTextPosition(JLabel.CENTER);
    this.setHorizontalAlignment(0);
}

And here is where I create the boxlayout:

 pnlMain.setLayout(new BoxLayout(pnlMain, BoxLayout.Y_AXIS));

Edit: Here is the main function inside my JFrame extension class. Above the function is just the creation of panels, buttons and labels.

public Window()
{
    //Create the JFrame
    super("Tank Trouble");
    this.pack();
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setVisible(true);

    //Changes the frame size to your screen size
    Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (int) (dimension.getWidth());
    int y = (int) (dimension.getHeight());
    setSize(x,y);
    setResizable(false);
    //GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(this); //Makes the application go fullscreen

    getContentPane().add(pnlMaster);

    pnlMaster.add(pnlMenu, "Main Menu");
    pnlMaster.add(pnlOptions, "Options");
    pnlMaster.add(pnlGame, "Game");
    pnlMaster.add(pnlMenu2);

    switchTo("Main Menu");

    pnlOptions.setLayout(new BoxLayout(pnlOptions, BoxLayout.Y_AXIS));

    Box box = Box.createVerticalBox();
    box.add(Window.playS);
    box.add(Box.createVerticalStrut(20));
    box.add(Window.playM);
    box.add(Box.createVerticalStrut(20));
    box.add(Window.options);
    box.add(Box.createVerticalStrut(20));
    box.add(Window.language);
    box.add(Box.createVerticalStrut(20));
    box.add(Window.exit);
    box.add(Box.createVerticalStrut(20));

    pnlMenu.add(box);
    pnlMenu.add(new JPanel());
    pnlMenu.add(new JPanel());
    pnlMenu.add(new JPanel());
    pnlMenu.add(new JPanel());

    pnlMenu2.add(Window.lblVersion);

    System.out.println("Window class loaded");

}

And here is what my menu class currently looks like (this is what previously handled everything to do with the buttons and labels except their creation).

package menu;

import main.Window;

public class Menu
{   
    public Menu()
    {
    Listener listener = new Listener();

    //Add ActionListeners
    Window.exit.addActionListener(listener);
    Window.playS.addActionListener(listener);
    Window.playM.addActionListener(listener);
    Window.options.addActionListener(listener);
    Window.language.addActionListener(listener);
    Window.btnBack.addActionListener(listener);

    System.out.println("Menu class loaded");
}
}
1

There are 1 best solutions below

7
Paul Samsotha On BEST ANSWER

You can get the desired results using the correct combinations of LayoutManagers. Don't limit yourself to one. Take advantage of the power than comes with combining/nesting layouts.

enter image description here

Here's the technique I used

  • A BoxLayout for the center buttons
  • A GridLayout(1, 5) for a panel the consists of everything but the buttom-left button which is in its own
  • FlowLayout with a LEADING alignment
  • All wrapped in the JFrame default BorderLayout

See the program below

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

public class BoxLayoutDemo {

    JButton button1 = new JButton("Button1");
    public BoxLayoutDemo() {
        JPanel pane = new JPanel(new GridLayout(1, 5));

        Box box = Box.createVerticalBox();
        box.add(new JButton("Button 1"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 2"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 3"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 4"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 5"));
        box.add(Box.createVerticalStrut(20));

        pane.add(new JPanel());
        pane.add(new JPanel());
        pane.add(box);
        pane.add(new JPanel());
        pane.add(new JPanel());

        JPanel pane2 = new JPanel(new FlowLayout(FlowLayout.LEADING));
        pane2.add(new JButton("ButtonButton"));

        JFrame frame = new JFrame("GridBag Box");
        frame.add(pane, BorderLayout.CENTER);
        frame.add(pane2, BorderLayout.SOUTH);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


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

Disclaimer : excuse the title of the frame. I was first thinking of combining GridBagLayout with the Box, but the way I did it was so much easier. Too lazy to change the title now that I've noticed it.


For those who say what I did above is somewhat hackish (by adding empty panels), which maybe it is, you could also add the top panel and bottom panel to a containing panel with a BorderLayout and a preferred size, and it will give you similar result

    public BoxLayoutDemo() {
        JPanel pane = new JPanel();

        Box box = Box.createVerticalBox();
        box.add(new JButton("Button 1"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 2"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 3"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 4"));
        box.add(Box.createVerticalStrut(20));
        box.add(new JButton("Button 5"));
        box.add(Box.createVerticalStrut(20));

        pane.add(box);

        JPanel pane2 = new JPanel(new FlowLayout(FlowLayout.LEADING));
        pane2.add(new JButton("ButtonButton"));

        JPanel panel = new JPanel(new BorderLayout()){
            public Dimension getPreferredSize() {
                return new Dimension(400, 260);
            }
        };
        panel.add(pane, BorderLayout.CENTER);
        panel.add(pane2, BorderLayout.SOUTH);

        JFrame frame = new JFrame("Slitting using different layouts");
        frame.add(panel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }