如何将 2 个 JButtons 放在 JPanel 的顶部(一个居中,另一个居中)?

How to place 2 JButtons at the top of a JPanel (one centered, the other topright)?

我想在我的 JPanel 上放置 2 个 JButton,其中一个居中,另一个位于 JPanel 的右上角。 JPanel 与包含 JPanel 的 JFrame 大小相同。我如何使用 GridBagLayout 和 GridBagConstraints 执行此操作?

public class MyPanel extends JPanel {
public MyPanel() {
    JButton btnGame1 = new JButton("Game 1");
    JButton btnExitFrame = new JButton("Exit");

    setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.anchor = GridBagConstraints.PAGE_START;
    c.weighty = 1;
    c.gridx = 0;
    add(btnGame1, c);
    c.gridx = 1;
    c.anchor = GridBagConstraints.FIRST_LINE_END;
    add(btnExitFrame, c);
}

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setResizable(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MyPanel());
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}
}

camickr 的 MCVE

public class MyPanel extends JPanel {
static JFrame frame = new JFrame();

public MyPanel() {
    JButton btnGame1 = new JButton("Game 1");
    JButton btnExitFrame = new JButton("Exit");;

    setLayout(new BorderLayout());

    JPanel top = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
    top.add( btnExitFrame );

    JPanel center = new JPanel(new GridBagLayout());
    center.add(btnGame1, new GridBagConstraints());

    add(top, BorderLayout.PAGE_START);
    add(center, BorderLayout.CENTER);
}

public static void main(String[] args) {
    frame.setResizable(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MyPanel());
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}
}

固定 SOL'N:

public class MyPanel extends JPanel {
    static JFrame frame = new JFrame();

    public MyPanel() {
        JButton btnGame1 = new JButton("Game 1");
        JButton btnExitFrame = new JButton("Exit");;

        int nOfCells = 3;
        setLayout(new GridBagLayout());        
        GridBagConstraints c = new GridBagConstraints();
        c.weightx = 1;
        c.weighty = 1;
        for(int i = 0; i < nOfCells; i++){
            for(int j = 0; j < nOfCells; j++){
                c.gridx = i;
                c.gridy = j;               
                if(i == 1 && j == 0) {
                    c.anchor = c.PAGE_START;
                    add(btnGame1, c);
                    c.anchor = c.CENTER;
                }
                else if(i == 2 && j == 0) {
                    c.anchor = c.FIRST_LINE_END;
                    add(btnExitFrame, c);
                    c.anchor = c.CENTER;
                }
                else {
                    c.fill = c.BOTH;
                    add(Box.createRigidArea(new Dimension(frame.getWidth()/nOfCells, frame.getHeight()/nOfCells)), c);
                    c.fill = c.NONE;
                }
            }
        }

    }

    public static void main(String[] args) {
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.getContentPane().add(new MyPanel());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

image of the fixed text box

利用框架的 BorderLayout 并使用嵌套面板。

JPanel top = new JPanel( new FlowLayout(set right alignment) ); // read FlowLayout API
top.add( topRightButton );

JPanel center = new JPanel( new GridBagLayout() );
center.add(centerButton, new GridBagConstraints());

frame.add(top, BorderLayout.PAGE_START);
frame.add(center, BorderLayout.CENTER);

编辑:

不要那样使用静态变量。如果您认为需要使用静态变量,那么您就有设计问题了。

由于您将 MyPanel class 直接添加到框架中,因此您需要进行以下更改才能有效地使您的 MyPanel class 成为使用 BorderLayout 的容器:

//setLayout(new GridBagLayout());
setLayout(new BorderLayout());

...

//frame.add(top, BorderLayout.PAGE_START);
//frame.add(center, BorderLayout.CENTER);
add(top, BorderLayout.PAGE_START);
add(center, BorderLayout.CENTER);

我建议您也可以阅读 How to Use BorderLayout 上的 Swing 教程中的部分。那里的演示代码将展示另一种将组件直接添加到框架的方法。

您当前的代码(加上我建议的上述更改)可能是更好的方法。但是您应该了解这两种方法以更好地理解布局管理器的工作原理。

另一个仅使用 GridBagLayout 的选项是添加不可见的 Boxes 作为填充物以将 JPanel 分成多个部分,然后用 JButtons 替换您首选位置的 Boxes。

    GridBagConstraints c = new GridBagConstraints();
    c.weightx = 1;
    for(int i=0; i<nOfCells; i++){
        for(int k=0; k<nOfCells; k++){

            c.gridx = i;
            c.gridy= k;
            this.add(Box.createRigidArea(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)), c);
        }
    }

GridBagLayout 不允许在 space 中固定位置,它们取决于它们相对于 JFrame 的其他组件的位置。