如何为嵌套的JPanels选择最佳布局?

时间:2017-08-03 17:28:49

标签: java swing layout-manager

我计划设计一个gui程序,其中包含一个外部JPanel,其中包含大量具有文本和按钮的循环JPanel。但是,我无法确定哪个布局适合此任务。我希望它像这个:

enter image description here

我只是复制并粘贴了第一个JPanel,它会像你在图片中看到的那样以编程方式重新编辑。 我应该使用哪些布局来获得这样的结果?

1 个答案:

答案 0 :(得分:3)

在我看来,它看起来像这样:

JScrollPane> JPanel (outerPane)> JPanel (innerPane [many])

基于此,我们需要考虑使用哪个布局管理器outerPane以及innerPane s ...

为了提供innerPane之间的间距,我会选择GridLayout (rows, columns, hgap, vgap)

GridLayout(0, 1, 5, 5);

现在每个innerPane我们可以选择GridLayoutGridBagLayoutFlowLayout,让我们看看每个会发生什么:

  • 如果我们使用FlowLayout,那么组件就不会像布局一样处于“网格”或“表格”中,所以,这是不可能的......这就是它的样子: / p>

    enter image description here

    尽管他们看起来像我们需要的东西,但我不确定每个标签是否会随着时间的推移而改变,但你可以试试......

    • 使用GridLayout会使我们的JButton占据单元格的整个空间,并且看起来不太好(至少在调整大小时),这里是前后的图像调整GUI大小以显示我的意思(裁剪为不在帖子中使用大量空间):

    enter image description here

    如果您的GUI不会调整大小,您可以使用此路径,如果可以,那么您应该进行另一种布局。

      在这种情况下,
    • GridBagLayout是我最喜欢的,因为每个标签都会留在自己的列中,按钮不会填满所有可用空间,我们的GUI看起来更像你发布的图像:

    enter image description here

    在上面的示例中,我使用了CustomBorder类来提供innerPaneouterPane之间的间距,同时还提供了彩色边框以及显示垂直{{1}永远。

    产生这些输出的代码是:

    JScrollPane

使用边框样式来获得所需的边框样式,我在GUI上绘制了一个-1像素的边框,如果我不这样做,它只会显示左边和上边框...

  • 另一种选择是使用package sof; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Insets; import java.awt.geom.Rectangle2D; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.SwingUtilities; import javax.swing.border.AbstractBorder; public class NestedPanels { private JFrame frame; private JPanel outerPane; private JPanel innerPane; private GridBagConstraints gbc; private JScrollPane scrollPane; public static void main(String[] args) { SwingUtilities.invokeLater(new NestedPanels()::createAndShowGui); } private void createAndShowGui() { frame = new JFrame(getClass().getSimpleName()); outerPane = new JPanel(); outerPane.setLayout(new GridLayout(0, 1, 5, 5)); for (int i = 0; i < 5; i++) { innerPane = new JPanel(); innerPane.setLayout(new GridBagLayout()); gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.BOTH; gbc.insets = new Insets(10, 10, 10, 10); innerPane.add(new JLabel("Recurring JLabel1"), gbc); gbc.gridx++; innerPane.add(new JLabel("Recurring JLabel2"), gbc); gbc.gridx++; innerPane.add(new JLabel("Recurring JLabel3"), gbc); gbc.gridx++; innerPane.add(new JButton("Recurring JButton1"), gbc); innerPane.setBorder(BorderFactory.createLineBorder(Color.BLACK)); outerPane.add(innerPane); } outerPane.setBorder(new CustomBorder(5, Color.BLACK)); scrollPane = new JScrollPane(outerPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); frame.add(scrollPane); frame.pack(); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } @SuppressWarnings("serial") class CustomBorder extends AbstractBorder { private int gap; private Color color; public CustomBorder(int gap, Color color) { this.gap = gap; this.color = color; } @Override public Insets getBorderInsets(Component c) { return new Insets(gap, gap, gap, gap); } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { super.paintBorder(c, g, x, y, width, height); Graphics2D g2d = (Graphics2D) g; g2d.setColor(color); g2d.draw(new Rectangle2D.Double(x, y, width - 1, height - 1)); } } } ,但我留给你