我该如何使用BoxLayout来达到这个效果?

3

我已经完美地设置了菜单(中间的方框),但我不知道如何定位标签。目前发生的情况是标签在菜单选项下方,而菜单选项被推到右侧。

这是我想要发生的事情: enter image description here

这是正在发生的事情: enter image description here

目前我使用以下方式使我的方框居中:

this.setAlignmentX(Component.CENTER_ALIGNMENT);

我尝试使用以下方法对我的标签进行相同的操作:

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

这只是一个空操作。

抱歉图示很糟糕,我在MS Paint里大约花了20秒钟画出来。

以下是标签的重要部分

public Label(String text)
{

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

这里是我创建BoxLayout的地方:

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

编辑:这是我在JFrame扩展类中的主要功能。在这个函数上面只是创建了面板、按钮和标签。

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");

}

这是我的菜单类当前的样子(此前负责按钮和标签的所有操作,除了它们的创建)。
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");
}
}

可能需要查看 JLabel.setHorizontalAlignment(int)。否则,请发布一个 SSCCE - Andrew Thompson
1
教程(在 Swing 标签维基中引用的圣经)中有一个完整的章节讲解如何使用 BoxLayout,包括如何修复对齐问题。 - kleopatra
我已经查看了修复方法。.setHorizontalAlignment并没有起到帮助作用。我正在更新我的帖子,以包含一个SSCCE。 - Jake Stanger
@peeskillet 抱歉,我应该更好地解释这个图表。唯一的标签是“版本”,而“菜单选项”是图表上的注释,指的是下面的按钮。 - Jake Stanger
您期望版本在哪里显示?它目前显示在哪里? - Paul Samsotha
显示剩余3条评论
1个回答

5
你可以使用正确的LayoutManager组合来获得所需的结果。不要局限于一个LayoutManager。利用组合/嵌套布局所带来的强大功能。
这是我使用的技术:
- 用BoxLayout来放置中间的按钮 - 用GridLayout(1,5)来放置除左下角按钮之外的所有内容,而该按钮则位于自己的面板中 - 使用FlowLayout和LEADING对齐方式 - 所有内容都被包含在JFrame默认的BorderLayout中
请参见下面的程序:
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();
            }
        });
    }
}

免责声明:请原谅标题的错误。我最初想将GridBagLayoutBox结合使用,但我的方法更加简单。现在我懒得改标题了。


对于那些说我上面所做的有点“hackish”(通过添加空面板),这可能是事实,你也可以将顶部面板和底部面板添加到一个包含BorderLayout和首选大小的面板中,它会给你类似的结果。

    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);
    }

我在修改代码时遇到了一些问题,因为我的JFrame是JFrame的扩展类(这就是“子类”吗?),并且在其上有一个“主面板”,因为我也使用了cardlayout。当我向主面板添加面板时,我使用了pnlMaster.add(pnlMenu,“主菜单”),而add方法只能像这样工作,或者您使用了BorderLayout参数。如果这没有意义,对不起,但我已经开始感到有点紧张,因为一切都已经崩溃了(什么都没有显示出来)。我很快会更新我的代码。 - Jake Stanger
你需要了解BorderLayout的工作原理。你需要为你添加的每个组件指定不同的位置(例如BorderLayout.NORTH)。在具有该布局的单个容器中,任何位置都不能重复使用。 - Paul Samsotha
不是太长,不。 - Jake Stanger
我很愿意提供帮助,但是如果没有更好的解释和查看一些代码,这真的很困难。 - Paul Samsotha
我正在更新帖子,请稍等。 - Jake Stanger
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接