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

时间:2017-04-18 21:58:47

标签: java swing jbutton gridbaglayout

我想在我的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);
}
}

MCVE for camickr

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

FIXED 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

2 个答案:

答案 0 :(得分:2)

仅使用GridBagLayout的另一个选项是添加隐形Box作为填充程序,将JPanel划分为多个部分,然后用您的JButton替换首选位置的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不允许在空间中修复位置,它们取决于它们相对于JFrame的其他组件的位置。

答案 1 :(得分:1)

利用框架的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类直接添加到框架中,因此需要进行以下更改才能有效地使MyPanel类成为使用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教程中的部分。那里的演示代码将显示另一种将组件直接添加到框架的方法。

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