Java 网格布局重量错误?

Java 网格布局重量错误?,java,swing,layout,grid,Java,Swing,Layout,Grid,我正在处理的项目中组件的布局看起来不正确,我怀疑Swing中存在错误。基本上,当布置的单元具有不同的最小尺寸和/或首选尺寸时,似乎发生的情况是,weightx和weighty比例没有得到遵守。我创建了一个示例程序来演示这一点,以下是源代码: package com.ensoftcorp.product.simmerge.gui.swing.dialogs; import java.awt.Color; import java.awt.Dimension; import java.awt.Gri

我正在处理的项目中组件的布局看起来不正确,我怀疑Swing中存在错误。基本上,当布置的单元具有不同的最小尺寸和/或首选尺寸时,似乎发生的情况是,
weightx
weighty
比例没有得到遵守。我创建了一个示例程序来演示这一点,以下是源代码:

package com.ensoftcorp.product.simmerge.gui.swing.dialogs;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestClass {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new TestClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static final GridBagConstraints GBC_CELL = new GridBagConstraints();
    static final GridBagConstraints GBC_ROWEND = new GridBagConstraints();
    static final GridBagConstraints GBC_FILLROW = new GridBagConstraints();
    static {
        GBC_CELL.anchor = GridBagConstraints.NORTHWEST;
        GBC_CELL.weightx = 0.5;
        GBC_CELL.fill = GridBagConstraints.BOTH;

        GBC_ROWEND.gridwidth = GridBagConstraints.REMAINDER;

        GBC_FILLROW.gridwidth = GridBagConstraints.REMAINDER;
        GBC_FILLROW.weightx = 1.0;
        GBC_FILLROW.fill = GridBagConstraints.BOTH;
    }

    public TestClass() {
        JFrame frame = new JFrame();

        JPanel pnlContent = new JPanel(new GridBagLayout());
        pnlContent.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        /*
         * Layout "ruler" panel
         */
        JPanel pnlRuler = new JPanel(new GridBagLayout());

        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);
        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);

        pnlRuler.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "correct" panel
         */
        JPanel pnlGoodLayout = new JPanel(new GridBagLayout());

        pnlGoodLayout.add(new JButton("JButton1"),GBC_CELL);
        pnlGoodLayout.add(new JButton("JButton2"),GBC_CELL);

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlGoodLayout.add(new JButton("JButton3"),GBC_CELL);
        pnlGoodLayout.add(new JButton("JButton4"),GBC_CELL);

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "incorrect" panel
         */
        JPanel pnlBadLayout = new JPanel(new GridBagLayout());

        pnlBadLayout.add(new JButton("JButton1"),GBC_CELL);
        pnlBadLayout.add(new JButton("JButton2"),GBC_CELL);

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlBadLayout.add(new JButton("JButton number 3 is wide"),GBC_CELL);
        pnlBadLayout.add(new JButton("JButton4"),GBC_CELL);

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Add panels to main panel
         */
        pnlContent.add(pnlRuler,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlGoodLayout,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlBadLayout,GBC_FILLROW);

        /*
         * Configure frame
         */
        frame.getContentPane().add(pnlContent);
        frame.setTitle("GridBagLayout Weight Bug?");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,200);
        frame.setVisible(true);
}

    JComponent createRulerCell(Color border, Color background) {
        JPanel glue = new JPanel();
        glue.setBorder(BorderFactory.createLineBorder(border));
        glue.setBackground(background);

        return glue;
    }

}
示例程序有三组…第一组是显示50%分数的“标尺”。第二组和第三组是使用GridBagLayout的面板,其中每个单元格的权重x为0.5。这两个组之间的唯一区别是按钮文本长度,但是第二个组的列比例并不均匀,即使它有足够的空间这样做

我的问题是:以前有没有人遇到过这个问题,他们会推荐一种解决方法

附言——如果jdk1.6.0_11有区别的话,我正在使用它。

来自:

指定如何分配额外的水平空间

网格行李布局管理器将列的重量计算为列中所有组件的最大重量X。如果生成的布局在水平方向上小于需要填充的区域,则额外的空间将按其权重比例分配给每列

考虑到这一点,我不认为这是一个bug,因为带有wide按钮的列需要更多的空间。一旦计算了该值和正常按钮列的大小,剩余的空间将被分配

解决方法:

