问题
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:
And here is what is happening:
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:
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.
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 aLEADING
alignment- All wrapped in the
JFrame
defaultBorderLayout
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);
}
来源:https://stackoverflow.com/questions/20934382/how-can-i-use-boxlayout-to-do-this