GridBagLayout:均匀分布的单元格

是否可以使用GridBagLayout管理器完全模拟GridLayout的行为?

基本上,我有一个8×8网格,其中每个单元格应具有相同的宽度和高度。 GridLayout自动执行此操作。 但我想在网格中添加另一行和列,其大小与其他大小不同 。 该行/列应占用可能遗留的所有剩余空间(因为可用大小无法平均分配到8个单元中)。 这是可能的,还是我 – 再次 – 必须使用不同的布局管理器?

编辑

这是我想要实现的简单图形,简化为4个单元格: 问题图形

有色单元格是我添加到实际网格(灰色)的单元格,其中单元格具有相同的高度和宽度x 。 因此网格的高度和宽度为4*x 。 我现在希望其他单元格具有必要的宽度/高度(minimumSize)加上完整尺寸的可用宽度/高度的其余部分。

如果更改整个面板的大小,灰色网格单元应该再次占用尽可能多的空间。

将固定单元格的GridBagConstraintsweightxweighty设置为0fillNONE 。 对于浮动单元格设置fillBOTH ,对于应该仅水平扩展的浮动单元格,将weightx设置为1 ,对于垂直扩展的浮动单元格,将weightx设置为1

细胞只有在有任何内容时才会展开,因此您需要填充一些内容。 我选择了JLabel并为固定单元格中的标签设置了固定尺寸。 在resize时,您需要重新计算尺寸并调用invalidate()以重新计算布局。

以下是w x h网格的示例:

 import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JLabel; public class GridBag { public static void main(String[] args) { final JFrame f = new JFrame("Gridbag Test"); final Container c = f.getContentPane(); c.setLayout(new GridBagLayout()); final Dimension dim = new Dimension(70, 70); final int w = 4; final int h = 4; final JLabel[] yfloating = new JLabel[w]; final JLabel[] xfloating = new JLabel[h]; final JLabel[][] fixed = new JLabel[w][h]; // adding the vertically floating cells final GridBagConstraints gc = new GridBagConstraints(); gc.fill = GridBagConstraints.BOTH; gc.weightx = 0.0; gc.weighty = 1.0; for(int i = 0; i < w; ++i) { yfloating[i] = new JLabel("floating " + i); yfloating[i].setBorder(BorderFactory.createLineBorder(Color.BLACK)); yfloating[i].setHorizontalTextPosition(JLabel.CENTER); yfloating[i].setVerticalTextPosition(JLabel.CENTER); gc.gridy = 0; gc.gridx = i+1; c.add(yfloating[i], gc); } // adding the horizontally floating cells gc.fill = GridBagConstraints.BOTH; gc.weightx = 1.0; gc.weighty = 0.0; for(int i = 0; i < w; ++i) { xfloating[i] = new JLabel("floating " + i); xfloating[i].setBorder(BorderFactory.createLineBorder(Color.BLACK)); xfloating[i].setHorizontalTextPosition(JLabel.CENTER); xfloating[i].setVerticalTextPosition(JLabel.CENTER); gc.gridy = i+1; gc.gridx = 0; c.add(xfloating[i], gc); } // adding the fixed cells gc.fill = GridBagConstraints.NONE; gc.weightx = 0.0; gc.weighty = 0.0; for(int i = 0; i < w; ++i) { for(int j = 0; j < h; ++j) { fixed[i][j] = new JLabel("fixed " + i); fixed[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK)); fixed[i][j].setMaximumSize(dim); fixed[i][j].setMinimumSize(dim); fixed[i][j].setPreferredSize(dim); gc.gridx = i+1; gc.gridy = j+1; c.add(fixed[i][j], gc); } } c.addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { final Component comp = e.getComponent(); final int newSize = Math.min(comp.getHeight() / h, comp.getWidth() / w); final Dimension newDim = new Dimension(newSize, newSize); for(int i = 0; i < w; ++i) { for(int j = 0; j < h; ++j) { fixed[i][j].setMaximumSize(newDim); fixed[i][j].setMinimumSize(newDim); fixed[i][j].setPreferredSize(newDim); } } comp.invalidate(); } }); f.pack(); f.setVisible(true); } } 

如果你没有必然绑定GridBagLayout,你应该查看MigLayout库。 你可以做一些事情:

 MigLayout layout = new MigLayout( "", // Layout Constraints "[10][10][10][10]", // Column constraints "[10][10][10][10]"); // Row constraints 

所有值都在GridBagConstraints中设置。

如果您希望固定8×8网格,可以设置ipadxipady值。

然后将新行/列的weightxweighty值设置为1.0 ,并将fill设置为FULL

您的额外行/列将随着剩余的空间而扩展。

如果您希望8×8网格也能扩展,那就更复杂了。 除了ipadxipady值之外,您还可以调整ipadxipady值。 或者为8×8网格制作一个面板,并在那里使用GridLayout 。 在面板和附加行/列上使用GridBagLayout

有没有理由你不在JTable中这样做? 看起来就像它所做的那样。 使用适当的单元格渲染器,您可以在单元格中放置任何所需的内容。

http://www.java2s.com/Code/Java/Swing-Components/TableRowHeaderExample.htm

在使用内置布局管理器尝试了许多不同的东西之后,我决定为这个问题创建一个自定义布局管理器。 我还没有这样做,因为我没有时间继续这个项目,但是当我完成它时,我将确保在这里发布布局管理器代码,以便任何对类似解决方案感兴趣的人可以用它。

编辑

didxga在评论中提醒我,我想发布我的解决方案。 然而,在从后面挖掘项目并查看它之后,我实际上无法发布我的解决方案,因为事实certificate我从来没有创建它!

这是一个单一的项目,于2010年9月中旬正式完成。我们实际上想继续研究它,这可能就是为什么我说我会发布它(因为这是我想改进的一件事),但我们从未真正得到过做到这一点 – 遗憾的是。 相反,我只是省略了那些额外的列和行(这意味着行/列btw的标签)。

所以,是的,我非常抱歉,我不能发布一个我最初想要的布局… :(也许如果有足够的请求这样的布局,我会创建它,但截至目前,我不是真的愿意再次深入Java布局;)