GridBagLayout 中的不均匀列
Uneven columns in GridBagLayout
我想创建一个由 4 个组件组成的 JPanel,它们分布在 2 列中。左列中的上部组件应占垂直 space 的 60%,下部组件应占剩余的 40%。在右栏中,它应该是相反的——上部组件占 40%,下部组件占 60%。
所以基本上我希望我的组件像这张图片一样布置:
我正在尝试通过 GridBagLayout
实现此行为。
public class Test extends JFrame {
JPanel testPanel = new JPanel();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Test().setVisible(true);
});
}
Test() {
prepareTestPanel();
setContentPane(testPanel);
setSize(500, 500);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void prepareTestPanel() {
testPanel.setLayout(new GridBagLayout());
addComp(makeUpperLeft());
addComp(makeLowerLeft());
addComp(makeUpperRight());
addComp(makeLowerRight());
}
private void addComp(Pair p) {
testPanel.add(p.comp, p.gbc);
}
private Pair makeUpperLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private Pair makeLowerLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 60;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeUpperRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 0;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeLowerRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 40;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private class Pair {
Component comp;
GridBagConstraints gbc;
public Pair(Component comp, GridBagConstraints gbc) {
this.comp = comp;
this.gbc = gbc;
}
}
}
不幸的是我得到的是:
我应该如何更正我的代码?另外,无论 window 如何调整大小,我都希望这个比例保持不变。我应该如何设置weighty
?
这不能直接在一个容器内完成。您将必须为您的两个列创建两个容器元素(比如另外两个 JPanel
对象)。在外部容器中添加列,然后在内部面板中添加组件。这是执行此操作的一些代码:
public class Test extends JFrame {
public Test() {
JPanel testPanel = new JPanel();
setContentPane(testPanel);
GridBagLayout gbl_testPanel = new GridBagLayout();
gbl_testPanel.columnWidths = new int[]{0, 0};
gbl_testPanel.rowHeights = new int[]{0};
gbl_testPanel.columnWeights = new double[]{0.5, 0.5};
gbl_testPanel.rowWeights = new double[]{1.0};
testPanel.setLayout(gbl_testPanel);
JPanel leftPanel = new JPanel();
GridBagConstraints gbc_leftPanel = new GridBagConstraints();
gbc_leftPanel.fill = GridBagConstraints.BOTH;
gbc_leftPanel.insets = new Insets(0, 0, 0, 5);
gbc_leftPanel.gridx = 0;
gbc_leftPanel.gridy = 0;
testPanel.add(leftPanel, gbc_leftPanel);
GridBagLayout gbl_leftPanel = new GridBagLayout();
gbl_leftPanel.columnWidths = new int[]{0};
gbl_leftPanel.rowHeights = new int[]{0, 0};
gbl_leftPanel.columnWeights = new double[]{0.0};
gbl_leftPanel.rowWeights = new double[]{0.6, 0.4};
leftPanel.setLayout(gbl_leftPanel);
JLabel lbl00 = new JLabel("Upper Left");
GridBagConstraints gbc_lbl00 = new GridBagConstraints();
gbc_lbl00.anchor = GridBagConstraints.NORTH;
gbc_lbl00.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl00.insets = new Insets(0, 0, 5, 0);
gbc_lbl00.gridx = 0;
gbc_lbl00.gridy = 0;
leftPanel.add(lbl00, gbc_lbl00);
JLabel lbl10 = new JLabel("Lower Left");
GridBagConstraints gbc_lbl10 = new GridBagConstraints();
gbc_lbl10.anchor = GridBagConstraints.NORTH;
gbc_lbl10.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl10.gridx = 0;
gbc_lbl10.gridy = 1;
leftPanel.add(lbl10, gbc_lbl10);
JPanel rightPanel = new JPanel();
GridBagConstraints gbc_rightPanel = new GridBagConstraints();
gbc_rightPanel.fill = GridBagConstraints.BOTH;
gbc_rightPanel.gridx = 1;
gbc_rightPanel.gridy = 0;
testPanel.add(rightPanel, gbc_rightPanel);
GridBagLayout gbl_rightPanel = new GridBagLayout();
gbl_rightPanel.columnWidths = new int[]{0};
gbl_rightPanel.rowHeights = new int[]{0, 0};
gbl_rightPanel.columnWeights = new double[]{0.0};
gbl_rightPanel.rowWeights = new double[]{0.4, 0.6};
rightPanel.setLayout(gbl_rightPanel);
JLabel lbl01 = new JLabel("Upper Right");
GridBagConstraints gbc_lbl01 = new GridBagConstraints();
gbc_lbl01.insets = new Insets(0, 0, 5, 0);
gbc_lbl01.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl01.anchor = GridBagConstraints.NORTH;
gbc_lbl01.gridx = 0;
gbc_lbl01.gridy = 0;
rightPanel.add(lbl01, gbc_lbl01);
JLabel lbl11 = new JLabel("Lower Right");
GridBagConstraints gbc_lbl11 = new GridBagConstraints();
gbc_lbl11.anchor = GridBagConstraints.NORTH;
gbc_lbl11.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl11.gridx = 0;
gbc_lbl11.gridy = 1;
rightPanel.add(lbl11, gbc_lbl11);
}
}
GridBagLayout 不容易支持这个:
您不能只指定您想要的比例 gridwidth/height。如果您想要 6/4 的比例,那么您实际上需要创建 10 个大小相同的虚拟组件,然后先将它们添加到面板中。然后你可以说一个组件的网格高度等于这些虚拟组件的 4(或 6)个。
weightx/y 约束仅适用于调整框架大小时的额外 space。因此,组件最初将按其首选尺寸打包,这意味着您还需要手动设置所需比例的首选尺寸。
您可以查看RelativeLayout。它确实允许您根据可用的 space 轻松创建相对大小的组件。
使用此布局的基本代码如下:
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
JPanel left = new JPanel( rl );
left.add(upperLeft, new Float(60));
left.add(lowerLeft, new Float(40));
// repeat above for the right panel
JPanel main = new JPanel( new GridLayout(0, 2) );
main.add(left);
main.add(right);
frame.add(main);
我想创建一个由 4 个组件组成的 JPanel,它们分布在 2 列中。左列中的上部组件应占垂直 space 的 60%,下部组件应占剩余的 40%。在右栏中,它应该是相反的——上部组件占 40%,下部组件占 60%。
所以基本上我希望我的组件像这张图片一样布置:
我正在尝试通过 GridBagLayout
实现此行为。
public class Test extends JFrame {
JPanel testPanel = new JPanel();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new Test().setVisible(true);
});
}
Test() {
prepareTestPanel();
setContentPane(testPanel);
setSize(500, 500);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void prepareTestPanel() {
testPanel.setLayout(new GridBagLayout());
addComp(makeUpperLeft());
addComp(makeLowerLeft());
addComp(makeUpperRight());
addComp(makeLowerRight());
}
private void addComp(Pair p) {
testPanel.add(p.comp, p.gbc);
}
private Pair makeUpperLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private Pair makeLowerLeft() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Left"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 60;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeUpperRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Upper Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 0;
gbc.gridheight = 40;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.4;
return new Pair(panel, gbc);
}
private Pair makeLowerRight() {
JPanel panel = new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Lower Right"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 50;
gbc.gridy = 40;
gbc.gridheight = 60;
gbc.gridwidth = 50;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.weightx = 0.5;
gbc.weighty = 0.6;
return new Pair(panel, gbc);
}
private class Pair {
Component comp;
GridBagConstraints gbc;
public Pair(Component comp, GridBagConstraints gbc) {
this.comp = comp;
this.gbc = gbc;
}
}
}
不幸的是我得到的是:
我应该如何更正我的代码?另外,无论 window 如何调整大小,我都希望这个比例保持不变。我应该如何设置weighty
?
这不能直接在一个容器内完成。您将必须为您的两个列创建两个容器元素(比如另外两个 JPanel
对象)。在外部容器中添加列,然后在内部面板中添加组件。这是执行此操作的一些代码:
public class Test extends JFrame {
public Test() {
JPanel testPanel = new JPanel();
setContentPane(testPanel);
GridBagLayout gbl_testPanel = new GridBagLayout();
gbl_testPanel.columnWidths = new int[]{0, 0};
gbl_testPanel.rowHeights = new int[]{0};
gbl_testPanel.columnWeights = new double[]{0.5, 0.5};
gbl_testPanel.rowWeights = new double[]{1.0};
testPanel.setLayout(gbl_testPanel);
JPanel leftPanel = new JPanel();
GridBagConstraints gbc_leftPanel = new GridBagConstraints();
gbc_leftPanel.fill = GridBagConstraints.BOTH;
gbc_leftPanel.insets = new Insets(0, 0, 0, 5);
gbc_leftPanel.gridx = 0;
gbc_leftPanel.gridy = 0;
testPanel.add(leftPanel, gbc_leftPanel);
GridBagLayout gbl_leftPanel = new GridBagLayout();
gbl_leftPanel.columnWidths = new int[]{0};
gbl_leftPanel.rowHeights = new int[]{0, 0};
gbl_leftPanel.columnWeights = new double[]{0.0};
gbl_leftPanel.rowWeights = new double[]{0.6, 0.4};
leftPanel.setLayout(gbl_leftPanel);
JLabel lbl00 = new JLabel("Upper Left");
GridBagConstraints gbc_lbl00 = new GridBagConstraints();
gbc_lbl00.anchor = GridBagConstraints.NORTH;
gbc_lbl00.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl00.insets = new Insets(0, 0, 5, 0);
gbc_lbl00.gridx = 0;
gbc_lbl00.gridy = 0;
leftPanel.add(lbl00, gbc_lbl00);
JLabel lbl10 = new JLabel("Lower Left");
GridBagConstraints gbc_lbl10 = new GridBagConstraints();
gbc_lbl10.anchor = GridBagConstraints.NORTH;
gbc_lbl10.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl10.gridx = 0;
gbc_lbl10.gridy = 1;
leftPanel.add(lbl10, gbc_lbl10);
JPanel rightPanel = new JPanel();
GridBagConstraints gbc_rightPanel = new GridBagConstraints();
gbc_rightPanel.fill = GridBagConstraints.BOTH;
gbc_rightPanel.gridx = 1;
gbc_rightPanel.gridy = 0;
testPanel.add(rightPanel, gbc_rightPanel);
GridBagLayout gbl_rightPanel = new GridBagLayout();
gbl_rightPanel.columnWidths = new int[]{0};
gbl_rightPanel.rowHeights = new int[]{0, 0};
gbl_rightPanel.columnWeights = new double[]{0.0};
gbl_rightPanel.rowWeights = new double[]{0.4, 0.6};
rightPanel.setLayout(gbl_rightPanel);
JLabel lbl01 = new JLabel("Upper Right");
GridBagConstraints gbc_lbl01 = new GridBagConstraints();
gbc_lbl01.insets = new Insets(0, 0, 5, 0);
gbc_lbl01.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl01.anchor = GridBagConstraints.NORTH;
gbc_lbl01.gridx = 0;
gbc_lbl01.gridy = 0;
rightPanel.add(lbl01, gbc_lbl01);
JLabel lbl11 = new JLabel("Lower Right");
GridBagConstraints gbc_lbl11 = new GridBagConstraints();
gbc_lbl11.anchor = GridBagConstraints.NORTH;
gbc_lbl11.fill = GridBagConstraints.HORIZONTAL;
gbc_lbl11.gridx = 0;
gbc_lbl11.gridy = 1;
rightPanel.add(lbl11, gbc_lbl11);
}
}
GridBagLayout 不容易支持这个:
您不能只指定您想要的比例 gridwidth/height。如果您想要 6/4 的比例,那么您实际上需要创建 10 个大小相同的虚拟组件,然后先将它们添加到面板中。然后你可以说一个组件的网格高度等于这些虚拟组件的 4(或 6)个。
weightx/y 约束仅适用于调整框架大小时的额外 space。因此,组件最初将按其首选尺寸打包,这意味着您还需要手动设置所需比例的首选尺寸。
您可以查看RelativeLayout。它确实允许您根据可用的 space 轻松创建相对大小的组件。
使用此布局的基本代码如下:
RelativeLayout rl = new RelativeLayout(RelativeLayout.Y_AXIS);
rl.setFill( true );
JPanel left = new JPanel( rl );
left.add(upperLeft, new Float(60));
left.add(lowerLeft, new Float(40));
// repeat above for the right panel
JPanel main = new JPanel( new GridLayout(0, 2) );
main.add(left);
main.add(right);
frame.add(main);