GridBagLayout居中组件

时间:2018-08-23 03:57:19

标签: java swing jpanel layout-manager gridbaglayout

我已经尝试了一段时间以完成这项工作。 我在线上看过许多教程和示例,似乎无济于事。

组合框和标签都位于框架中间的正下方。

我知道必须有一个GridBagConstraints,并且每次添加新组件时都需要设置gbc。

我正在这样做,所以我不确定为什么它不起作用。

为什么还要在中心呢? 如果有的话,它不应该在左上方吗?

public class Application {
ArrayList listOfTickers = new ArrayList();
JFrame frame;
JPanel panel;
JLabel jLabel;
GridBagLayout layout;
GridBagConstraints gbc;
JComboBox comboBox;


Application(ArrayList listOfTickers) throws BadLocationException {
    this.listOfTickers = listOfTickers;

    setLabels();
    setComboBox(listOfTickers);
    setFrameAndPanel();
    addComponents();
    closeFrame();
}

private void addComponents() {
    addobjects(jLabel, panel, layout, gbc, 1, 3, 4, 2);
    addobjects(comboBox, panel, layout, gbc, 3, 0, 2, 1);
}

private void setLabels() {
    jLabel = new JLabel("test");
}

private void closeFrame() {
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

private void setComboBox(ArrayList listOfTickers) throws BadLocationException {
    comboBox = new JComboBox(listOfTickers.toArray());
    comboBox.addActionListener(e -> {
        String ticker = comboBox.getSelectedItem().toString();
    });
}

private void setFrameAndPanel() {
    frame = new JFrame("JFrame Example");
    panel = new JPanel();
    layout = new GridBagLayout();
    panel.setLayout(layout);
    frame.getContentPane().setLayout(layout);
    gbc = new GridBagConstraints();
    frame.add(panel);
    frame.setSize(600, 600);
}

public void addobjects(Component component, Container panel, GridBagLayout layout, GridBagConstraints gbc, int gridx, int gridy, int gridwidth, int gridheight) {

    gbc.gridx = gridx;
    gbc.gridy = gridy;

    gbc.gridwidth = gridwidth;
    gbc.gridheight = gridheight;

    layout.setConstraints(component, gbc);
    panel.add(component, gbc);
    } 
}

2 个答案:

答案 0 :(得分:2)

  

为什么还要在中心呢?它是否应该在左上方?

不,这是GridBagLayout的工作方式,GridBagLayout将围绕container的中心布局其组件。您可以使用weightx/y属性来更改分配给给定单元格的剩余空间。

我还建议您避免使用gridwidthgridheight,直到您对它们的作用有所了解为止,因为它们会影响组件的位置

以下内容将组件移至容器的顶部/左侧...

Top/Left

private void addComponents() {
    gbc.gridx = 1;
    gbc.gridy = 3;
    gbc.weighty = 1;
    gbc.anchor = GridBagConstraints.NORTHWEST;
    panel.add(jLabel, gbc);

    gbc.gridx = 3;
    gbc.gridy = 0;
    gbc.anchor = GridBagConstraints.WEST;
    gbc.weightx = 1;
    gbc.weighty = 0;

    panel.add(comboBox, gbc);
}

尽管,由于您要对GridBagLayout本身应用JFrame,因此我很想更改{{1}的weightx/yanchor属性}}本身,将其添加到框架中后,它将变得更加简单

  

因此,如果我想说要建立一个将按钮放置在特定区域中的计算器,实际上是将整个面板转换成一个大网格并在该网格内绘制我的容器,那将是最佳的布局,以及如何使用那?

这最终取决于您希望UI的外观。如果您只想让所有按钮均匀地占据可用空间,则也许panel是一个更好的选择...

GridLayout

GridLayout

请注意,我必须在 0 按钮周围留两个空格,这是import java.awt.EventQueue; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class Application { public static void main(String[] args) { new Application(); } public Application() { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { public TestPane() { setLayout(new GridLayout(4, 3)); String labels[] = new String[] {"7", "8", "9", "4", "5", "6", "1", "2", "3", "", "0", ""}; for (String label : labels) { if (label.trim().isEmpty()) { add(new JLabel()); } else { add(new JButton(label)); } } } } } 的要求,因为您无法控制组件实际显示在哪些单元格上,它们只是以线性方式布置。

但是,如果您希望使用看起来更像大多数计算器的工具,则需要GridLayout ...

GridBagLayout

GridBagLayout

需要动力,您需要决定是否需要灵活性而不是一致性(在这种情况下)。 import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class Application { public static void main(String[] args) { new Application(); } public Application() { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame(); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { public TestPane() { setLayout(new GridBagLayout()); String labels[][] = new String[][]{{"7", "8", "9"}, {"4", "5", "6"}, {"1", "2", "3"}}; GridBagConstraints gbc = new GridBagConstraints(); gbc.gridy = 0; for (String[] row : labels) { gbc.gridx = 0; for (String col : row) { add(new JButton(col), gbc); gbc.gridx++; } gbc.gridy++; } gbc.gridx = 0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = 3; add(new JButton("0"), gbc); } } } 非常强大和灵活,但随之而来的是复杂性。

注意:我也可以使用两个面板和两个GridBagLayout完成第二个布局-这是一个重要的概念,您不必局限于一个布局管理器,可以使用多个面板,每个面板使用不同的布局管理器并将它们“复合”在一起以产生丰富的界面

答案 1 :(得分:-2)

如果您将要进行大量的UI构建,那么下载Netbeans IDE并学习使用其GUI构建器将对您大有裨益。它是出色的GUI构建器,并且在调整布局参数时所获得的视觉反馈对于获得UI构建的帮助非常有用,尤其是对于各种GridBagLayout参数的工作原理也非常有用。与“ write-run-tweak-rerun”循环相比,该方法在实验中效率更高。

手动编写UI代码是我最不喜欢的事情。如果可能,不要对自己造成伤害!