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

Java 如何更改JComboBox下拉列表的宽度?,java,swing,combobox,Java,Swing,Combobox,我有一个可编辑的JComboBox,其中包含一个单字母值列表。因此,组合框非常小 每一个字母都有一个特殊的含义,如果是很少使用的字母,用户有时不清楚。因此,我创建了一个自定义的ListCellRenderer,显示下拉列表中每个字母的含义 不幸的是,这个解释不适合下拉列表,因为它太小了,因为它与组合框的宽度相同 有没有办法使下拉列表比组合框更宽 这就是我想要实现的目标: --------------------- | Small JCombobox | V | ---------------

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

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

不幸的是,这个解释不适合下拉列表,因为它太小了,因为它与组合框的宽度相同

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

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

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

我无法更改组合框的宽度,因为该应用程序是旧的遗留应用程序的翻版,其中某些内容必须与以前完全相同。(在这种情况下,组合框必须不惜一切代价保持小尺寸)

听起来您需要自己编写

有一个很好的例子说明了如何实现这一点


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

我认为使用公共API实现这一点的唯一方法是编写自定义UI(目前正在处理此问题)

如果您只是想要一些快速而肮脏的东西,我发现这样做可以使用实现细节():

把这个放在一个盒子里,它可能对你有用

或者,您可以使用以下代码:


这是Santhosh Kumar提出的一个很好的解决方案,不需要搞乱UI和其他类似的讨厌的东西


这里有一个很好的解决方案

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

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

    }
}

希望对以后的参考有用

您可能需要使用
setSize()
方法

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

这里有一段简单的代码,没有扩展JComboBox或其他任何类

在本例中,with下拉列表始终为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);
                    }                       
                };
            }
        });

这两种方法似乎都有效,但popupMenuWillBecomeVisible仅在您还提供自定义ListCellRenderer的情况下才有效。默认的一个似乎是按原始大小剪切字符串。当JComboBox(OSX)中有以下8项时,第一个不适用于我。第二个解决方案甚至在MAC上也有windows的外观……第一个解决方案不起作用,因为在设置大小之前会调用popupMenuWillBecomeVisible(请参见BasicComboPopup中的show()),所以您在该侦听器中设置的任何大小都将被覆盖。答案可以在JDK源代码“BasicComboPopup#getPopupLocation”中找到,我们可以将其计算大小和调整大小的解决方案复制到PopupMenuListener的“popupMenuWillBecomeVisible()”,对于过长的项目,我们甚至可以设置弹出菜单的位置(其位置为“屏幕位置”)。此解决方案不调整高度,只调整宽度。调整高度要复杂得多。此解决方案打破了原始组合框的“箭头”。应用后,不再有箭头注意:链接已断开
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);

    }
}
return widest + 5;
combo.setSize(200, combo.getPreferredSize().height);
        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);
                    }                       
                };
            }
        });