将宽度固定为GridBagLayout

时间:2011-07-27 10:03:33

标签: java swing layout-manager gridbaglayout

enter image description here

我正在使用GridBagLayout创建一个看起来像图片中的StatusBar。我有4个区域,所以我在第一个区域有一个按钮,然后是第二个区域中的信息消息,然后我又想要两个(我还有第五个用于制作角落)。

按钮区域非常合适,因为内容始终是宽度相同的按钮。与角落区域相同。信息区域必须获得所有可用空间。第3和第4个区域必须具有固定值,与屏幕大小无关。

我该怎么做?

我目前的代码是:

public MyStatusBar() {
        setLayout(new GridBagLayout());
        setPreferredSize(new Dimension(getWidth(), 23));
        GridBagConstraints c = new GridBagConstraints();

        botonDispositivo = new JButton("");
        this.setText(0, "Disconnected");
        URL imageUrl = getClass().getResource("resources/22x22/dispositivo01.png");
        this.setButtonImg(imageUrl);
        this.setButtonEnabled(false);


        c.gridx = 0;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        c.anchor = GridBagConstraints.WEST;
        c.gridwidth = 1;
        c.gridheight = 1;
        this.add(botonDispositivo, c);

        c.insets= new Insets(0,10,0,0);
        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.7;
        c.fill = GridBagConstraints.HORIZONTAL;
        msgLabel = new JLabel("");
        msgLabel.setPreferredSize(new Dimension(500, msgLabel.getHeight()));
        this.add(msgLabel, c);
        this.setText(1, "Waiting for potentiostat conection");

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        this.add(new SeparatorPanel(Color.GRAY, Color.WHITE), c);

        c.gridx ++;
        c.gridy = 0;
        c.fill = GridBagConstraints.NONE;
        c.weightx = 0.0;
        overErrorLabel = new JLabel("");
        overErrorLabel.setSize(new Dimension(150, overErrorLabel.getHeight()));
        this.add(overErrorLabel, c);
        //this.setText(2, "");

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        this.add(new SeparatorPanel(Color.GRAY, Color.WHITE), c);

        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.NONE;
        c.anchor = GridBagConstraints.EAST;
        timeLabel = new JLabel("");
        timeLabel.setMinimumSize(new Dimension(150, timeLabel.getHeight()));
        //timeLabel.setMaximumSize(new Dimension(150, timeLabel.getHeight()));
        this.add(timeLabel, c);
        //this.setText(3, "");


        JPanel rightPanel = new JPanel(new GridBagLayout());
        c.gridx ++;
        c.gridy = 0;
        c.weightx = 0.0;
        c.fill = GridBagConstraints.BOTH;
        rightPanel.add(new JLabel(new AngledLinesWindowsCornerIcon()), c);
        rightPanel.setOpaque(false);

        c.gridx ++;
        c.gridy = 0;
        c.fill = GridBagConstraints.BOTH;
        this.add(rightPanel, c);

        setBackground(SystemColor.control);
      }

3 个答案:

答案 0 :(得分:12)

您可以为不同的标签设置首选,最小,最大等大小。 我认为你需要的只是设置权重X> 0并填充param = HORIZONTAL约束你想要调整大小的标签,weightX = 0和fill-NONE用于你不想调整大小的标签。

还可以使用ipadx指定标签的最小尺寸。

答案 1 :(得分:4)

为了更好和最简单地输出到GUI,可以更好地查找Borderlayout

JPanel#setPrefferedSize(200, 30); JButton Icon WEST areaJPanel#setPrefferedSize(200, 30);和JLabel加入EAST area

JPanel(右侧窗格)到CENTER area

将另一个{{1}}添加到{{1}}

答案 2 :(得分:4)

如果希望GridBagLayout中的单元格在宽度(或高度)上固定,那么就有一个可行的解决方案。假设您希望(x,y)处的单元格在宽度上固定,但其中的JLabel具有可变内容,必须在运行时更改。如果JLabel需要更改大小,则使用GridBagLayout将重新定位其他组件,从而强制调整包含单元格的大小。要解决此问题,您可以执行以下操作之一:

  • 您可以在第x个单元格包含虚拟JPanel的布局中添加一个额外的行(y + 1),并在该JPanel上调用.setPreferredSize(new Dimension(desiredWidth, 0));
  • 相同,但不是设置preferredSize,而是在添加此虚拟面板时在GridBagConstraints对象上设置insets。因此,如果您想要固定宽度,请执行gbc.insets = new Insets(0,preferredWidth,0,0);gbc.insets = new Insets(0,0,0,preferredWidth);。这样,面板本身的尺寸为(0,0),但是包含的单元格将被强制为您指定的宽度(因为插图是从组件中看到的外部填充)。

第一个要求你调用setPreferredSize(),这总让我感到不舒服,因为你正在搞乱LayoutManager的任务。因此,我更喜欢后一种解决方案,但由于您的假面板没有尺寸,您将无法看到您的单元格。在前一种解决方案中,您可以通过为面板提供背景颜色来使单元格可见。

这种方法的好处在于您无需为JLabel上的设置大小而烦恼,特别是在显示之前未知的高度。您无法在JLabel上设置preferredSize,因为您不知道它必须具有哪个高度(平台相关,依赖于字体等)。您只需添加它,并使用虚拟面板和虚拟面板将强制包含JLabel的单元格与desiredWidth一样宽。

这个解决方案的工作原理是JLabel的宽度不会超过desiredWidth,因为在这种情况下,单元格也会增长。您总是可以在JLabel上放置一个maximumSize来解决这个问题(这里没有未知高度的问题 - 对于最大高度,您可以使用Integer.MAX_VALUE)。

同样的故事适用于高度,只需引入一个虚拟列,并在发生问题的行中的单元格中添加一个维度为JP(= 0,preferredHeight)的虚拟JPanel。

这种方法的缺点:你必须使用虚拟组件,这绝不是最好的方法,但它在这里运作得很好。