2011-07-27 160 views
4

enter image description here固定宽度成的GridBagLayout

我使用的GridBagLayout做一个状态栏,它看起来像的图片。我有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); 
     } 

回答

4

更好,最简单的输出到GUI是Borderlayout更好看,

JPanel#setPrefferedSize(200, 30);JButtonIcon和JLabel的投入到WEST area

JPanel#setPrefferedSize(200, 30);(rightPanel)至EAST area

把另一JPanelCENTER area

11

设置首选大小,最小maximul等为不同的标签大小。 我认为你所需要的只是设置重量X> 0,并且填充param = HORIZONTAL,用于要调整大小的标签的约束,weightX = 0,fill-NONE用于不希望调整大小的标签。

也使用ipadx指定标签的最小尺寸。

+0

看起来没问题,但有一个问题: –

+0

当标签为空时,ipadx是区域宽度。但是,当我写入标签并获得例如100px宽时,该区域获得100px + ipadx宽。我希望它始终保持ipadx宽,我该怎么做? –

+0

来自javadoc:ipadx此字段指定组件的内部填充,要添加多少空间以添加到组件的最小宽度。组件的宽度至少是其最小宽度加上ipadx像素。所以它取决于你的内容的最小尺寸。 – StanislavL

4

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

  • 您可以添加额外的行(Y + 1),其中第x单元包含一个虚拟的JPanel的布局,并在该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的最大高度)。

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

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