0

MRU リスト コンボ ボックスとディレクトリ ツリー パネルを含む JComboBox があります。一緒に、2 つが JSplitPane である私の GUI の左側のパネル (MRU はツリー パネルの上にあります) を形成するため、左側のパネルはサイズ変更可能です。

ツリー パネルでそのディレクトリを表示するためにディレクトリ テキストが常に必要な幅よりも長いという問題があるため、コンボを停止するには、ツリーに必要な幅よりもはるかに広い左側のペインのサイズを変更する必要があります。からのボックスには、切り捨てられたディレクトリ名が表示されます。

コンボボックスは、ファイル名の末尾が切り捨てられているとあまり役に立ちませんが、左ペインをファイル名に対して十分に広くすると、ウィンドウ全体、特にウィンドウ全体に対して目障りに広すぎることがよくあります。最大化されていない場合。通常、関心のあるのはファイル名の末尾部分だけです。JComboBox に"start..." ではなく"start...end" を表示させることができれば、問題は解決します。

スクリーンショット http://www.freeimagehosting.net/uploads/da9810ed86.png


更新:私はうまくいく解決策を持っています(以下の自己回答を見てください)が、それは完璧ではありません。誰かが私がそれを改善する方法を知っていれば、それは大歓迎です.

4

2 に答える 2

1

mmHhh おそらくカスタム レンダラーを提供していますか?... .

リストセルレンダラーか何かだと思います。

私が理解していることでは、十分なスペースがない場合、デフォルトはラップされています。レンダリングされたセルを作成/または変更することで、コンポーネントの使用可能な幅を知り、レンダリングするテキストを自由に変更できます。

うーん、私は数年間その API (セル レンダリングのもの) に近づいていないので、おそらく少し混乱している可能性があります。

:)

于 2009-04-25T00:41:19.673 に答える
0

ListCellRenderer を使用するという Oscar のアイデアに取り組んで、ほとんど機能するものを思いつきました... コンポーネントの値は正しくレンダリングされますが、リストの値には醜いハックが必要です。

リスト項目の場合、(getSize() からの) レンダラーのサイズは、値をレンダリングするために使用できるスペースの幅ではなく、最も長い項目のテキスト幅を反映するため、ハックが必要です。JComboBox 自体を使用してみましたが、その幅には小さなドロップダウン ボタンが含まれているため、スクロールバーが存在する場合、その幅は考慮されません。ハックは、レンダラーの幅がコンボボックスの幅よりも小さい場合はそれを保存し、レンダラーの幅がコンボボックスの幅よりも大きい場合は保存された幅を使用することです。これには、レンダラーの幅が内部 JLabel の幅とコンボボックスの幅の間にあるコーナーケースがあります。

レンダリングスペースはコンボボックスの幅からスクロールバーとインセットの幅を差し引いたものになるため、リストにスクロールバーがあることを知る方法とスクロールバーを取得する方法について誰かが提案を持っている場合は、幅を抽出し、私はすべての耳です。たぶん、list.getParent() を実行して、それが JScrollPane であることを期待できます (JComboBox または JList doco は、スクロール ペインを使用すると述べています)。

これを改善するための他の提案は大歓迎です。

コードは次のとおりです。

recentDirs.setRenderer(new ComboTextRenderer(recentDirs));

...

static private class ComboTextRenderer
extends DefaultListCellRenderer
implements SwingConstants
{
JComponent                          parent;
int                                 renderWidth;

ComboTextRenderer(JComponent par) {
    super();

    parent=par;
    renderWidth=-1;
    }

public void paint(Graphics gc) {
    String                          txt=getText();

    int                             len=txt.length();
    int                             wid=getSize().width;
    Insets                          ins=getInsets();
    FontMetrics                     met=gc.getFontMetrics();

    if(renderWidth==-1 || wid<parent.getSize().width) { renderWidth=wid; }
    else                                              { wid=renderWidth; }
    wid-=(ins.left+ins.right);

    if(met.stringWidth(txt)>wid) {
        String rpl=null;
        for(int xa=0,pfx=Math.min(15,((len/2)-1)),sfx=(pfx+2); pfx>0 && sfx<len; xa++) {
            rpl=(txt.substring(0,pfx)+" ... "+txt.substring(sfx));
            if(met.stringWidth(rpl)<=wid) { break; }
            rpl=null;
            if     ((len-sfx)>15) { sfx++; }
            else if((xa%2)==0   ) { pfx--; }
            else                  { sfx++; }
            }
        if(rpl!=null) { setText(rpl); }
        }

    super.paint(gc);
    }
}
于 2009-04-25T08:01:19.680 に答える