Java 在GridBagLayout单元格中收缩JLabel 问题

Java 在GridBagLayout单元格中收缩JLabel 问题,java,swing,jlabel,layout-manager,gridbaglayout,Java,Swing,Jlabel,Layout Manager,Gridbaglayout,我有一个JPanel,其中GridBagLayout是一个布局管理器。我希望布局的列具有一定的宽度。有时,列的宽度可能低于内部组件的首选宽度。在这种情况下,柱应强制构件仅占用柱的可用空间。 但是,就目前而言,如果列宽约束小于组件的首选宽度,则单元内的组件不会收缩 例子 下面是4x4网格的演示。我希望左上角的JLabel按照初始化GridBagLayout时设置的最小宽度收缩(10像素) 当我运行下面的示例时,得到以下结果: 左上角的单元格占用的空间比最初由GridBagLayout所允许的多

我有一个
JPanel
,其中
GridBagLayout
是一个布局管理器。我希望布局的列具有一定的宽度。有时,列的宽度可能低于内部组件的首选宽度。在这种情况下,柱应强制构件仅占用柱的可用空间。 但是,就目前而言,如果列宽约束小于组件的首选宽度,则单元内的组件不会收缩

例子 下面是4x4网格的演示。我希望左上角的
JLabel
按照初始化
GridBagLayout
时设置的最小宽度收缩(10像素)

当我运行下面的示例时,得到以下结果:

左上角的单元格占用的空间比最初由
GridBagLayout所允许的多

public class ResizeDemo extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            ResizeDemo resizeDemo = new ResizeDemo();
            resizeDemo.pack();
            resizeDemo.setDefaultCloseOperation(EXIT_ON_CLOSE);
            resizeDemo.setVisible(true);
        });
    }

    public ResizeDemo() {
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0, 0};
        gridBagLayout.rowHeights = new int[]{0, 0};
        gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
        gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE};
        getContentPane().setLayout(gridBagLayout);

        JPanel panel = new JPanel();
        GridBagConstraints gbc_panel = new GridBagConstraints();
        gbc_panel.fill = GridBagConstraints.BOTH;
        gbc_panel.gridx = 0;
        gbc_panel.gridy = 0;
        getContentPane().add(panel, gbc_panel);
        GridBagLayout gbl_panel = new GridBagLayout();
        
        
        // ============  Set the column widths here ============
        //  Note that the width of the first column is 10 px 
        gbl_panel.columnWidths = new int[] {10, 150, 0};
        // =====================================================
        
        gbl_panel.rowHeights = new int[]{0, 0, 0};
        gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0};
        gbl_panel.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
        panel.setLayout(gbl_panel);

        JLabel label1 = new JLabel("A very long string here");
        label1.setHorizontalAlignment(SwingConstants.CENTER);
        GridBagConstraints gbc_label1 = new GridBagConstraints();
        gbc_label1.fill = GridBagConstraints.HORIZONTAL;
        gbc_label1.gridx = 0;
        gbc_label1.gridy = 0;
        panel.add(label1, gbc_label1);

        JLabel label2 = new JLabel("Label");
        GridBagConstraints gbc_label2 = new GridBagConstraints();
        gbc_label2.gridx = 1;
        gbc_label2.gridy = 0;
        panel.add(label2, gbc_label2);

        JLabel label3 = new JLabel("Label");
        GridBagConstraints gbc_label3 = new GridBagConstraints();
        gbc_label3.fill = GridBagConstraints.HORIZONTAL;
        gbc_label3.gridx = 0;
        gbc_label3.gridy = 1;
        panel.add(label3, gbc_label3);

        JLabel label4 = new JLabel("Label");
        GridBagConstraints gbc_label4 = new GridBagConstraints();
        gbc_label4.gridx = 1;
        gbc_label4.gridy = 1;
        panel.add(label4, gbc_label4);

    }
}
问题:
如何强制
GridBagLayout
单元格内的
JLabel
收缩自身?

这是代码中设置宽度的部分。缺少设置列宽默认值以适应封闭构件

gbl_panel.columnWidths = new int[] {10, 150, 0};

GridBagLayout根据添加到列中的任何组件的最大“首选大小”调整每个列的大小

“columnWidths”用于设置任何列的最小值。调整框架大小时使用此选项。如果没有足够的空间以其首选尺寸显示零部件,并且您已为零部件设置了调整尺寸的权重,则零部件的尺寸将从其首选尺寸缩小到其最小尺寸

如何强制GridBagLayout单元格中的JLabel收缩自身

一种可能是使用
BoxLayout
将标签包装在面板中。
BoxLayout
将考虑组件的最大尺寸。基本逻辑是:

//panel.add(label1, gbc_label1);
Dimension max = label1.getPreferredSize();
max.width = 10;
label1.setMaximumSize(max);
Box wrapper = Box.createHorizontalBox();
wrapper.add(label1);
panel.add(wrapper, gbc_label1);

不知道您真正的应用程序是什么,但如果您只使用标签,那么您可能可以使用
JTable
。使用
JTable
可以控制实际列宽。

GridBagLayout根据添加到列中的任何组件的最大“首选大小”调整每列的大小。“columnWidths”用于设置任何列的最小值。调整框架大小时使用此选项。如果没有足够的空间以其首选尺寸显示构件,并且您已为列设置了调整权重,则构件的尺寸将从首选尺寸缩小到最小尺寸。一种可能是使用BoxLayout将标签包装在面板中。BoxLayout将考虑组件的最大尺寸。好的,现在我看到了。我认为
GridBagLayout.columnWidths
强制网格设置为该大小,但正如您所解释的,只有当网格没有足够的空间来满足其组件的首选大小时,它才会影响单元格的行为。实际上,is所做的是为列提供最小间距。因此,例如,如果将组件添加到第0列和第3列,它将为第1列和第2列提供最小宽度(如果定义了列宽),这将允许您使用组件为随机列的网格。请参阅:以获取演示此操作的示例。