要解决此问题,可以在添加每个按钮之前设置
GBC_CELL.gridx
GBC_CELL.gridy
,在与大按钮共享行的按钮之前,可以设置

GBC_单元,ipadx=100

然后将其设置为
0
,然后再添加宽按钮(#3)。这将使按钮在更多的网格中对齐。

使用内置按钮。您拥有比GridBagLayout更多的控制权。

这可能会有帮助:

当多个列具有非零权重时,多余的空间为 使用权重值分布在非零权重列中。 特别是,如果多余空间为P个像素,则列权重 因为列^i是权重^i,那么列^i得到的正好是(权重^i*P)/ (所有列权重之和)。例如,如果列1的权重为1 列2的权重为2,多余空间为90像素,列1 将获得30个额外像素,第2列将获得60个额外像素。排 对于非零权重,其行为方式类似


我找到了一个简单的解决办法。将每个
JButton
preferredSize.width
属性显式设置为
preferredSize.width=0

这是一种方法:

private JButton createButton(String text) {
    JButton button = new JButton(text);
    button.setPreferredSize(new Dimension(0, button.getPreferredSize().height));
    return button;
}
这是您修改过的示例(我用
//
public class TestClass {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            new TestClass();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static final GridBagConstraints GBC_CELL = new GridBagConstraints();
    static final GridBagConstraints GBC_ROWEND = new GridBagConstraints();
    static final GridBagConstraints GBC_FILLROW = new GridBagConstraints();
    static {
        GBC_CELL.anchor = GridBagConstraints.NORTHWEST;
        GBC_CELL.weightx = 0.5;
        GBC_CELL.fill = GridBagConstraints.BOTH;

        GBC_ROWEND.gridwidth = GridBagConstraints.REMAINDER;

        GBC_FILLROW.gridwidth = GridBagConstraints.REMAINDER;
        GBC_FILLROW.weightx = 1.0;
        GBC_FILLROW.fill = GridBagConstraints.BOTH;
    }

    public TestClass() {
        JFrame frame = new JFrame();

        JPanel pnlContent = new JPanel(new GridBagLayout());
        pnlContent.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

        /*
         * Layout "ruler" panel
         */
        JPanel pnlRuler = new JPanel(new GridBagLayout());

        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);
        pnlRuler.add(createRulerCell(Color.BLACK, Color.WHITE),GBC_CELL);

        pnlRuler.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "correct" panel
         */
        JPanel pnlGoodLayout = new JPanel(new GridBagLayout());

        pnlGoodLayout.add(createButton("JButton1"),GBC_CELL); // <==============
        pnlGoodLayout.add(createButton("JButton2"),GBC_CELL); // <==============

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlGoodLayout.add(createButton("JButton3"),GBC_CELL); // <==============
        pnlGoodLayout.add(createButton("JButton4"),GBC_CELL); // <==============

        pnlGoodLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Layout "incorrect" panel
         */
        JPanel pnlBadLayout = new JPanel(new GridBagLayout());

        pnlBadLayout.add(createButton("JButton1"),GBC_CELL); // <==============
        pnlBadLayout.add(createButton("JButton2"),GBC_CELL); // <==============

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        pnlBadLayout.add(createButton("JButton number 3 is wide"),GBC_CELL); // <==============
        pnlBadLayout.add(createButton("JButton4"),GBC_CELL); // <==============

        pnlBadLayout.add(Box.createHorizontalGlue(),GBC_ROWEND);

        /*
         * Add panels to main panel
         */
        pnlContent.add(pnlRuler,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlGoodLayout,GBC_FILLROW);
        pnlContent.add(Box.createVerticalStrut(8),GBC_FILLROW);
        pnlContent.add(pnlBadLayout,GBC_FILLROW);

        /*
         * Configure frame
         */
        frame.getContentPane().add(pnlContent);
        frame.setTitle("GridBagLayout Weight Bug?");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400,200);
        frame.setVisible(true);
    }

    JComponent createRulerCell(Color border, Color background) {
        JPanel glue = new JPanel();
        glue.setBorder(BorderFactory.createLineBorder(border));
        glue.setBackground(background);

        return glue;
    }

    private JButton createButton(String text) {
        JButton button = new JButton(text);
        button.setPreferredSize(new Dimension(0, button.getPreferredSize().height));
        return button;
    }

}