13

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

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

编辑

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

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

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

4

5 回答 5

3

固定单元格的和weightx到和到。对于设置为 的浮动单元格,对于应该仅水平扩展的浮动单元格设置为,对于设置为垂直扩展的浮动单元格设置为。weightyGridBagConstraints0fillNONEfillBOTHweightx1weighty1

单元格只有在它们有任何内容时才会扩展,所以你需要用一些东西填充它。我选择了JLabels 并为固定单元格中的标签设置了固定尺寸。在调整大小时,您需要重新计算尺寸并调用invalidate()以重新计算布局。

这是wxh网格的示例:

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);
    }
}
于 2010-09-14T04:26:21.543 回答
1

如果您不必绑定到 GridBagLayout,则应该查看MigLayout库。您可以执行以下操作:

MigLayout layout = new MigLayout(
        "",         // Layout Constraints
        "[10][10][10][10]", // Column constraints
        "[10][10][10][10]");  // Row constraints
于 2010-10-01T02:35:15.293 回答
0

所有值都设置在GridBagConstraints.

如果您想固定 8x8 网格,您可以设置ipadxipady值。

然后将新行/列的weightx和值设置为并设置为。weighty1.0fillFULL

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

如果您还希望扩展 8x8 网格,那就更复杂了。除了和值之外,您还可以调整ipadx和值。或者为 8x8 网格制作一个面板并在其中使用 a 。在面板上使用您的和附加的行/列。ipadyweightxweightyGridLayoutGridBagLayout

于 2010-09-12T15:42:46.777 回答
0

你没有在 JTable 中这样做是有原因的吗?似乎正是它的用途。使用适当的单元格渲染器,您可以在单元格中放置您想要的任何内容。

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

于 2010-10-02T16:46:59.963 回答
-2

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

编辑

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

这是一个 uni 项目,于 2010 年 9 月中旬正式完成。我们实际上想在之后继续工作,这可能是我说我会发布它的原因(因为这是我想要改进的一件事),但我们从来没有真正得到周围做它 - 可悲的是。相反,我只是省略了那些额外的列和行(顺便说一句,这意味着作为行/列的标签)。

所以,是的,我很抱歉我不能发布一个符合我最初想要的布局...... :( 如果有足够多的请求这样的布局,我会创建它,但到目前为止,我不太愿意再次进入 Java 布局;)

于 2010-10-02T17:49:07.347 回答