Java 如何获得带有空 JLabel 的 JPanel 以占用 GridBagLayout 中的空间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19738402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I get a JPanel with an empty JLabel to take up space in a GridBagLayout
提问by restin84
I am working on a GUI for a project at school. I am using a GridBagLayout in swing.
我正在为学校的一个项目开发 GUI。我在 Swing 中使用 GridBagLayout。
I want to have a label indicating the input(a type of file @ x = 0, y = 0), followed by another label(the actual file name once selected @ x = 1, y = 0
), followed by a browse button for a file chooser( @ x = 2, y = 0
). The label at (1,0)
is initially blank, however I want the area that the text will occupy to take up some space when the label contains no text. I also want the space between the label at (0,0)
and the button at (2,0)
to remain constant.
我想要一个指示输入的标签(文件类型@ x = 0,y = 0),然后是另一个标签(选择@ 后的实际文件名x = 1, y = 0
),然后是文件选择器的浏览按钮(@ x = 2, y = 0
) . 标签 at(1,0)
最初是空白的,但是当标签不包含文本时,我希望文本将占据的区域占用一些空间。我还希望标签 at(0,0)
和按钮 at之间的空间(2,0)
保持不变。
To achieve this, I'm trying to put the label onto a panel and then play with the layouts. However I can't seam to achieve the desired results. Could anyone offer some suggestions? The next three rows of the GridBagLayout will be laid out exactly the same way.
为了实现这一点,我试图将标签放在面板上,然后使用布局。但是我无法缝合以达到预期的结果。有人可以提供一些建议吗?GridBagLayout 的接下来三行将以完全相同的方式布局。
Here is a link to a screen shot of the GUI.
这是指向 GUI 屏幕截图的链接。
calibrationFileSelectionValueLabel = new JLabel("",Label.LEFT);
calibrationFileSelectionValueLabel.setName("calibrationFileSelection");
calibrationFileSelectionValueLabel.setMinimumSize(new Dimension(100,0));
calibrationFileSelectionValuePanel = new JPanel();
calibrationFileSelectionValuePanel.setBorder(BorderFactory.createEtchedBorder());
calibrationFileSelectionValuePanel.add(calibrationFileSelectionValueLabel);
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.NONE;
filesPanel.add(calibrationFileLabel,c);
c.gridy = 1;
filesPanel.add(frequencyFileLabel,c);
c.gridy = 2;
filesPanel.add(sampleFileLabel,c);
c.gridy = 3;
filesPanel.add(outputFileLabel,c);
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
// filesPanel.add(calibrationFileSelection,c);
filesPanel.add(calibrationFileSelectionValuePanel,c);
c.gridy = 1;
// filesPanel.add(frequencyFileSelection,c);
filesPanel.add(frequencyFileSelectionValueLabel,c);
c.gridy = 2;
// filesPanel.add(sampleFileSelection,c);
filesPanel.add(sampleFileSelectionValueLabel,c);
c.gridy = 3;
// filesPanel.add(outputFileSelection,c);
filesPanel.add(outputFileSelectionValueLabel,c);
c.gridx = 2;
c.gridy = 0;
c.fill = GridBagConstraints.NONE;
filesPanel.add(calibrationFileSelectionButton,c);
c.gridy = 1;
filesPanel.add(frequencyFileSelectionButton,c);
c.gridy = 2;
filesPanel.add(sampleFileSelectionButton,c);
c.gridy = 3;
filesPanel.add(createOutputFileButton,c);
panelForFilesPanelBorder = new JPanel();
panelForFilesPanelBorder.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(5,10,5,10), BorderFactory.createEtchedBorder()));
panelForFilesPanelBorder.add(filesPanel);
buttonsPanel = new JPanel();
buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
buttonsPanel.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(5,10,10,10), BorderFactory.createEtchedBorder()));
buttonsPanel.add(startButton);
buttonsPanel.add(stopButton);
basePanel.add(panelForFilesPanelBorder);
basePanel.add(numericInputPanel);
basePanel.add(buttonsPanel);
采纳答案by Sage
Well, Essentially, GridBagLayout places components in rectangles (cells) in a grid, and then uses the components' preferred sizes
to determine how big the cells should be. With this layout:
嗯,本质上,GridBagLayout 将组件放置在网格中的矩形(单元格)中,然后使用组件preferred sizes
来确定单元格应该有多大。有了这个布局:
- if the container's size is smallerthan the preferred size only thenthe minimum size gets used.
- With empty(
""
) text AJLabel\JTextFeild\JButton
's preferred size is around(2,2)
, if no preferred size hints is given to it explicitly usingsetPreferredSize(size)
or overridinggetPreferredSize(size)
.
- 如果容器的大小小于首选大小,则仅使用最小大小。
- 使用 empty(
""
) 文本 AJLabel\JTextFeild\JButton
的首选大小约为(2,2)
,如果没有显式使用setPreferredSize(size)
或覆盖的首选大小提示getPreferredSize(size)
。
At his point setting minimum size will not work, as the preferred size with empty text is around (2,2)
and container's size is already larger than the preferred size. GridBagLayout
uses the preferred size not worrying about the minimum size at all.
此时设置最小尺寸将不起作用,因为带有空文本的首选尺寸就在附近,(2,2)
并且容器的尺寸已经大于首选尺寸。GridBagLayout
使用首选大小根本不用担心最小大小。
You actually need to set both preferred and minimum size with GridBagLayout
because:
您实际上需要同时设置首选和最小尺寸,GridBagLayout
因为:
If you try setting onlythe preferred size, shrinking the size of the window would eventually cause the container panel's size to get shrink. The container's panel size will be smallerthan the preferred size of the component and the JLabel\JTextFeild\JButton
shrink to their minimum size. If you haven't given minimum size hints at this point, the default minimum size: likely to be around (2,2)
gets used. You will understand better with given working example below.
如果您尝试仅设置 首选大小,缩小窗口的大小最终会导致容器面板的大小缩小。容器的面板尺寸将小于组件的首选尺寸,并JLabel\JTextFeild\JButton
缩小到它们的最小尺寸。如果此时您还没有给出最小尺寸提示,则使用默认的最小尺寸:可能在附近(2,2)
。通过下面给定的工作示例,您将更好地理解。
Some other things to note:
其他一些注意事项:
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
// filesPanel.add(calibrationFileSelection,c);
filesPanel.add(calibrationFileSelectionValuePanel,c);
you are adding the panel
which contains your calibrationFileSelectionValueLabel
. You don't need to use an extra panel, rather just add the calibrationFileSelectionValueLabel
directly to the grid by setting( instead overriding getPreferedSize(Size)
is preferable) preferredSize
. However try setting inset to the GridBagConstraints
to look your first panel
a little more nicer:
您正在添加panel
包含您的calibrationFileSelectionValueLabel
. 您不需要使用额外的面板,而只需calibrationFileSelectionValueLabel
通过设置将直接添加到网格中(而不是覆盖getPreferedSize(Size)
更可取)preferredSize
。但是尝试将 inset 设置为使GridBagConstraints
您的第panel
一个看起来更好一点:
gridBagCnst.insets = new Insets(3, 3, 3, 3);
A minimal working example for you:
一个最小的工作示例:
In case you are not getting what we are saying, this example i have set only preferred size for resolving your problem. But as i haven't set minimum size, try resizing the window to match with above explanation.
如果您没有得到我们所说的,这个例子我只设置了首选大小来解决您的问题。但由于我没有设置最小尺寸,请尝试调整窗口大小以符合上述说明。
Source code:
源代码:
import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.border.*;
/**
*
* @author Rashed
*/
class GridBagLayoutDemo extends JFrame{
public JLabel createLabel(String txt, int width, int height, Color color)
{
JLabel label = new JLabel(txt);
label.setOpaque(true);
label.setBackground(color);
label.setPreferredSize(new Dimension(width, height));
return label;
}
public GridBagLayoutDemo() throws HeadlessException {
// setSize(400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new java.awt.GridBagLayout());
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
GridBagConstraints labCnst = new GridBagConstraints();
Dimension preferredSize = new Dimension(140,20);
labCnst.insets = new Insets(3, 3, 3, 3);
JLabel title = new JLabel("My Title");
JLabel title2 = new JLabel("My Title");
JLabel title3 = new JLabel("My Title");
JLabel selectionLabel1 = new JLabel("");
selectionLabel1.setBorder(new LineBorder(Color.BLACK));
JLabel selectionLabel2 = new JLabel("");
selectionLabel2.setBorder(new LineBorder(Color.BLACK));
JLabel selectionLabel3 = new JLabel("");
selectionLabel3.setBorder(new LineBorder(Color.BLACK));
selectionLabel1.setPreferredSize(preferredSize);
selectionLabel2.setPreferredSize(preferredSize);
selectionLabel3.setPreferredSize(preferredSize);
JButton browse1 = new JButton("Browse");
JButton browse2 = new JButton("Browse");
JButton browse3 = new JButton("Browse");
labCnst.gridx = 0;
labCnst.gridy = 0;
panel.add(title, labCnst);
labCnst.gridy = 1;
panel.add(title2, labCnst);
labCnst.gridy = 2;
panel.add(title3, labCnst);
labCnst.gridx = 1;
labCnst.gridy = 0;
panel.add(selectionLabel1, labCnst);
labCnst.gridy = 1;
panel.add(selectionLabel2, labCnst);
labCnst.gridy = 2;
panel.add(selectionLabel3, labCnst);
labCnst.gridx = 3;
labCnst.gridy = 0;
panel.add(browse1, labCnst);
labCnst.gridy = 1;
panel.add(browse2, labCnst);
labCnst.gridy = 2;
panel.add(browse3, labCnst);
//labCnst.anchor = GridBagConstraints.LINE_END;
add(panel);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new GridBagLayoutDemo().setVisible(true);
}
});
}
}
回答by John Kugelman
Annoyingly, a label with no text will take up no vertical space. You can get around this by using " "
when it's empty.
令人讨厌的是,没有文本的标签不会占用垂直空间。您可以通过" "
在它为空时使用来解决此问题。
JLabel fileNameLabel = new JLabel(" ");
回答by Thomas W
As John said, put a single space in the label and/or set it's setMinimumSize()
.
正如约翰所说,在标签中放置一个空格和/或将其设置为setMinimumSize()
.
Minimum size is useful if the label is intended to be populated later, on UI activity.. prevents the UI from compacting into an ugly state when nothing is initially selected.
如果打算稍后在 UI 活动中填充标签,则最小尺寸很有用。可防止 UI 在最初未选择任何内容时压缩为丑陋的状态。
回答by Mike Clark
I modified Sage's program using John's " "
trick and added a little bit of my own GridBagConstraint
flavoring to make the dialog resize more naturally under collapse and expand.
我使用 John 的" "
技巧修改了 Sage 的程序,并添加了一点我自己的GridBagConstraint
风格,使对话框在折叠和展开时更自然地调整大小。
public class GridBagLayoutDemo extends JFrame {
public GridBagLayoutDemo() throws HeadlessException {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
JPanel panel = new JPanel(new java.awt.GridBagLayout());
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
GridBagConstraints labCnst = new GridBagConstraints();
Dimension preferredSize = new Dimension(140, 1);
labCnst.insets = new Insets(3, 3, 3, 3);
JLabel title = new JLabel("My Title");
JLabel title2 = new JLabel("My Title");
JLabel title3 = new JLabel("My Title");
final JLabel selectionLabel1 = new JLabel(" ");
selectionLabel1.setBorder(new LineBorder(Color.BLACK));
final JLabel selectionLabel2 = new JLabel(" ");
selectionLabel2.setBorder(new LineBorder(Color.BLACK));
final JLabel selectionLabel3 = new JLabel(" ");
selectionLabel3.setBorder(new LineBorder(Color.BLACK));
setPreferredWidth(selectionLabel1, 120);
setPreferredWidth(selectionLabel2, 120);
setPreferredWidth(selectionLabel3, 120);
JButton browse1 = new JButton(new AbstractAction("Browse 1") {
public void actionPerformed(ActionEvent arg0) {
selectionLabel1.setText("C:\Documents and Settings\jsmith\My Documents\Studio 2014\Projects\1");
}
});
JButton browse2 = new JButton(new AbstractAction("Browse 2") {
public void actionPerformed(ActionEvent arg0) {
selectionLabel2.setText("C:\Documents and Settings\jsmith\My Documents\Studio 2014\Projects\2");
}
});
JButton browse3 = new JButton(new AbstractAction("Browse 3") {
public void actionPerformed(ActionEvent arg0) {
selectionLabel3.setText("C:\Documents and Settings\jsmith\My Documents\Studio 2014\Projects\3");
}
});
labCnst.gridx = 0;
labCnst.gridy = 0;
panel.add(title, labCnst);
labCnst.gridy = 1;
panel.add(title2, labCnst);
labCnst.gridy = 2;
panel.add(title3, labCnst);
labCnst.weightx = 1;
labCnst.fill = GridBagConstraints.HORIZONTAL;
labCnst.gridx = 1;
labCnst.gridy = 0;
panel.add(selectionLabel1, labCnst);
labCnst.gridy = 1;
panel.add(selectionLabel2, labCnst);
labCnst.gridy = 2;
panel.add(selectionLabel3, labCnst);
labCnst.weightx = 0;
labCnst.gridx = 3;
labCnst.gridy = 0;
panel.add(browse1, labCnst);
labCnst.gridy = 1;
panel.add(browse2, labCnst);
labCnst.gridy = 2;
panel.add(browse3, labCnst);
add(panel, BorderLayout.CENTER);
pack();
}
private void setPreferredWidth(JComponent c, int w) {
Dimension d = c.getPreferredSize();
d.width = w;
c.setPreferredSize(d);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
GridBagLayoutDemo demo = new GridBagLayoutDemo();
demo.setLocationRelativeTo(null);
demo.setVisible(true);
}
});
}
}