web-dev-qa-db-ja.com

BoxLayoutでJButtonの幅を変更できないのに、高さを変更できるのはなぜですか?

Java)に移植しているプログラムが持っている特定の外観に合うように、私のJDialogのレイアウトを取得しようとしています。いくつか使用しました。 LayoutManagersは以前は大成功でしたが、何らかの理由でこれをまったく機能させることができないようです。私の目標は、JDialogの右側(東)に[次を検索]ボタンと[キャンセル]ボタンを含めることです。 2つのボタンが常にJDialogの上部にあるように、トップダウンの順序とその下の余分なスペースがありますが、何らかの理由でBoxLayoutは変更の試みを継続的に無視しています(これは失われた場所)JButtonの幅。コードは次のとおりです。

_JButton findNext = new JButton("Find Next");
JButton cancel = new JButton("Cancel");
cancel.setPreferredSize(new Dimension((int)findNext.getPreferredSize().getWidth(),  
    (int)cancel.getPreferredSize().getHeight()));

JPanel example = new JPanel();  
example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS));  
example.add(findNext);
example.add(cancel);  
example.add(Box.createGlue());  
_

何を試しても、cancelは常に通常のサイズを保持します。 setPreferredSizeと同じパラメータでsetMinimumSize()setMaximumSize()を試しましたが運がありませんでした。 cancel.setPreferredSize(new Dimension(500, 500));を試したところ、ボタンの高さが調整されただけで、指定されたデフォルトの幅が保持されていました。

質問をクリアするために、次のように表示されます(これで完了です)。[次を検索]ボタンと[キャンセル]ボタンのサイズが同じではないことがわかります。

example image

18
Brandon Buck

私はこれが古い質問であることを知っていますが、私は本当に良い説明を見ていません。それで、これにつまずく検索者のために、私は私の2セントを追加します。

Swingのコンポーネントのサイズ設定に関連するメソッドは、setPreferredSize()、setMinimumSize()、およびsetMaximumSize()の3つです。ただし、重要な点は、これらの方法のいずれかを尊重するかどうかは、使用されている特定のレイアウトマネージャー次第であるということです。

BoxLayout(元のポスターが使用しているレイアウト)の場合:

  • setMinimumSize()-BoxLayoutはこれを尊重します
  • setMaximumSize()-BoxLayoutはこれを尊重します
  • setPreferredSize()-X_AXISが使用されている場合は幅が尊重され、Y_AXISが使用されている場合は高さが尊重されます

OPはY_AXISBoxLayoutを使用しているため、高さのみが変更されていました。

更新:すべてのレイアウトマネージャーについて、これと同じ情報を含むページをまとめました。うまくいけば、それは一部の検索者を助けることができます: http://thebadprogrammer.com/swing-layout-manager-sizing/

47
Michael

必要に応じて 成長してコンテナ内の余分なスペースを吸収する」Box.createGlue()は必要ない場合があります。代わりに、 Box.createVerticalStrut()betweenボタンを使用してください。以下および ControlPanel この シミュレーション

_example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS));
example.add(findNext);
Box.createVerticalStrut(10);
example.add(cancel);
_

補遺:

setMaximumSize()を追加すると機能しました。

これは、 ボックスレイアウト機能 で説明されているように、垂直方向のBoxLayoutで同じ最大幅を持つコンポーネントの予想される動作です。コンテナの優先幅は(同じ幅の)子の幅になり、Xの配置は無関係になります。

_example.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
JButton findNext = new JButton("Find Next");
JButton cancel = new JButton("Cancel");
Dimension d = findNext.getMaximumSize();
cancel.setMaximumSize(new Dimension(d));
example.add(findNext);
example.add(cancel);
_
6
trashgod

質問へのコメントで述べたように、setMaximumSize()に切り替えることで修正することができました。ただし、ご指摘のとおり、setPreferredSize()は機能しません。それで、どうしたの?

Swingの多くの場合、BoxLayoutを使用するときに実際のコンポーネントサイズを決定するために使用されるプロパティは、いくぶんランダムです(私の意見では)。コンポーネントのレンダリング方法を決定するとき、SwingはレイアウトマネージャーでlayoutComponent()を呼び出します。これは、すべてを配置する場所を特定します。

BoxLayoutlayoutComponent()の実装には、追加する各コンポーネントの幅と高さのオブジェクトを作成するメソッドの呼び出しが含まれます SizeRequirementsJPanelgetMinimum/Preferred/MaximumSize()メソッドに基づく。

後で、方向が_BoxLayout.Y_AXIS_(高さは別の方法を使用して計算される)であるため、各コンポーネントの正しい幅の値を決定するためにSizeRequirements.calculateAlignedPositions()を呼び出します。ソースからスニペットを取得すると、このメソッドの関連する実装は次のようになります。

_for (int i = 0; i < children.length; i++) {
    SizeRequirements req = children[i];
    //...
    int maxAscent = (int)(req.maximum * alignment);
    int maxDescent = req.maximum - maxAscent;
    //...
    int descent = Math.min(totalDescent, maxDescent);
    //...
    spans[i] = (int)Math.min((long) ascent + (long)descent, Integer.MAX_VALUE);
}
_

totalDescentが使用可能な幅であるため、descentは常にmaxDescentに設定されます。これは、[$ = FUNC @から取得された_SizeRequirements.maximum_に基づいています。 ]。 _spans[i]_の値は、後でJButton.getMaximumSize()の呼び出しで幅として使用されます。お気づきのように、JButton.setBounds()はここでは関与していません。そのため、この場合、getPreferredSize()を設定しても影響はありません。

3
Tim Stone

ボタンをGridLayoutパネルに配置すると、同じ幅になります。

0
Denizen

通常、Swingでコンポーネントのサイズを確認する場合は、同じ値でsetMinimumSize()setMaximumSize()、およびSetPrefferedSize()を呼び出す必要があります。

0
Denis Tulskiy