如何将 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 的其他组件的位置。
我想在我的 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 的其他组件的位置。