GridBagLayout - 如何让此单元格填充其下方的 space?
GridBagLayout - How can I make this cell fill the space below it?
我正在创建一个包含 4 个 JPanel 的 JFrame。使用 GridBagLayout,我创建了三行两列,每列两个面板。通过将蓝色面板的单元格高度从 1 更改为 2,我可以让它覆盖下面的单元格。我想对绿色面板执行相同的操作,以填充其下方的 space。这是我的代码当前生成的内容:
我尝试将绿色面板的网格高度更改为 2,但结果是:
我是否错误地使用了 GridBagLayout?这样做的合适方法是什么?
这是我的代码:
import java.awt.Color;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
addComponents(frame.getContentPane());
frame.setSize(800, 600);
frame.setVisible(true);
}
public static void addComponents(Container contentPane) {
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(3,3,3,3);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 1;
c.weighty = 0.85;
JPanel panel1 = new JPanel();
panel1.setBackground(Color.BLUE);
contentPane.add(panel1, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1.1;
c.weighty = 0.35;
JPanel panel2 = new JPanel();
panel2.setBackground(Color.YELLOW);
contentPane.add(panel2, c);
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.15;
c.weighty = 0.5;
JPanel panel3 = new JPanel();
panel3.setBackground(Color.RED);
contentPane.add(panel3, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.38;
c.weighty = 0.5;
JPanel panel4 = new JPanel();
panel4.setBackground(Color.GREEN);
contentPane.add(panel4, c);
}
}
I create three rows and two columns,
实际上您只有两行,因为您只添加了网格值为 0 和 1 的组件。其中一个组件的网格高度为 2 的事实不会创建新行。
一种解决方案是使用嵌套面板。
为蓝色和黄色组件创建一个面板。这将使用具有一列和两行的 GridBagLayout。然后为每个组件设置权重值以提供所需的高度。
然后您再次为红色和绿色组件创建第二个面板,其中包含 1 列和两行。每个权重将设置为 0.5。
最后,您创建了一个包含 2 列和 1 行的第三个面板。您设置所需的 weightx 并将以上两个面板添加到此面板,然后将面板添加到框架。
如果第 3 列包含三个单元格,每个单元格的行跨度为 1,则布局开始按预期运行。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AnotherFourPanelLayout {
private JComponent ui = null;
AnotherFourPanelLayout() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
addComponents(ui);
}
public void addComponents(Container contentPane) {
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(3, 3, 3, 3);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.66;
c.weighty = 0.66;
JPanel panel1 = new JPanel();
addLabel(panel1, c);
panel1.setBackground(Color.CYAN);
contentPane.add(panel1, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.gridheight = 1;
//c.weightx = 1.1; // logical?
c.weightx = 0.66;
c.weighty = 0.33;
JPanel panel2 = new JPanel();
addLabel(panel2, c);
panel2.setBackground(Color.YELLOW);
contentPane.add(panel2, c);
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.33;
c.weighty = 0.33;
JPanel panel3 = new JPanel();
addLabel(panel3, c);
panel3.setBackground(Color.RED);
contentPane.add(panel3, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.33;
c.weighty = 0.66;
JPanel panel4 = new JPanel();
addLabel(panel4, c);
panel4.setBackground(Color.GREEN);
contentPane.add(panel4, c);
// hack to fix?
c.gridx = 2;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.01;
c.weighty = 0.33;
JPanel panelH1 = new JPanel();
//addLabel(panelH1, c);
panelH1.setBackground(Color.MAGENTA);
contentPane.add(panelH1, c);
c.gridy = 1;
JPanel panelH2 = new JPanel();
//addLabel(panelH2, c);
panelH2.setBackground(Color.MAGENTA);
contentPane.add(panelH2, c);
c.gridy = 2;
JPanel panelH3 = new JPanel();
//addLabel(panelH3, c);
panelH3.setBackground(Color.MAGENTA);
contentPane.add(panelH3, c);
}
private void addLabel(JPanel panel, GridBagConstraints gbc) {
panel.add(new JLabel(constraintsToString(gbc)));
}
private String constraintsToString(GridBagConstraints gbc) {
StringBuilder sb = new StringBuilder();
sb.append("<html><table>");
sb.append(addRowToTable("Grid X", gbc.gridx));
sb.append(addRowToTable("Grid Y", gbc.gridy));
sb.append(addRowToTable("Weight X", gbc.weightx));
sb.append(addRowToTable("Weight Y", gbc.weighty));
sb.append(addRowToTable("Grid Width", gbc.gridwidth));
sb.append(addRowToTable("Grid Height", gbc.gridheight));
return sb.toString();
}
private String addRowToTable(String label, double value) {
StringBuilder sb = new StringBuilder("<tr><td>");
sb.append(label);
sb.append("</td><td>");
sb.append(value);
sb.append("</td></tr>");
return sb.toString();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
AnotherFourPanelLayout o = new AnotherFourPanelLayout();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
我正在创建一个包含 4 个 JPanel 的 JFrame。使用 GridBagLayout,我创建了三行两列,每列两个面板。通过将蓝色面板的单元格高度从 1 更改为 2,我可以让它覆盖下面的单元格。我想对绿色面板执行相同的操作,以填充其下方的 space。这是我的代码当前生成的内容:
我尝试将绿色面板的网格高度更改为 2,但结果是:
我是否错误地使用了 GridBagLayout?这样做的合适方法是什么?
这是我的代码:
import java.awt.Color;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
addComponents(frame.getContentPane());
frame.setSize(800, 600);
frame.setVisible(true);
}
public static void addComponents(Container contentPane) {
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(3,3,3,3);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 1;
c.weighty = 0.85;
JPanel panel1 = new JPanel();
panel1.setBackground(Color.BLUE);
contentPane.add(panel1, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1.1;
c.weighty = 0.35;
JPanel panel2 = new JPanel();
panel2.setBackground(Color.YELLOW);
contentPane.add(panel2, c);
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.15;
c.weighty = 0.5;
JPanel panel3 = new JPanel();
panel3.setBackground(Color.RED);
contentPane.add(panel3, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.38;
c.weighty = 0.5;
JPanel panel4 = new JPanel();
panel4.setBackground(Color.GREEN);
contentPane.add(panel4, c);
}
}
I create three rows and two columns,
实际上您只有两行,因为您只添加了网格值为 0 和 1 的组件。其中一个组件的网格高度为 2 的事实不会创建新行。
一种解决方案是使用嵌套面板。
为蓝色和黄色组件创建一个面板。这将使用具有一列和两行的 GridBagLayout。然后为每个组件设置权重值以提供所需的高度。
然后您再次为红色和绿色组件创建第二个面板,其中包含 1 列和两行。每个权重将设置为 0.5。
最后,您创建了一个包含 2 列和 1 行的第三个面板。您设置所需的 weightx 并将以上两个面板添加到此面板,然后将面板添加到框架。
如果第 3 列包含三个单元格,每个单元格的行跨度为 1,则布局开始按预期运行。
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class AnotherFourPanelLayout {
private JComponent ui = null;
AnotherFourPanelLayout() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
addComponents(ui);
}
public void addComponents(Container contentPane) {
contentPane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(3, 3, 3, 3);
c.fill = GridBagConstraints.BOTH;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.66;
c.weighty = 0.66;
JPanel panel1 = new JPanel();
addLabel(panel1, c);
panel1.setBackground(Color.CYAN);
contentPane.add(panel1, c);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.gridheight = 1;
//c.weightx = 1.1; // logical?
c.weightx = 0.66;
c.weighty = 0.33;
JPanel panel2 = new JPanel();
addLabel(panel2, c);
panel2.setBackground(Color.YELLOW);
contentPane.add(panel2, c);
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.33;
c.weighty = 0.33;
JPanel panel3 = new JPanel();
addLabel(panel3, c);
panel3.setBackground(Color.RED);
contentPane.add(panel3, c);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 2;
c.weightx = 0.33;
c.weighty = 0.66;
JPanel panel4 = new JPanel();
addLabel(panel4, c);
panel4.setBackground(Color.GREEN);
contentPane.add(panel4, c);
// hack to fix?
c.gridx = 2;
c.gridy = 0;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 0.01;
c.weighty = 0.33;
JPanel panelH1 = new JPanel();
//addLabel(panelH1, c);
panelH1.setBackground(Color.MAGENTA);
contentPane.add(panelH1, c);
c.gridy = 1;
JPanel panelH2 = new JPanel();
//addLabel(panelH2, c);
panelH2.setBackground(Color.MAGENTA);
contentPane.add(panelH2, c);
c.gridy = 2;
JPanel panelH3 = new JPanel();
//addLabel(panelH3, c);
panelH3.setBackground(Color.MAGENTA);
contentPane.add(panelH3, c);
}
private void addLabel(JPanel panel, GridBagConstraints gbc) {
panel.add(new JLabel(constraintsToString(gbc)));
}
private String constraintsToString(GridBagConstraints gbc) {
StringBuilder sb = new StringBuilder();
sb.append("<html><table>");
sb.append(addRowToTable("Grid X", gbc.gridx));
sb.append(addRowToTable("Grid Y", gbc.gridy));
sb.append(addRowToTable("Weight X", gbc.weightx));
sb.append(addRowToTable("Weight Y", gbc.weighty));
sb.append(addRowToTable("Grid Width", gbc.gridwidth));
sb.append(addRowToTable("Grid Height", gbc.gridheight));
return sb.toString();
}
private String addRowToTable(String label, double value) {
StringBuilder sb = new StringBuilder("<tr><td>");
sb.append(label);
sb.append("</td><td>");
sb.append(value);
sb.append("</td></tr>");
return sb.toString();
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
AnotherFourPanelLayout o = new AnotherFourPanelLayout();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}