使用JComboBox的Swing BoxLayout问题而不使用setXXXSize

这是一个SSCCE:

import java.awt.Color; import java.awt.Dimension; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JPanel; public class BoxLayoutTest extends JFrame { public BoxLayoutTest(){ JPanel main = new JPanel(); main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS)); main.setBackground(Color.red); this.add(main); JPanel northPanel = new JPanel(); JPanel middle = new JPanel(); middle.setLayout(new BoxLayout(middle, BoxLayout.X_AXIS)); middle.add(new JButton("FOO")); middle.add(Box.createHorizontalGlue()); JPanel aPanel = new JPanel(); aPanel.setBackground(Color.black); JComboBox b = new JComboBox(); //b.setPreferredSize(new Dimension(100,16)); //uncomment this to see the layout I would like to achieve //b.setMaximumSize(new Dimension(100,16)); //middle.add(b); //uncomment this line middle.setBackground(Color.green); northPanel.setBackground(Color.blue); main.add(northPanel); main.add(middle); main.add(Box.createVerticalGlue()); this.setSize(800,600); this.setResizable(true); this.setVisible(true); } public static void main(String[] args) { new BoxLayoutTest(); } } 

我正在尝试重构我前一段时间写的一些类,当时我不知道在组件上使用setXXXSize方法是错误的。 使用可resize的帧,我想要实现的结果如下:

  1. northPanel应该保持在顶部并根据框架尺寸修改改变它的尺寸(似乎工作正常)
  2. 我放置JButton的绿色面板应保持JButton的最大尺寸,并保持在上面的蓝色面板下方(如果我只将JButton放在该面板中,这可以正常工作)。

如果我在绿色面板中放置一个JComboBox(尝试取消注释SSCCE中的行),就会出现问题。 我猜JComboBox没有指定最大尺寸,因此它随框架延伸。 在我之前的错误版本的代码中,我在JComboBox上使用setxxxSize方法来限制它的维度(尝试取消注释setXXXSize方法上的行以查看它)。

我的问题是:

  1. 是否可以在不调用setXXXSize()方法的情况下使用BoxLayout实现相同的结果?
  2. 如果有,怎么样?
  3. 我可以使用其他任何LayoutManager来获得该效果吗?

请把我放在正确的方向

在报告无限制的最大高度时,JComboBox行为不端(与JTextField相同):应该永远不会显示多行。 补救措施是相同的:子类并返回合理的高度

  JComboBox b = new JComboBox() { /** * @inherited 

*/ @Override public Dimension getMaximumSize() { Dimension max = super.getMaximumSize(); max.height = getPreferredSize().height; return max; } };

只是为了好玩,这里有一个使用MigLayout的片段(这是我个人最喜欢的:-)

  // two panels as placeholders JPanel northPanel = new JPanel(); northPanel.setBackground(Color.YELLOW); JPanel southPanel = new JPanel(); southPanel.setBackground(Color.YELLOW); // layout with two content columns LC layoutContraints = new LC().wrapAfter(2) .debug(1000); AC columnContraints = new AC() // first column pref, followed by greedy gap .size("pref").gap("push") // second .size("pref"); // three rows, top/bottom growing, middle pref AC rowContraints = new AC() .grow().gap().size("pref").gap().grow(); MigLayout layout = new MigLayout(layoutContraints, columnContraints, rowContraints); JPanel main = new JPanel(layout); main.setBackground(Color.WHITE); // add top spanning columns and growing main.add(northPanel, "spanx, grow"); main.add(new JButton("FOO")); // well-behaved combo: max height == pref height JComboBox combo = new JComboBox() { @Override public Dimension getMaximumSize() { Dimension max = super.getMaximumSize(); max.height = getPreferredSize().height; return max; } }; // set a prototype to keep it from constantly adjusting combo.setPrototypeDisplayValue("somethingaslongasIwant"); main.add(combo); // add top spanning columns and growing main.add(southPanel, "spanx, grow"); 

我一直认为在jdk中使用布局管理器并不容易。 它们要么太简单又不灵活,要么格栅布局太麻烦了。 相反,我开始使用jgoodies表单布局,从来没有回头看过..看看它。 它非常简单易用。 这是一个链接:

http://www.jgoodies.com/freeware/forms/

请务必仔细阅读白皮书。

现在,我们也有谷歌为formlayout提供了一个WYSISWG编辑器作为eclipse的插件。 这只会让生活变得更轻松。

http://code.google.com/javadevtools/wbpro/palettes/swing_palette.html