GridBagLayout:均匀分布的单元格

发布于 2024-09-19 00:15:25 字数 495 浏览 9 评论 0原文

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

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

编辑

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

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

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

Is it possible to completely emulate the behavior of a GridLayout with the GridBagLayout manager?

Basically, I have a 8x8 grid in which each cell should have the same width and height. The GridLayout automatically did this. But I want to add another row and column to the grid which size is not the same as the other ones. That row/column should take up all the remaining space that might be left over (because the available size couldn't be equally distributed into 8 cells). Is that even possible, or do I – again – have to use a different layout manager?

edit

Here is a simple graphic of what I want to achieve, simplified to just 4 cells:
Problem graphic

The colored cells are the ones I added to the actual grid (gray) which has cells with the same height and width x. So the grid's height and width is 4*x. I now want the additional cells to have the necessary width/height (minimumSize) plus the rest of the available width/height from the full size.

If the whole panel's size is changed, the gray grid cells should again take up as much as space as possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

猫性小仙女 2024-09-26 00:15:25

将固定单元格的GridBagConstraintsweightxweighty设置为0fill。对于浮动单元格,将 fill 设置为 BOTH,对于仅水平扩展的浮动单元格,将 weightx 设置为 1对于垂直扩展的,将 weighty 设置为 1

单元格只有在有内容时才会扩展,因此您需要用一些东西填充它。我选择了 JLabel 并为固定单元格中的标签设置了固定尺寸。调整大小时,您需要重新计算尺寸并调用 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);
    }
}

set weightx and weighty of GridBagConstraints of the fixed cells to 0 and the fill to NONE. For the floating cells set fill to BOTH, for the floating cells that should expand only horizontally set weightx to 1 and for the vertically expanding ones set weighty to 1.

The cells only expand if they have any content, so you need to fill it with something. I chose JLabels and set fixed dimensions for the labels in the fixed cells. On resize you need to recalculate the dimensions and call invalidate() to recalculate the layout.

Here is an example for a w x h grid:

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);
    }
}
枫以 2024-09-26 00:15:25

如果您不一定依赖于 GridBagLayout,则应该查看 MigLayout 库。您可以按照以下方式做一些事情:

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

If you're not tied to the GridBagLayout necessarily, you should look into the MigLayout library. You can do something along the lines of:

MigLayout layout = new MigLayout(
        "",         // Layout Constraints
        "[10][10][10][10]", // Column constraints
        "[10][10][10][10]");  // Row constraints
萌梦深 2024-09-26 00:15:25

所有值均在 GridBagConstraints 中设置。

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

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

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

如果你想让8x8的网格也扩展,那就更复杂了。除了 weightxweighty 值之外,您还可以调整 ipadxipady 值。或者为 8x8 网格创建一个面板并在其中使用 GridLayout。在面板和附加行/列上使用 GridBagLayout

All values are set in the GridBagConstraints.

If you want your 8x8 grid fixed, you can set the ipadx and ipady values.

Then set the weightx and weighty values of your new row/column to 1.0 and set fill to FULL.

Your extra row/column will expand with the space that is left over.

If you want the 8x8 grid to expand as well, that is more complicated. You can adjust the ipadx and ipady values in addition to the weightx and weighty values. Or make a panel for the 8x8 grid and use a GridLayout in there. Use your GridBagLayout on the panel and the additional row/column.

许仙没带伞 2024-09-26 00:15:25

您不在 JTable 中执行此操作是否有原因?看起来就是它的用途。使用适当的单元格渲染器,您可以将任何您想要的内容放入单元格中。

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

Is there a reason you're not doing this in a JTable? Seems like just the sort of thing it's made for. With the appropriate cell renderer you can put anything you want in the cells.

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

祁梦 2024-09-26 00:15:25

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

编辑

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

这是一个大学项目,于 2010 年 9 月中旬正式完成。我们实际上想在之后继续研究它,这可能就是为什么我说我会发布它(因为这是我想要改进的一件事),但我们从未真正得到过围绕这样做——可悲的是。相反,我只是省略了那些额外的列和行(顺便说一句,这意味着作为行/列的标签)。

所以,是的,我非常抱歉,我无法发布一个可以实现我最初想要的布局......:(也许如果有足够多的人请求这样的布局,我会创建它,但到目前为止,我并不是真的愿意再次深入研究 Java 布局;)

After trying many different things with the built-in layout managers, I decided to create a custom layout manager for this problem as well. I didn't do it yet, as I didn't have the time to continue with this project, but when I have it done, I'll make sure to post the layout manager code here, so that anyone interested in a similar solution can use it.

edit

didxga reminded me in the comments that I wanted to post my solution. However, after digging out the project from back then and looking at it, I actually cannot post my solution because it turns out that I never got to creating it!

It was a uni project that finished official mid September 2010. We actually wanted to continue working on it afterwards, which is probably why I said that I would post it (as that was one thing I wanted to improve), but we never really got around doing it – sadly. Instead I simply left out those extra column and row (which was meant as a label for the rows/columns btw).

So yeah, I’m terribly sorry that I cannot post a layout that does what I initially wanted… :( Maybe if there are enough requesting such a layout, I would create it, but as of now, I’m not really willing to dive into Java layouting again ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文