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

Dan*_*ski 27 java swing combobox

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

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

不幸的是,这种解释不适合下拉列表,因为它的尺寸很小,因为它与组合框的宽度相同.

有没有办法让下拉列表比组合框更宽?

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

 ---------------------
| Small JCombobox | V |
 --------------------------------------------
| "Long item 1"                              |
 --------------------------------------------
| "Long item 2"                              |
 --------------------------------------------
| "Long item 3"                              |
 --------------------------------------------
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*ers 14

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

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

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);
}
Run Code Online (Sandbox Code Playgroud)

把它放在一个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());
  }
}
Run Code Online (Sandbox Code Playgroud)


Shl*_*omi 14

这是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; 
    } 
}
Run Code Online (Sandbox Code Playgroud)


raf*_*end 5

这是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);

    }
}
Run Code Online (Sandbox Code Playgroud)

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

return widest + 5;
Run Code Online (Sandbox Code Playgroud)

希望它对将来参考有用!