简体   繁体   English

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

[英]How can I change the width of a JComboBox dropdown list?

I have an editable JComboBox which contains a list of single letter values.我有一个可编辑的JComboBox ,其中包含一个单字母值列表。 Because of that the combobox is very small.因此,组合框非常小。

Every letter has a special meaning which sometimes isn't clear to the user in case of rarely used letters.每个字母都有一个特殊的含义,在很少使用的字母的情况下,用户有时不清楚。 Because of that I've created a custom ListCellRenderer which shows the meaning of each letter in the dropdown list.因此,我创建了一个自定义ListCellRenderer ,它显示了下拉列表中每个字母的含义。

Unfortunately this explanation doesn't fit into the dropdown because it is to small, because it has the same width as the combobox.不幸的是,这种解释不适合下拉列表,因为它太小了,因为它与组合框的宽度相同。

Is there any way to make the dropdown list wider than the combobox?有没有办法让下拉列表比组合框更宽?

This is what I want to achieve:这就是我想要实现的目标:

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

I cannot change the width of the combobox because the application is a recreation of an old legacy application where some things have to be exactly as they were before.我无法更改组合框的宽度,因为该应用程序是旧遗留应用程序的重新创建,其中某些内容必须与以前完全一样。 (In this case the combobox has to keep it's small size at all costs) (在这种情况下,组合框必须不惜一切代价保持小尺寸)

I believe the only way to do this with the public API is to write a custom UI (there are two bugs dealing with this).我相信使用公共 API 做到这一点的唯一方法是编写一个自定义 UI(有两个错误可以解决这个问题)。

If you just want something quick-and-dirty, I found this way to use implementation details to do it ( here ):如果你只是想要一些快速而肮脏的东西,我找到了这种使用实现细节来做到这一点的方法(这里):

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

Put this in a PopupMenuListener and it might work for you.把它放在一个PopupMenuListener ,它可能对你PopupMenuListener

Or you could use the code from the first linked 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());
  }
}

Here is a great solution by Santhosh Kumar, without the need to mess with UI's and other nasty stuff like that!这是 Santhosh Kumar 的一个很好的解决方案,无需弄乱 UI 和其他类似的讨厌的东西!

http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough 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; 
    } 
}

Here is a nice solution from tutiez .这是tutiez 的一个很好的解决方案。

Before setting up the Dimension of popup list, it gets the biggest item from it and calculated the width needed to show it completely.在设置弹出列表的维度之前,它从中获取最大的项目并计算完整显示所需的宽度。

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

    }
}

The code above has already a main for a quick test.上面的代码已经有一个主要用于快速测试。 But notice that the statement below may be adjusted to around 20 if you want to have a vertical scroll.但是请注意,如果您想要垂直滚动,下面的语句可能会调整为20左右。

return widest + 5;

Hope it is useful for future reference!希望对日后参考有用!

Sounds like you'll need to write your own ComboBoxUI .听起来您需要编写自己的ComboBoxUI

There is a good example here that shows how to accomplish this.有一个很好的例子, 在这里,说明如何做到这一点。

Also note, the method you would probably be interested in is the createPopup() method.另请注意,您可能感兴趣的方法是createPopup()方法。 This is the method that creates the popup for the combo box and where you would be able to customize it.这是为组合框创建弹出窗口的方法,您可以在其中自定义它。

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

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

Here you have a simple piece of code without extends JComboBox nor other any class这里有一段简单的代码,没有扩展 JComboBox 或其他任何类

In this example the with of drop down is 500 always.在这个例子中,下拉菜单总是 500。 You also can modify the height or the location.您还可以修改高度或位置。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM