JButtonなどの高さを変更せずに幅を指定
高さはデフォルトのまま幅だけを指定して、JButton、JComboBox、JTextFieldなどのサイズを変更します。
サンプルコード
Dimension dim = button1.getPreferredSize(); button1.setPreferredSize(new Dimension(100, dim.height)); button2.setPreferredSize(new Dimension(100, dim.height)); Box box1 = Box.createHorizontalBox(); box1.add(Box.createHorizontalGlue()); box1.add(button1); box1.add(Box.createHorizontalStrut(5)); box1.add(button2); box1.add(Box.createHorizontalStrut(5)); box1.add(Box.createRigidArea(new Dimension(0, dim.height+10)));
解説
サンプルの下段のようにJButtonの幅を一定にそろえて水平に並べたい場合や、GridBugLayoutでウエイトを指定するのが面倒といった場合に使用します。
上記のサンプルでは、まずJButtonのUIがフォントサイズや文字列の長さから決めたデフォルトサイズをgetPreferredSize()で取得しています。高さはそのまま利用し、幅だけ一定の値を設定して、新たなデフォルトサイズを作成し、setPreferredSize()しています。これで次からgetPreferredSize()で帰ってくる値は、どちらのボタンでも全く同じになります。
このgetPreferredSize()で得られる値を使用するかどうかは、レイアウトマネージャーによって異なりますが、水平方向にコンポーネントを並べるBoxLayoutの場合は以下のようになるため、パネルをリサイズしても、ボタンのサイズはどちらも同じで変化しません。
- 幅: 推奨サイズ(getPreferredSizeメソッド)から取得した値
- 高さ: 各コンポーネントの推奨サイズ(getPreferredSizeメソッド)で得られた中からもっとも大きな値
- 上記のサンプルでbutton1.setPreferredSize(new Dimension(100, 0));としても結果は同じ
例えばフレームをpack()する前にgetPreferredSize()ではなく、getSize()でサイズを取得すると、[width=0,height=0]が帰ってきます。コンポーネントが表示されている場合、getSize()で得られるサイズは、その実際に表示されているサイズになります。
以下はJLabelをgetPreferredSize()した場合の例です。初期状態(preferredSizeがnull)の場合は、JLabelのUIがサイズを計算しています。
JLabel l = new JLabel();
l.setText("a"); //preferredSizeがnullの場合、UIがサイズを計算
//l.getPreferredSize() -> Dimension[width=6,height=13]
l.setText("aaaa"); //JLabelの場合、Fontサイズと文字列の長さなどで決まる
//l.getPreferredSize() -> Dimension[width=24,height=13]
l.setText("<html>aa<br>aa");
//l.getPreferredSize() -> Dimension[width=12,height=26]
l.setPreferredSize(new Dimension(10,10)); //preferredSizeを設定した場合
//l.getPreferredSize() -> Dimension[width=10,height=10]
l.setPreferredSize(null); //preferredSizeをnullに戻した場合
//l.getPreferredSize() -> Dimension[width=12,height=26]
JComboBox、JTextField などのコンポーネントでは、JComboBoxなどの幅をカラム数で指定のように、カラム数で幅を指定することもできます。JDK 1.5 でこの方法をしようすると、コンポーネントによって高さや余白などが微妙に異なりますが、JDK 1.6 以上ならうまくサイズを指定することができます。