web-dev-qa-db-ja.com

JComboBoxドロップダウンリストの幅を変更するにはどうすればよいですか?

1文字の値のリストを含む編集可能なJComboBoxがあります。そのため、コンボボックスは非常に小さいです。

すべての文字には特別な意味があり、めったに使用されない文字の場合、ユーザーにはわからないことがあります。そのため、ドロップダウンリストの各文字の意味を示すカスタムListCellRendererを作成しました。

残念ながら、この説明は、コンボボックスと同じ幅であるため、小さすぎるため、ドロップダウンに適合しません。

ドロップダウンリストをコンボボックスよりも広くする方法はありますか?

これが私が達成したいことです:

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

アプリケーションは古いレガシーアプリケーションを再現したものであり、以前とまったく同じである必要があるため、コンボボックスの幅を変更することはできません。 (この場合、コンボボックスはすべてのコストで小さいサイズを維持する必要があります)

27
Daniel Rikowski

パブリックAPIでこれを行う唯一の方法は、カスタムUIを作成することだと思います(これに対処するために 2バグ があります)。

迅速で汚いものが必要な場合は、実装の詳細を使用してそれを行うこの方法を見つけました( ここ ):

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 に入れると、うまくいくかもしれません

または、 最初にリンクされたバグ のコードを使用することもできます。

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());
  }
}
14
Michael Myers

これは、UIやその他の厄介なものをいじる必要のない、Santhosh Kumarによる優れたソリューションです!

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; 
    } 
}
14
Shlomi

これが 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;

今後の参考になりますように!

5
rafaelrezend

独自に作成する必要があるようです ComboBoxUI

これを達成する方法を示す良い例 ここ があります。

また、おそらく興味があると思われるメソッドはcreatePopup()メソッドであることに注意してください。これは、コンボボックスのポップアップを作成し、それをカスタマイズできる場所です。

1
thedude19

setSize()メソッドを使用することをお勧めします。

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

ここに、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);
                    }                       
                };
            }
        });
0
josepmra