如何使用标准Java布局管理器纠正/居中GridLayout?

以下代码表示问题。 由于我有南北面板的高度设置,其余部分使用GridLayout进入中心面板。 我认为,因为它不能在它的行之间平等地共享剩余的像素,所以它只留下它们。 因此,在下面的代码中,我们在南面板上有一条丑陋的白线。

我的问题是:如何确保GridLayout不占用整个空间时至少居中?

通常情况下,我会使用TableLayout并对情况进行排序,但由于我正在编写答案,因此我只想使用标准管理器。 事先知道这对我来说非常有用。

例:

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.GridLayout; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; public class AligningButonsTest { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame(); f.setSize(800, 600); double CONSTANT_FACTOR = .1; int noOfRows = 5; JPanel centerP = new JPanel(new GridLayout(noOfRows,1)); for(int i = 0; i < noOfRows; i++) { BoxPanel bP = new BoxPanel(); centerP.add(bP); } JPanel contentPane = new JPanel(new BorderLayout()); f.setContentPane(contentPane); contentPane.add(centerP, BorderLayout.CENTER); JPanel southP = new JPanel(); southP.setBackground(Color.RED.darker());//southP.setOpaque(false); southP.setPreferredSize(new Dimension(1, (int)(CONSTANT_FACTOR* f.getHeight()))); contentPane.add(southP, BorderLayout.SOUTH); JPanel northP = new JPanel(); northP.setBackground(Color.RED.darker());//northP.setOpaque(false); northP.setPreferredSize(new Dimension(1, (int)(CONSTANT_FACTOR* f.getHeight()))); contentPane.add(northP, BorderLayout.NORTH); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }); } } class BoxPanel extends JPanel { public BoxPanel() { setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.RED)); setBackground(Color.DARK_GRAY); } } 

BoxLayout使用Box.createVerticalGlue()在组件之间分配空间方面做得非常好。 此示例使用Box.createVerticalStrut() ,top和bottom。 如何使用BoxLayout:使用不可见组件作为填充程序中描述了间隔

附录: BoxTest2是一种变体,它使用BoxLayout创建固定尺寸的边缘面板和垂直胶水,以更均匀地分布空间。 Box.Filler也可用于控制“剩余”垂直空间。

 /** @see http://stackoverflow.com/questions/6072956 */ public class BoxTest2 { private static final int WIDE = 480; private static final int HIGH = WIDE / 8; private static final int ROWS = 5; private static final Box center = new Box(BoxLayout.Y_AXIS); public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); center.setOpaque(true); center.setBackground(Color.lightGray); center.add(Box.createVerticalGlue()); center.add(new EdgePanel()); for (int i = 0; i < ROWS; i++) { center.add(new BoxPanel()); } center.add(new EdgePanel()); center.add(Box.createVerticalGlue()); f.add(center, BorderLayout.CENTER); f.pack(); f.setVisible(true); } }); } private static class EdgePanel extends JPanel { public EdgePanel() { Dimension d = new Dimension(WIDE, 2 * HIGH / 3); setPreferredSize(d); setBackground(Color.red.darker()); } } private static class BoxPanel extends JPanel { public BoxPanel() { setPreferredSize(new Dimension(WIDE, HIGH)); setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.red)); setBackground(Color.darkGray); } } } 

如何确保当GridLayout没有占据整个空间时它至少居中?

 JPanel wrapper = new JPanel( new GridBagLayout() ); wrapper.add( centerP ); contentPane.add(wrapper, BorderLayout.CENTER); //contentPane.add(centerP, BorderLayout.CENTER); 

您是否可以尝试将此中心面板嵌套在BorderLayout.North或甚至FlowLayout.Center中。

我的意思是:JPanel holder = new JPanel(new BorderLayout()); holder.add(centerP,BorderLayout.NORTH); contentPane.add(holder,BorderLayout.CENTER);

我无法准确地看到您的问题,因此很难编写解决方案。