【问题标题】:GridBagLayout and minimum widthGridBagLayout 和最小宽度
【发布时间】:2013-07-25 11:53:39
【问题描述】:

我想制作限制最大宽度的面板,但是当容器变短时会减小其宽度。

我使用了GridBagLayout,但是当大小变得足够短时,它的行为很奇怪。

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

import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Michael Nesterenko
 *
 */
public class SSCE extends JFrame {

    /**
     * 
     */
    public SSCE() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        GridBagLayout gbl = new GridBagLayout();
        gbl.columnWidths = new int[] {200, 1};
        gbl.columnWeights = new double[] {0, 1};
        gbl.rowHeights = new int[] {10};
        gbl.rowWeights = new double[] {0};
        setLayout(gbl);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;

        JPanel sizeRestrictedPanel = new JPanel();
        sizeRestrictedPanel.setBackground(Color.BLUE);
        sizeRestrictedPanel.setMinimumSize(new Dimension(50, 50));
        sizeRestrictedPanel.setMaximumSize(new Dimension(300, 50));
        sizeRestrictedPanel.setPreferredSize(new Dimension(300, 50));
        add(sizeRestrictedPanel, gbc);

        JPanel dummy = new JPanel();
        dummy.setBackground(Color.RED);
        add(dummy, gbc);

        setPreferredSize(new Dimension(600, 200));
        pack();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new SSCE().setVisible(true);
    }

}

当框架宽度变得足够短时,蓝色面板会立即调整大小,但是我希望它能够随着窗口大小调整而平滑调整。

【问题讨论】:

  • 使用setXxXSize() 方法也可能是罪魁祸首。如果您可以提供一张关于您对结果的期望的小图片,那将很有帮助:-)
  • @nIcEcOw,我希望blue 面板在框架窗口足够大时有一些限制宽度,但是当窗口变短时(所以blue 面板不再适合)blue面板的宽度变得等于窗口的宽度并且平滑地调整大小。目前它只是跳到一些较小的值。
  • 请查看answer,看看这是否也与您的情况相似。对于调整大小,您可以考虑使用 ComponentListener 并将其附加到您的 Blue JPanel

标签: java swing gridbaglayout


【解决方案1】:

您可以定义GridBagConstraints.ipadxGridBagConstraints.ipady 约束来设置最小宽度/高度

/**
 * This field specifies the internal padding of the component, how much
 * space to add to the minimum width of the component. The width of
 * the component is at least its minimum width plus
 * <code>ipadx</code> pixels.
 * <p>
 * The default value is <code>0</code>.
 * @serial
 * @see #clone()
 * @see java.awt.GridBagConstraints#ipady
 */
public int ipadx;

/**
 * This field specifies the internal padding, that is, how much
 * space to add to the minimum height of the component. The height of
 * the component is at least its minimum height plus
 * <code>ipady</code> pixels.
 * <p>
 * The default value is 0.
 * @serial
 * @see #clone()
 * @see java.awt.GridBagConstraints#ipadx
 */
public int ipady;

【讨论】:

    【解决方案2】:

    当用户缩小窗口的宽度时,首先只有红色面板缩小。

    问题中的代码示例实际上是从一个超出打包组件给定大小的扩展窗口开始的。如果我们删除setPreferredSize(new Dimension(600, 200)); 行,那么我们会得到如下所示的窗口,而不是带有扩展红色面板的窗口。如果我们将宽度减小到小于这个大小,那么我们会强制蓝色面板小于它的首选大小并且“它的行为很奇怪”。这是因为 GridBagLayout 不再支持蓝色面板的首选大小,它现在为每个面板提供相等的空间,并尝试支持它们的最小尺寸。

    我建议不要将 setPreferredSize 与 GridBagLayout 一起使用。 您可能希望确定您的窗口仍然有用所需的最小尺寸,并且不允许用户将尺寸减小到此最小值以下。某些组件不应占用比用户展开窗口时最初分配的空间更多的空间。我们可以使用 GridBagConstraints weightx 和 weighty 而不是 setMaximumSize 来实现这一点。

    下面的代码显示了两个面板的平滑调整大小,我添加了一些文本来显示调整大小时的尺寸。

    import java.awt.*;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.*;
    
    /**
     * @author Michael Nesterenko, Leon LaSpina
     *
     */
    public class SSCE extends JFrame {
       JLabel blueDimension, redDimension;
       JPanel sizeRestrictedPanel, dummyPanel, bottomPanel;
    
       public SSCE() {
          setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          JPanel testPanel = new JPanel();
          bottomPanel = new JPanel();
          setLayout(new BorderLayout());
          GridBagLayout gbl = new GridBagLayout();
          testPanel.setLayout(gbl);
          add(testPanel, BorderLayout.CENTER);
          add(bottomPanel, BorderLayout.SOUTH);
          GridBagConstraints gbc = new GridBagConstraints();
          gbc.fill = GridBagConstraints.HORIZONTAL;
          gbc.weightx = 0.75;
    
          sizeRestrictedPanel = new JPanel();
          sizeRestrictedPanel.setBackground(Color.BLUE);
          sizeRestrictedPanel.setMinimumSize(new Dimension(50, 50));
          sizeRestrictedPanel.setMaximumSize(new Dimension(300, 50));
          //sizeRestrictedPanel.setPreferredSize(new Dimension(300, 50));
          testPanel.add(sizeRestrictedPanel, gbc);
          dummyPanel = new JPanel();
          dummyPanel.setBackground(Color.RED);
          dummyPanel.setMinimumSize(new Dimension(50, 50));
          //dummyPanel.setPreferredSize(new Dimension(50, 50));
          gbc.weightx = 0.25;
          testPanel.add(dummyPanel, gbc);
    
          setSize(new Dimension(600, 200));
          blueDimension = new JLabel("------");
          blueDimension.setForeground(Color.BLUE);
          redDimension = new JLabel("------");
          redDimension.setForeground(Color.RED);
          bottomPanel.add(blueDimension);
          bottomPanel.add(new JLabel("   "));
          bottomPanel.add(blueDimension);
          bottomPanel.add(redDimension);
          this.addComponentListener(new ComponentAdapter() {
             public void componentResized(ComponentEvent e) {
                updateDimensionText();
             }
          });
       }
    
       private void updateDimensionText() {
          Dimension d1 = sizeRestrictedPanel.getSize();
          String s1 = d1.width + "," + d1.height;
          Dimension d2 = dummyPanel.getSize();
          String s2 = d2.width + "," + d2.height;
          blueDimension.setText(s1);
          redDimension.setText(s2);
       }
    
       /**
        * @param args
        */
       public static void main(String[] args) {
          SSCE win = new SSCE();
          win.setVisible(true);
          win.updateDimensionText();
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-08
      • 2012-11-13
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-31
      • 2013-05-14
      相关资源
      最近更新 更多