2009-06-05 20 views
26

編集可能なJComboBoxには、1文字の値のリストが含まれています。そのため、コンボボックスは非常に小さいです。JComboBoxのドロップダウンリストの幅を変更するにはどうすればよいですか?

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

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

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

これは私が達成したいものです。

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

アプリケーションは、彼らが前にあったように、いくつかの物事が正確でなければならない古いレガシーアプリケーションのレクリエーションですので、私はコンボボックスの幅を変更することはできません。 (この場合、コンボボックスはどんな小さなサイズでも保たなければなりません)

答えて

14

パブリックAPIでこれを行う唯一の方法は、カスタムUI(これにはtwobugsがあります)を書くことです。

あなただけの迅速かつ汚い何かをしたい場合は、私はそれを行うには実装の詳細を使用するには、この方法(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); 
} 

PopupMenuListenerでこれを入れて、それあなたのためのかもしれない仕事。

それとも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()); 
    } 
} 
+0

両方のメソッドは動作するようですが、popupMenuWillBecomeVisibleはカスタムListCellRendererも提供する場合にのみ機能します。デフォルトの文字列は元のサイズで文字列を切り取っているようです。 –

+0

JComboBox(OSX)に8つの項目がある場合、最初の1つは私には役に立たない。そして第2のものはMAC上でさえウィンドウの外観を持っています.... – Grains

+0

サイズが設定される前にpopupMenuWillBecomeVisibleが呼び出されるので、最初の解決策は機能しません(BasicComboPopupのshow()を参照)。上書きされます。 –

1

あなた自身が書いたように聞こえるでしょうComboBoxUI

これを実現する方法の例を示すhereがあります。

また、興味がある方法はcreatePopup()メソッドです。これは、コンボボックスのポップアップを作成し、それをカスタマイズできる場所です。

13

のような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; 
    } 
} 
+0

この解決策では、高さ、幅のみを調整しません。高さの調整ははるかに複雑です。 – DejanLekic

+0

は私のために働いていません – user489872

+0

このソリューションは、元のコンボボックスの '矢'を壊します。適用後、もう矢印はありません –

3

tutiezから素敵なソリューションです。

Dimension of popup listを設定する前に、その項目から最大の項目を取得し、完全に表示するのに必要な幅を計算しました。

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; 

今後の参考にしたいと考えています。

0

setSize()メソッドを使用します。

combo.setSize(200, combo.getPreferredSize().height); 
関連する問題