如何更改JComboBox下拉列表的宽度?

我有一个可编辑的JComboBox ,其中包含单个字母值的列表。 因此,combobox非常小。

每个字母都有一个特殊的含义,在很少使用字母的情况下,有时用户不清楚。 因此我创建了一个自定义ListCellRenderer ,它显示了下拉列表中每个字母的含义。

不幸的是,这种解释不适用于下拉列表,因为它很小,因为它具有与combobox相同的宽度。

有没有办法让下拉列表比combobox更宽?

这就是我想要实现的目标:

  --------------------- | Small JCombobox | V | -------------------------------------------- | "Long item 1" | -------------------------------------------- | "Long item 2" | -------------------------------------------- | "Long item 3" | -------------------------------------------- 

我无法改变combobox的宽度,因为应用程序是旧的遗留应用程序的重新创建,其中某些东西必须与之前完全一样。 (在这种情况下,combobox必须不惜一切代价保持它的小尺寸)

我相信使用公共API执行此操作的唯一方法是编写自定义UI(有两个 error handling此问题)。

如果你只想要快速和肮脏的东西,我发现这种方式使用实现细节来做( 在这里 ):

 public void popupMenuWillBecomeVisible(PopupMenuEvent e) { JComboBox box = (JComboBox) e.getSource(); Object comp = box.getUI().getAccessibleChild(box, 0); if (!(comp instanceof JPopupMenu)) return; JComponent scrollPane = (JComponent) ((JPopupMenu) comp).getComponent(0); Dimension size = new Dimension(); size.width = box.getPreferredSize().width; size.height = scrollPane.getPreferredSize().height; scrollPane.setPreferredSize(size); // following line for Tiger // scrollPane.setMaximumSize(size); } 

把它放在PopupMenuListener ,它可能适合你。

或者您可以使用第一个链接的bug中的代码:

 class StyledComboBoxUI extends BasicComboBoxUI { protected ComboPopup createPopup() { BasicComboPopup popup = new BasicComboPopup(comboBox) { @Override protected Rectangle computePopupBounds(int px,int py,int pw,int ph) { return super.computePopupBounds( px,py,Math.max(comboBox.getPreferredSize().width,pw),ph ); } }; popup.getAccessibleContext().setAccessibleParent(comboBox); return popup; } } class StyledComboBox extends JComboBox { public StyledComboBox() { setUI(new StyledComboBoxUI()); } } 

我有点像Santhosh Kumar的WideComboBox

这是Santhosh Kumar的一个很好的解决方案,不需要弄乱UI和其他令人讨厌的东西!

http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough

 import javax.swing.*; import java.awt.*; import java.util.Vector; // got this workaround from the following bug: // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4618607 public class WideComboBox extends JComboBox{ public WideComboBox() { } public WideComboBox(final Object items[]){ super(items); } public WideComboBox(Vector items) { super(items); } public WideComboBox(ComboBoxModel aModel) { super(aModel); } private boolean layingOut = false; public void doLayout(){ try{ layingOut = true; super.doLayout(); }finally{ layingOut = false; } } public Dimension getSize(){ Dimension dim = super.getSize(); if(!layingOut) dim.width = Math.max(dim.width, getPreferredSize().width); return dim; } } 

这是tutiez的一个很好的解决方案。

在设置弹出列表的维度之前,它从中获取最大项目并计算完全显示它所需的宽度。

 public class WiderDropDownCombo extends JComboBox { private String type; private boolean layingOut = false; private int widestLengh = 0; private boolean wide = false; public WiderDropDownCombo(Object[] objs) { super(objs); } public boolean isWide() { return wide; } // Setting the JComboBox wide public void setWide(boolean wide) { this.wide = wide; widestLengh = getWidestItemWidth(); } public Dimension getSize() { Dimension dim = super.getSize(); if (!layingOut && isWide()) dim.width = Math.max(widestLengh, dim.width); return dim; } public int getWidestItemWidth() { int numOfItems = this.getItemCount(); Font font = this.getFont(); FontMetrics metrics = this.getFontMetrics(font); int widest = 0; for (int i = 0; i < numOfItems; i++) { Object item = this.getItemAt(i); int lineWidth = metrics.stringWidth(item.toString()); widest = Math.max(widest, lineWidth); } return widest + 5; } public void doLayout() { try { layingOut = true; super.doLayout(); } finally { layingOut = false; } } public String getType() { return type; } public void setType(String t) { type = t; } public static void main(String[] args) { String title = "Combo Test"; JFrame frame = new JFrame(title); String[] items = { "I need lot of width to be visible , oh am I visible now", "I need lot of width to be visible , oh am I visible now" }; WiderDropDownCombo simpleCombo = new WiderDropDownCombo(items); simpleCombo.setPreferredSize(new Dimension(180, 20)); simpleCombo.setWide(true); JLabel label = new JLabel("Wider Drop Down Demo"); frame.getContentPane().add(simpleCombo, BorderLayout.NORTH); frame.getContentPane().add(label, BorderLayout.SOUTH); int width = 200; int height = 150; frame.setSize(width, height); frame.setVisible(true); } } 

上面的代码已经成为快速测试的主要内容。 但请注意,如果您想要垂直滚动,可以将下面的语句调整为大约20

 return widest + 5; 

希望它对将来参考有用!

听起来你需要编写自己的ComboBoxUI 。

这里有一个很好的例子,展示了如何实现这一目标。

另请注意,您可能感兴趣的方法是createPopup()方法。 这是为combobox创建弹出窗口的方法,您可以在其中自定义弹出窗口。

您可能想要使用setSize()方法。

 combo.setSize(200, combo.getPreferredSize().height); 

在这里你有一段简单的代码,没有扩展JComboBox,也没有任何类

在这个例子中,下拉的总是500。 您还可以修改高度或位置。

  FaceCorrectiveReasonComboBox.getTextComponent().setUI(new BasicComboBoxUI() { @Override protected ComboPopup createPopup() { return new BasicComboPopup(comboBox) { protected Rectangle computePopupBounds(int px,int py,int pw,int ph) { return super.computePopupBounds(px, py, 500, ph); } }; } });