有没有办法强制GridLayout留下空单元格?

我有一个JTabbedPane,其中2个JPanels设置为GridLayout(13,11)。 第一个JPanel有足够的单元格填充它离开空单元格。 在此处输入图像描述

第二个JPanel填充的单元格明显减少,这导致每个按钮被拉伸以填满整行。 在此处输入图像描述

有没有办法让GridLayout尊重空单元格,所以两个JPanels中的按钮大小相同?

使用嵌套布局来获得所需的结果。 某些布局遵循组件的首选大小,而有些则不支持。 GridLayout是其中之一。 看看这个答案 ,看看哪个人做了哪个,哪个不做。

例如,您可以将嵌套在另一个JPanel中的GridLayout的13个按钮嵌套FlowLayout

 JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING)); JPanel p2 = new JPanel(new GridLayout(13, 1)); for (int i = 0; i < 13; i++) { p2.add(new JButton("Button " + i)); } p1.add(p2); 

在此处输入图像描述

 import java.awt.FlowLayout; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class Test6 { public Test6() { JPanel p1 = new JPanel(new FlowLayout(FlowLayout.LEADING)); JPanel p2 = new JPanel(new GridLayout(13, 1)); for (int i = 0; i < 13; i++) { p2.add(new JButton("Button " + i)); } p1.add(p2); JFrame frame = new JFrame("Test Card"); frame.add(p1); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { Test6 test = new Test6(); } }); } } 

有没有办法让GridLayout尊重空单元格,所以两个JPanels中的按钮大小相同?

它当然可以使用GridLayout ,只需使用没有文本的JLabel “填充”空白方块。

EG这是两个网格布局,都填充到3行。

填充网格布局

 import java.awt.*; import java.awt.image.BufferedImage; import java.util.ArrayList; import javax.swing.*; import javax.swing.border.LineBorder; class FillGridLayout { public static final JComponent getPaddedGrid( ArrayList images, int width, int height) { JPanel p = new JPanel(new GridLayout(height, width, 2, 2)); p.setBorder(new LineBorder(Color.RED)); int count = 0; for (BufferedImage bi : images) { p.add(new JButton(new ImageIcon(bi))); count++; } for (int ii=count; ii images = new ArrayList(); int s = 16; for (int ii = s/4; ii < s; ii+=s/4) { images.add(new BufferedImage(ii, s, BufferedImage.TYPE_INT_RGB)); images.add(new BufferedImage(s, ii, BufferedImage.TYPE_INT_RGB)); } Runnable r = new Runnable() { @Override public void run() { JPanel gui = new JPanel(new BorderLayout(3,3)); gui.add(getPaddedGrid(images, 3, 3), BorderLayout.LINE_START); gui.add(getPaddedGrid(images, 4, 3), BorderLayout.LINE_END); JOptionPane.showMessageDialog(null, gui); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency SwingUtilities.invokeLater(r); } }