我在使用Java的Swing布局管理器时遇到一些麻烦。这是我第一次尝试创建自己的GUI,所以我可能只是错过了一些相当简单的东西,不过我会很感激任何可以提供的建议。
我想要创建的是一个包含JLabel和JTextFields的自定义JPanel,允许用户输入一个IP地址(因此四个JTextFields与三个JLabel包含一个'。')
我发现很难找到一个可以按照我的意愿设置它的布局管理器;我已经尝试了Flow和Box布局,因为这些都没有用,我也尝试了一个GridBag,我认为这可能是矫枉过正,但即使这样做也不行。
这是启动课程的代码:
public class PingPanel extends JPanel {
private JLabel[] dotLabels;
private JTextField[] pingFields;
public PingPanel() {
Dimension dim = getPreferredSize();
dim.width = 400;
setPreferredSize(dim);
dotLabels = new JLabel[3];
for (int i = 0; i < dotLabels.length; i++) {
dotLabels[i] = new JLabel(".");
}
pingFields = new JTextField[4];
for (int i = 0; i < pingFields.length; i++) {
pingFields[i] = new JTextField(3);
}
Border panelBorder = BorderFactory.createLineBorder(Color.BLACK);
setBorder(panelBorder);
//setupFlow();
//setupBox();
//setupGridBag();
我只将面板的宽度设置为400以尝试显示所有内容(正如您稍后会看到的那样,我也没有太多运气。我知道有些经理无论如何都会忽略首选尺寸,这可能就是为什么它不起作用的原因。我创建了三种方法来尝试不同的布局管理器;在这里,他们产生的效果是:
public void setupFlow() {
for (int p = 0; p < pingFields.length; p++) {
if (p == dotLabels.length) {
add(pingFields[p]);
System.out.println(p + " (Final Column)");
}
else {
add(pingFields[p]);
add(dotLabels[p]);
System.out.println(p);
}
}
}
FlowLayout产生了这个:
这是我想要的最接近的样子,但我不确定为什么我只得到一个JTextField和一个Label。
public void setupBox() {
Container pingBox = Box.createHorizontalBox();
for (int p = 0; p < pingFields.length; p++) {
if (p == dotLabels.length) {
pingBox.add(pingFields[p]);
System.out.println(p + " (Final Column)");
}
else {
pingBox.add(pingFields[p]);
pingBox.add(dotLabels[p]);
System.out.println(p);
}
}
}
这就是BoxLayout给我的。我完全不知道我是如何搞砸这个的!
public void setupGridBag() {
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.gridy = 0;
gc.gridx = 0;
gc.weightx = 1.0;
gc.weighty = 1.0;
gc.fill = GridBagConstraints.HORIZONTAL;
add(pingFields[0], gc);
gc.gridx++;
add(dotLabels[0], gc);
gc.gridx++;
add(pingFields[1], gc);
gc.gridx++;
add(dotLabels[1], gc);
gc.gridx++;
add(pingFields[2], gc);
gc.gridx++;
add(dotLabels[2], gc);
gc.gridx++;
add(pingFields[3], gc);
}
GridBagLayout至少为我提供了我正在寻找的布局,但是我还没有弄清楚如何使JTextField更宽。
所以我们有 - 我确定我的绿色让我错过了一些明显的东西,但如果有人有任何想法,我会非常感激。
答案 0 :(得分:0)
通常GridBagLayout
就是你所追求的。将其视为基于网格的布局,并为每个组件定制对齐;此外,每个组件都可以占用多个列和行,从而实现完全自定义设置。
我得到了一些示例代码,如下所示:
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] {30, 30, 60, 60, 60, 30, 30};
gridBagLayout.rowHeights = new int[] {18, 18, 18, 18, 18, 18, 18, 18, 18};
gridBagLayout.columnWeights = new double[] {0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1};
gridBagLayout.rowWeights = new double[] {0.125, 0.125, 0.1, 0.1, 0.1, 0.1, 0.1, 0.125, 0.125};
setLayout(gridBagLayout);
JLabel labelLong = new JLabel("Long");
labelLong.setForeground(Color.DARK_GRAY);
labelLong.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
GridBagConstraints gbc_labelLong = new GridBagConstraints();
gbc_labelLong.insets = new Insets(0, 0, 5, 5);
gbc_labelLong.gridx = 0;
gbc_labelLong.gridy = 0;
add(labelLong, gbc_labelLong);
JLabel labelShort = new JLabel("Short");
labelShort.setForeground(Color.DARK_GRAY);
labelShort.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
GridBagConstraints gbc_labelShort = new GridBagConstraints();
gbc_labelShort.insets = new Insets(0, 0, 5, 0);
gbc_labelShort.gridx = 6;
gbc_labelShort.gridy = 0;
add(labelShort, gbc_labelShort);
如果你只是在一个简单的布局之后,那么BorderLayout
就是你要做的。将固定尺寸组件放在侧面,将主要组件放在中心位置。
另外,值得一提的是,Java使用每个组件的setPreferredSize()
来指定其他大小参数,因此GUI布局将尽力满足每个组件的首选大小。在构造完成后调用JFrame.pack()
来安排组件。