Java GridBagLayout中的固定宽度
我正在使用GridBagLayout制作一个状态栏,如图所示。我有4个区域,所以我在第一个区域有一个按钮,然后在第二个区域有一个信息消息,然后我还想要两个(我还有第五个区域来转弯) 按钮区域非常适合,因为内容始终是具有相同宽度的按钮。角区也一样。信息区必须获得所有可用空间。第三和第四区域必须具有固定值,与屏幕大小无关 我该怎么做 我目前的代码是:Java GridBagLayout中的固定宽度,java,swing,layout-manager,gridbaglayout,Java,Swing,Layout Manager,Gridbaglayout,我正在使用GridBagLayout制作一个状态栏,如图所示。我有4个区域,所以我在第一个区域有一个按钮,然后在第二个区域有一个信息消息,然后我还想要两个(我还有第五个区域来转弯) 按钮区域非常适合,因为内容始终是具有相同宽度的按钮。角区也一样。信息区必须获得所有可用空间。第三和第四区域必须具有固定值,与屏幕大小无关 我该怎么做 我目前的代码是: public MyStatusBar() { setLayout(new GridBagLayout()); setP
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);
}
您可以为不同的标签设置首选、最小、最大等尺寸。 我认为您只需要为要调整大小的标签设置约束的weight X>0和fill param=水平,为不想调整大小的标签设置weight X=0和fill NONE
还可以使用ipadx指定标签的最小大小。要更好、最简单地输出到GUI,最好查找
边界布局
JPanel#setpreferedsize(200,30)代码>用于带有图标的JButton
,并将JLabel置于西区
JPanel#setpreferedsize(200,30)代码>(右面板)至东部区域
将另一个JPanel
放置到中心区域
如果您希望GridBagLayout中的单元格在宽度(或高度)上固定,则有一个可行的解决方案。假设您希望(x,y)处的单元格宽度固定,但其中的JLabel具有可变内容,必须在运行时更改这些内容。如果JLabel需要更改大小,那么使用GridBagLayout将重新定位其他组件,从而强制调整包含单元格的大小。要解决此问题,您可以执行以下操作之一:
- 您可以在第X个单元格包含虚拟JPanel的布局中添加额外的行(y+1),并在该JPanel上调用
.setPreferredSize(新维度(desiredWidth,0))代码>李>
- 相同,但不是设置preferredSize,而是在添加此虚拟面板时使用的GridBagConstraints对象上设置插图。因此,如果您想要固定宽度,只需执行
gbc.insets=newinsets(0,preferredWidth,0,0)代码>或gbc.insets=新插入(0,0,0,首选宽度)代码>。这样,面板本身的尺寸为(0,0),但包含的单元格将强制为您指定的宽度(因为从组件上看,插图是外部填充)
第一个要求您调用setPreferredSize(),这总是让我感到不舒服,因为您正在干扰LayoutManager的任务。因此,我更喜欢后一种解决方案,但由于虚拟面板没有大小,您将无法可视化单元格。在前一种解决方案中,您可以通过为面板提供背景色使单元格可见
这种方法的好处是,您不必费心在JLabel上设置大小,尤其是在显示之前未知的高度。无法在JLabel上设置preferredSize,因为您不知道它必须具有的高度(取决于平台、字体等)。您只需添加它,使用虚拟行和虚拟面板将强制包含JLabel的单元格与desiredWidth
一样宽
如果JLabel的宽度不会超过desiredWidth
,则此解决方案有效,因为在这种情况下,单元也会增长。您始终可以在JLabel上放置一个maximumSize来解决这个问题(这里您没有未知高度的问题-对于最大高度,您可以使用Integer.MAX_值)
高度也是一样,只需引入一个虚拟列,并在出现问题的行的单元格中添加一个维度为(0,preferredHeight)的虚拟JPanel
这种方法的缺点是:您必须使用虚拟组件,这从来不是最好的方法,但在这里效果很好。看起来不错,但有一个问题:当标签为空时,ipadx是区域宽度。但是当我写进标签时,它的宽度是100px,这个区域的宽度是100px+ipadx。我希望它始终保持ipadx宽度,我应该如何做到这一点?从javadoc:ipadx中,此字段指定组件的内部填充,以及添加到组件最小宽度的空间。组件的宽度至少为其最小宽度加上ipadx像素。所以这取决于你的内容的最小大小。是的,我已经知道它为什么会这样,我希望它有一个固定的宽度,独立于标签宽度(总是更小)。当label width=0时,您的解决方案是正常的,但当写入某些内容时,出现所描述的问题。是否有任何方法可以动态地将ipadx值更改为“constant_value-label.getWidth()”?是否最好指定标签的最小/最大/首选大小,而根本不使用标签?或者只重写标签的getMinimumSize()以始终返回0