如何为嵌套 JPanel 选择最佳布局?
How to choose the best layouts for nested JPanels?
我打算设计一个 gui 程序,其中包含一个外部 JPanel,其中包含许多具有文本和 button.Yet 的重复 JPanel,我无法决定哪种布局适合此 task.I 希望它是这样的:
我刚刚复制并粘贴了第一个 JPanel,它将像您在图像中看到的那样以编程方式重复出现。
我应该使用哪种布局才能获得这样的结果?
在我看来是这样的:
JScrollPane
> JPanel (outerPane)
> JPanel (innerPane [many])
基于此,我们需要考虑 outerPane
将使用哪个布局管理器以及 innerPane
s...
为了在 innerPane
之间提供间距,我会选择 GridLayout (rows, columns, hgap, vgap)
,例如:
GridLayout(0, 1, 5, 5);
现在,对于每个 innerPane
,我们可以选择 GridLayout
、GridBagLayout
或 FlowLayout
,让我们看看每个
会发生什么:
如果我们使用 FlowLayout
组件将不会像 "grid" 或 "table" 这样的布局,所以,这是不行的......这个是它的样子:
虽然它们看起来像我们需要的,但我不确定每个标签是否会随着时间的推移而改变,但您可以尝试...
- 使用
GridLayout
会使我们的 JButton
占用整个 space 单元格,并且看起来不太好(至少在调整大小时),这是一个调整 GUI 大小前后的图像以显示我的意思(裁剪为不在 post 中使用大量 space):
如果您的 GUI 不会调整大小,您可以使用此路径,如果可以,那么您应该使用另一个布局。
在这种情况下,GridBagLayout
是我的最爱,因为每个标签都将保留在自己的列中,按钮不会填满所有可用的 space,我们的 GUI 看起来更像您的图像post编辑:
在上面的示例中,我使用了 CustomBorder
class 来提供 innerPane
和 outerPane
之间的间距,同时还提供了彩色边框以及始终显示垂直 JScrollPane
。
产生这些输出的代码是:
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));
}
}
}
调整边框样式以获得所需的样式,我在 GUI 上用 -1 像素绘制了边框,如果我不这样做,它只会显示左边框和上边框...
- 另一种选择是使用
JTable
但我留给你了
我打算设计一个 gui 程序,其中包含一个外部 JPanel,其中包含许多具有文本和 button.Yet 的重复 JPanel,我无法决定哪种布局适合此 task.I 希望它是这样的:
我刚刚复制并粘贴了第一个 JPanel,它将像您在图像中看到的那样以编程方式重复出现。 我应该使用哪种布局才能获得这样的结果?
在我看来是这样的:
JScrollPane
> JPanel (outerPane)
> JPanel (innerPane [many])
基于此,我们需要考虑 outerPane
将使用哪个布局管理器以及 innerPane
s...
为了在 innerPane
之间提供间距,我会选择 GridLayout (rows, columns, hgap, vgap)
,例如:
GridLayout(0, 1, 5, 5);
现在,对于每个 innerPane
,我们可以选择 GridLayout
、GridBagLayout
或 FlowLayout
,让我们看看每个
如果我们使用
FlowLayout
组件将不会像 "grid" 或 "table" 这样的布局,所以,这是不行的......这个是它的样子:虽然它们看起来像我们需要的,但我不确定每个标签是否会随着时间的推移而改变,但您可以尝试...
- 使用
GridLayout
会使我们的JButton
占用整个 space 单元格,并且看起来不太好(至少在调整大小时),这是一个调整 GUI 大小前后的图像以显示我的意思(裁剪为不在 post 中使用大量 space):
如果您的 GUI 不会调整大小,您可以使用此路径,如果可以,那么您应该使用另一个布局。
-
在这种情况下,
GridBagLayout
是我的最爱,因为每个标签都将保留在自己的列中,按钮不会填满所有可用的 space,我们的 GUI 看起来更像您的图像post编辑:
在上面的示例中,我使用了
CustomBorder
class 来提供innerPane
和outerPane
之间的间距,同时还提供了彩色边框以及始终显示垂直JScrollPane
。产生这些输出的代码是:
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)); } } }
- 使用
调整边框样式以获得所需的样式,我在 GUI 上用 -1 像素绘制了边框,如果我不这样做,它只会显示左边框和上边框...
- 另一种选择是使用
JTable
但我留给你了