网格袋布局斗争
Grid bag layout struggles
我正在尝试在 Java Swing 中创建以下 GUI。在做了一些研究之后,我发现 Grid Bag Layout 是最灵活和 "best" 使用的管理器。问题是我遇到了一些困难,无法真正弄明白。
这是我要创建的布局:
真的很简单,但这就是我想要的。我想从简单的开始。
我从标题开始,只是第一个按钮,但事情是这样的:
标题很好,但按钮一直延伸到外面。当然,这是因为:gc.fill = GridBagConstraints.HORIZONTAL
,但它想要它,但不是所有的方式。可能是画面的 1/6。
无论如何,这是我的代码:
public class MainFrame extends JFrame {
private XJLabel jlNaam, welcome;
private XJTextField jtfNaam;
private XJButton jbOk;
private XJButton jbOk2;
public MainFrame() {
setTitle("TITLE");
setSize(600, 400);
setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
welcome = new XJLabel("TITLE!", 30);
welcome.setHorizontalAlignment(SwingConstants.CENTER);
jbOk = new XJButton("ok");
jbOk2 = new XJButton("ok2");
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.HORIZONTAL;
gc.insets = new Insets(10, 10, 10, 10);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.gridy = 0;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 3;
panel.add(welcome, gc);
gc.gridy = 1;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 1;
panel.add(jbOk, gc);
gc.gridy = 2;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 1;
panel.add(jbOk2, gc);
add(panel);
setVisible(true);
}
}
"X"类没什么特别的,只是为了让它更漂亮一点。
我怎样才能做到这一点?我愿意接受更好的方法来做到这一点。请注意:我在学校,因此不允许使用第三方布局管理器。所以我必须掌握默认的窍门。
在您的情况下,您似乎想要 3 列中的组件。
在你的情况下,问题是你没有任何一行包含 3 列组件,因此你无法按照你的意愿放置 "Title" 和底部 "Button"。
因此,如果您想使用 GridBagLayout,则需要伪造它。因此,在第二行中,您需要在第三列中添加一个虚拟组件。您应该可以使用 Box.createHorizontalStrut(10)
并将其添加到第 3 列的行中。
现在在第一行中,组件可以通过给它一个 gridwidth = 3
居中
在最后一行中,您使用 gridx = 2
添加按钮。
阅读 How to Use GridBagLayout 上的 Swing 教程部分。那里的演示几乎完全符合您的要求。
I found out The Grid Bag Layout was the most flexible and "best" manager to use
但是,您永远不会被迫使用单个布局管理器。
例如,您可以使用带有垂直 BoxLayout
的面板。那么你会:
- 将标签添加到面板。
- 将按钮添加到面板。
- 使用左对齐创建第二个面板
FlowLayout
并将按钮添加到按钮面板和面板。
- 将
Box.createVerticalGlue()
添加到面板。
- 将最后一个按钮添加到面板。
注:
您将需要使用 setAlignmentX(...)
方法正确对齐 left/center/right 位置的组件。
对于按钮面板,您需要使用 buttonsPanel.setMaximumSize( buttons.getPreferredSize() )
来防止面板的高度增加。
尝试实施这两种解决方案以更好地理解嵌套布局管理器的概念。然后您可以为以后的布局选择您喜欢的选项。
GridBagLayout
是最灵活的布局管理器之一,但也是最复杂的布局管理器之一。
很多时候,拿出一些纸并绘制布局将使您更容易理解您希望如何应用约束。
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test extends JFrame {
public static void main(String[] args) {
new Test();
}
public Test() throws HeadlessException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
// Fill the first row
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
JLabel title = new JLabel("Title!");
title.setHorizontalAlignment(JLabel.CENTER);
add(title, gbc);
// First column, second row
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.gridwidth = 1;
gbc.gridy++;
add(makeLabel("Button"), gbc);
// First column, second row
gbc.gridy++;
add(makeLabel("Button 2"), gbc);
// Second column, second row
gbc.gridx++;
add(makeLabel("Button 3"), gbc);
// Last column
gbc.gridx++;
// The the remaining area
gbc.weightx = 1;
gbc.weighty = 1;
// Bottom/right
gbc.anchor = GridBagConstraints.SOUTHEAST;
add(makeLabel("Button 4"), gbc);
}
protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text);
label.setOpaque(true);
label.setForeground(Color.WHITE);
label.setBackground(Color.BLUE);
return label;
}
}
}
显然,这是直接使用 GridBagLayout
。根据您的需要,您可能会发现使用两个或多个复合布局更容易
我正在尝试在 Java Swing 中创建以下 GUI。在做了一些研究之后,我发现 Grid Bag Layout 是最灵活和 "best" 使用的管理器。问题是我遇到了一些困难,无法真正弄明白。
这是我要创建的布局:
真的很简单,但这就是我想要的。我想从简单的开始。
我从标题开始,只是第一个按钮,但事情是这样的:
标题很好,但按钮一直延伸到外面。当然,这是因为:gc.fill = GridBagConstraints.HORIZONTAL
,但它想要它,但不是所有的方式。可能是画面的 1/6。
无论如何,这是我的代码:
public class MainFrame extends JFrame {
private XJLabel jlNaam, welcome;
private XJTextField jtfNaam;
private XJButton jbOk;
private XJButton jbOk2;
public MainFrame() {
setTitle("TITLE");
setSize(600, 400);
setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
welcome = new XJLabel("TITLE!", 30);
welcome.setHorizontalAlignment(SwingConstants.CENTER);
jbOk = new XJButton("ok");
jbOk2 = new XJButton("ok2");
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.HORIZONTAL;
gc.insets = new Insets(10, 10, 10, 10);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.gridy = 0;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 3;
panel.add(welcome, gc);
gc.gridy = 1;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 1;
panel.add(jbOk, gc);
gc.gridy = 2;
gc.gridx = 0;
gc.weighty = 1;
gc.weightx = 1;
panel.add(jbOk2, gc);
add(panel);
setVisible(true);
}
}
"X"类没什么特别的,只是为了让它更漂亮一点。
我怎样才能做到这一点?我愿意接受更好的方法来做到这一点。请注意:我在学校,因此不允许使用第三方布局管理器。所以我必须掌握默认的窍门。
在您的情况下,您似乎想要 3 列中的组件。
在你的情况下,问题是你没有任何一行包含 3 列组件,因此你无法按照你的意愿放置 "Title" 和底部 "Button"。
因此,如果您想使用 GridBagLayout,则需要伪造它。因此,在第二行中,您需要在第三列中添加一个虚拟组件。您应该可以使用 Box.createHorizontalStrut(10)
并将其添加到第 3 列的行中。
现在在第一行中,组件可以通过给它一个 gridwidth = 3
在最后一行中,您使用 gridx = 2
添加按钮。
阅读 How to Use GridBagLayout 上的 Swing 教程部分。那里的演示几乎完全符合您的要求。
I found out The Grid Bag Layout was the most flexible and "best" manager to use
但是,您永远不会被迫使用单个布局管理器。
例如,您可以使用带有垂直 BoxLayout
的面板。那么你会:
- 将标签添加到面板。
- 将按钮添加到面板。
- 使用左对齐创建第二个面板
FlowLayout
并将按钮添加到按钮面板和面板。 - 将
Box.createVerticalGlue()
添加到面板。 - 将最后一个按钮添加到面板。
注:
您将需要使用
setAlignmentX(...)
方法正确对齐 left/center/right 位置的组件。对于按钮面板,您需要使用
buttonsPanel.setMaximumSize( buttons.getPreferredSize() )
来防止面板的高度增加。
尝试实施这两种解决方案以更好地理解嵌套布局管理器的概念。然后您可以为以后的布局选择您喜欢的选项。
GridBagLayout
是最灵活的布局管理器之一,但也是最复杂的布局管理器之一。
很多时候,拿出一些纸并绘制布局将使您更容易理解您希望如何应用约束。
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test extends JFrame {
public static void main(String[] args) {
new Test();
}
public Test() throws HeadlessException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("");
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
// Fill the first row
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = GridBagConstraints.REMAINDER;
JLabel title = new JLabel("Title!");
title.setHorizontalAlignment(JLabel.CENTER);
add(title, gbc);
// First column, second row
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.gridwidth = 1;
gbc.gridy++;
add(makeLabel("Button"), gbc);
// First column, second row
gbc.gridy++;
add(makeLabel("Button 2"), gbc);
// Second column, second row
gbc.gridx++;
add(makeLabel("Button 3"), gbc);
// Last column
gbc.gridx++;
// The the remaining area
gbc.weightx = 1;
gbc.weighty = 1;
// Bottom/right
gbc.anchor = GridBagConstraints.SOUTHEAST;
add(makeLabel("Button 4"), gbc);
}
protected JLabel makeLabel(String text) {
JLabel label = new JLabel(text);
label.setOpaque(true);
label.setForeground(Color.WHITE);
label.setBackground(Color.BLUE);
return label;
}
}
}
显然,这是直接使用 GridBagLayout
。根据您的需要,您可能会发现使用两个或多个复合布局更容易