这就是我所拥有的。我有两个 JPanel,每个都有 GridBagLayout。它们的权重 x = 0.5 并填充两个方向。所以基本上窗口是一个 JPanel 的一半,另一个 JPanel 的一半。它应该保持这种状态。但是,如果我将 JButton 放入其中一个,则 JPanel 会变宽并占用第二个 JPanel 的一些空间。
我应该怎样做才能防止这种行为?是否还有其他布局可以按照我描述的方式工作?
这是我一直在测试的代码。
`
JFrame f = new JFrame();
f.setLayout(new BorderLayout());
f.setTitle("Start Window");
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setSize(400,300);
f.setResizable(true);
JPanel top = new JPanel();
JPanel right = new JPanel();
JPanel bottom = new JPanel();
JPanel left = new JPanel();
top.setPreferredSize(new Dimension(30,30));
right.setPreferredSize(new Dimension(30,30));
bottom.setPreferredSize(new Dimension(30,30));
left.setPreferredSize(new Dimension(30,30));
f.add(top,BorderLayout.NORTH);
f.add(right,BorderLayout.EAST);
f.add(bottom,BorderLayout.SOUTH);
f.add(left,BorderLayout.WEST);
JPanel centerContainer = new JPanel(new GridBagLayout());
GridBagConstraints centerLayout = new GridBagConstraints();
centerContainer.setBackground(Color.blue);
f.add(centerContainer);
JPanel centerLeft = new JPanel(new GridBagLayout());
GridBagConstraints centerLeftLayout = new GridBagConstraints();
centerLayout.gridx=0;
centerLayout.gridy=0;
centerLayout.weightx=0.5;
centerLayout.weighty=1;
centerLayout.fill = GridBagConstraints.BOTH;
centerLeft.setBackground(Color.red);
centerContainer.add(centerLeft,centerLayout);
JPanel centerRight = new JPanel();
centerLayout.gridx=1;
centerLayout.gridy=0;
centerLayout.weightx=0.5;
centerLayout.weighty=1;
centerLayout.fill = GridBagConstraints.BOTH;
centerRight.setBackground(Color.green);
centerContainer.add(centerRight,centerLayout);
JPanel leftElement = new JPanel(new GridBagLayout());
GridBagConstraints leftElementLayout = new GridBagConstraints();
centerLeftLayout.gridx=0;
centerLeftLayout.gridy=0;
centerLeftLayout.weightx=1;
centerLeftLayout.weighty=1;
centerLeftLayout.fill = GridBagConstraints.HORIZONTAL;
centerLeft.add(leftElement,centerLeftLayout);
JButton leftBtn = new JButton("CLIIIIICK!!!");
leftBtn.setLayout(new GridBagLayout());
leftElementLayout.gridx=0;
leftElementLayout.gridy=0;
leftElementLayout.weighty=0;
leftElementLayout.weightx=1;
leftElementLayout.fill=GridBagConstraints.HORIZONTAL;
leftElement.add(leftBtn,leftElementLayout);
f.setVisible(true);
`
解决方案:需要时使用更简单的布局。在这里,最好将这些中心 JPanel 保存在 1 行 2 列的 GridLayout 中,因为这将保证它们将面板精确地分成两部分。
旁注:
int ebGap = 30;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class SwingFoo02 extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = 300;
public SwingFoo02() {
int ebGap = 30;
setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
JPanel centerLeft = new JPanel(new GridBagLayout());
JPanel centerRight = new JPanel();
centerLeft.setBackground(Color.RED);
centerRight.setBackground(Color.GREEN);
JButton leftBtn = new JButton("CLIIIIICK!!!");
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.gridx = 1;
gbc.gridy = 1;
centerLeft.add(leftBtn, gbc);
setLayout(new GridLayout(1, 2));
add(centerLeft);
add(centerRight);
}
@Override
public Dimension getPreferredSize() {
Dimension supSize = super.getPreferredSize();
int w = Math.max(supSize.width, PREF_W);
int h = Math.max(supSize.height, PREF_H);
return new Dimension(w, h);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SwingFoo02 mainPanel = new SwingFoo02();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}