3

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");
}
}
Jake Stanger
  • 449
  • 1
  • 8
  • 24
  • It is possible you need to look to [`JLabel.setHorizontalAlignment(int)`](http://docs.oracle.com/javase/7/docs/api/javax/swing/JLabel.html#setHorizontalAlignment%28int%29). Otherwise, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jan 05 '14 at 14:35
  • 1
    there's a whole chapter about how-to-use BoxLayout in the tutorial (the bible, referenced in the swing tag wiki), including how-to-fix alignment problems – kleopatra Jan 05 '14 at 14:38
  • Wait, which label are you talking about? I see a MenuOption but not another label except for the "Version" but that doesn't say anyting relative to the question. – Paul Samsotha Jan 05 '14 at 14:43
  • I did look at the fixes. And the .setHorizontalAlignment didn't help. I'm updating my post to contain an SSCCE. – Jake Stanger Jan 05 '14 at 14:49
  • @peeskillet sorry I should have explained the diagram better. The only label is "version" and "menu options" is an annotation on the diagram, refering to the buttons below it. – Jake Stanger Jan 05 '14 at 14:59
  • And where do you expect version to be showing and where is it currently showing? – Paul Samsotha Jan 05 '14 at 15:01
  • I don't get your drawing at all or what you wish to accomplish. You really need to explain better. Imagine you're explaining it to a 5 year old – Paul Samsotha Jan 05 '14 at 15:11
  • Ok sorry. Boxes represent swing elements upon the JPanel. All the centre elements are buttons. The box with the word "version" inside of it is the label I am trying to independently position. The diagram represents what I want my JPanel to look like. Currently the label is centred, below where I want the buttons to be and the buttons are all "pushed" to the right by the label. I am updating the diagrams for you too. – Jake Stanger Jan 05 '14 at 19:08

1 Answers1

5

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);
    }
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • I'm having a bit of an issue changing the code around because my JFrame is an extended class of JFrame (is this what a "subclass" is?) and upon that sits a "master panel" because I'm using a cardlayout too. When I've added panels to the master panel, I've used `pnlMaster.add(pnlMenu, "Main Menu")` and the add method only works like that or how you did it with the BorderLayout argument. Sorry if this makes no sense, but I'm getting kinda stressed over the fact everything has just broken (nothing is showing up any more). I will update my code soon. – Jake Stanger Jan 06 '14 at 10:38
  • You need to understand how `BorderLayout works. You need to sepcify a different position (i.e. BorderLayout.NORTH) for _every_ component you add. No poition can be used more than once in a single container with that layout. – Paul Samsotha Jan 06 '14 at 10:43
  • It's not too long, no. – Jake Stanger Jan 06 '14 at 10:52
  • I would like to help but without better explanation and seeing some code, its really hard – Paul Samsotha Jan 06 '14 at 10:53
  • I'm updating the post. Hold old. – Jake Stanger Jan 06 '14 at 10:55
  • I'm sure it is something stupid I've done wrong. It always is the silly mistakes... – Jake Stanger Jan 06 '14 at 11:01
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44605/discussion-between-peeskillet-and-roboguy99) – Paul Samsotha Jan 06 '14 at 11:02