先月までは,AWT/Java2Dの新機能を紹介してきました。今月からはSwingの新機能に移りましょう。とはいうものの,今週と来週はAWTとSwingの両方で通用する機能を紹介します。

SwingやAWTで悩ましい問題として,コンポーネントのレイアウトがあります。

どのレイアウト・マネージャを使えばいいのか,どのように配置すればいいのか,思ったように配置できない,などなど。面倒になってレイアウト・マネージャをnullにしてしまった経験をお持ちの方も多いと思います。

Java SE 6では,レイアウトの機能も拡張されました。

そこで,今週は既存のレイアウト・マネージャの拡張機能,来週は新しいレイアウト・マネージャであるGroupLayoutクラスについて解説します。

文字の属性

アルファベットの構成
図1 アルファベットの構成

コンポーネントを水平方向にレイアウトする場合を考えてみましょう。このような場合,垂直方向の位置合わせにはコンポーネントの上,下,中央のいずれかが使用されます。例えば,FlowLayoutクラスでは,コンポーネントの中央にそろえて配置されます。

通常はそれで十分です。しかし,文字,特にアルファベットを表示する場合,考慮しなくてはならないことがあります。

英語をはじめて習ったときに,4線のノートでアルファベットを書いたのを覚えていますか?

アルファベットを書くときには,この4線の下から2番目の線を基準として表記します。しかし,gやyなどの文字は,その線の下にはみ出てしまいます。これがやっかいなところです。

図1に示したように,アルファベットで書くときに基準となる線のことをベースライン(Baseline)といいます。そして,ベースラインから上の部分をアセント,下の部分をディセントといいます。

中央で整列
図2 中央で整列
ベースラインで整列
図3 ベースラインで整列

さて,ここでGUIに戻りましょう。図2は三つのコンポーネントが並んでいるGUIです。それぞれのコンポーネントは中央にそろえて配置されています。しかし,文字の大きさが異なるため,整然と並んでいる感じを受けません。

中央でそろえるのがおかしいならば,上で合わせますか? それとも下で合わせますか?

こうした文字が表示されているコンポーネントを並べる場合には,さきほど説明したベースラインでそろえるのが最適です。

図2のGUIをベースラインでそろえたものを図3に示しました。どうですか? ずっとすっきりしたと思いませんか?

ここで示したように,Java SE 6ではベースラインで整列ができるようになりました。とはいうものの,java.awt.GridLayoutクラスのように,プリファードサイズを使用しないレイアウト・マネージャではベースラインを使用することはできません。

そこで,今回はjava.awt.FlowLayoutクラス,java.awt.GridBagLayoutクラス,javax.swing.SpringLayoutクラスでのベースライン整列について解説していきます。

FlowLayoutクラスの場合

図2や図3で示したGUIはレイアウト・マネージャにFlowLayoutクラスを使用しています。FlowLayoutクラスでのベースラインによる整列はとても簡単。たった1行付け加えるだけです。

サンプルのソースコード BaselineLayoutSample1.java

コンテナにレイアウト・マネージャを適用する部分を以下に示します。まずは通常の使い方です。

JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("FlowLayout"));

// FlowLayout
FlowLayout layout = new FlowLayout();
panel.setLayout(layout);

これを実行したのが図2です。何もしなければ前述したように中央で整列します。

ベースラインで整列させるには次のように1行加えます。

JPanel panel = new JPanel();
panel.setBorder(new TitledBorder("FlowLayout"));

// FlowLayout
FlowLayout layout = new FlowLayout();

// ベースラインで整列
layout.setAlignOnBaseline(true);
panel.setLayout(layout);

これだけで,図3のようにベースラインで整列させることができます。

GridBagLayoutクラスの場合

FlowLayoutクラスはちょっとしたレイアウトには重宝しますが,少し複雑なGUIになると太刀打ちできません。そうしたときによく使われるのが,GridBagLayoutクラスです。

GridBagLayoutクラスは,GridBagConstraintsクラスを用いてレイアウトの付随情報を表します。「ベースラインで整列する」という情報も,GridBagConstraintsクラスに記述します。

サンプルのソースコード BaselineLayoutSample2.java

ベースラインで整列させるかどうかはGridBagConstraints.anchorに記述します。

GridBagConstraints constraints
    = new GridBagConstraints();
constraints.insets = new Insets(5, 5, 5, 5);

// ベースライン整列
constraints.anchor = GridBagConstraints.BASELINE;

JLabel label = new JLabel("<html><h1>GridLayout</h1></html>");
layout.setConstraints(label, constraints);
panel.add(label);

GridBagConstraints.BASELINEはJava SE 6で新たに定義された定数です。その他のコンポーネントもanchorをBASELINEにすることでベースラインで整列させることができます。

実行結果を図4に示しました。

anchorで使用できる定数として,BASELINE以外にABOVE_BASELINE,BELOW_BASELINEなどが定義されました。

図5は,ラベルをBASELINE,テキスト・フィールドをABOVE_BASELINE,ボタンをBELOW_BASELINEとしたときの実行結果です。

GridBagLayout
図4 GridBagLayoutでの実行結果
ベースラインで整列
図5 ベースラインを基準にしたレイアウト

SpringLayoutクラスの場合

SpringLayout
図6 SpringLayout

SpringLayoutクラスは,J2SE 1.4から導入された比較的新しいレイアウト・マネージャです。新しいということもあって,使用される頻度が低い気がします。この解説ではじめてSpringLayoutの存在を知る方も多いのではないでしょうか。

でも,結構便利なレイアウト・マネージャなんです。

SpringLayoutクラスは自分自身のコンポーネントとその周りのコンポーネントの位置関係を利用してレイアウトを行います。

SpringLayoutのおもしろいところは,位置関係をバネで表すところです。そう,SpringLayoutのSpringは文字通りバネのことです。

例えば,コンポーネントc1とコンポーネントc2を水平方向に並べるには,c1の右端(EAST)とc2の左端(WEST)を,スプリングで結び付けるための記述を行います(図6)。例えば,最短で5ピクセル,推奨は10ピクセル,最大に伸びたときに20ピクセルのスプリングで結び付けるには以下のように記述します。

springLayout.putConstraint(SpringLayout.EAST, c1,
                     Spring.constant(5,10, 20);
                     SpringLayout.WEST, c2);

ここで変数springLayoutは,SpringLayoutオブジェクトです。

このようにコンポーネント間をスプリングで結び付けていきます。ベースラインについても同じようにスプリングで表します。とはいうものの,ベースラインで整列させるのであれば,長さ0のスプリングで結び付けなければなりません。

サンプルのソースコード BaselineLayoutSample3.java

サンプルでは,ラベルとテキスト・フィールド,ボタンの三つをベースラインで整列させています。

// ベースラインで整列
layout.putConstraint(SpringLayout.BASELINE, field,
                     Spring.constant(0),
                     SpringLayout.BASELINE, label);
layout.putConstraint(SpringLayout.BASELINE, field,
                     Spring.constant(0),
                     SpringLayout.BASELINE, button);
SpringLayout
図7 SpringLayoutでの実行結果

Spring.constant(0)は長さ0のスプリングを生成します。

今週は既存の三つのレイアウト・マネージャでベースラインでの整列を行ってみました。

来週はJava SE 6で新たに導入されたGroupLayoutクラスについて解説します。

著者紹介 櫻庭祐一

横河電機 ネットワーク開発センタ所属。Java in the Box 主筆

今月の櫻庭

自家製桜もち

櫻庭は洋菓子しか興味がないと思ったあなた,それは間違いです(笑)。

実は和菓子も大好きなんです。

特に冬から春にかけての和菓子。花びら餅,福豆,桜もちに柏餅。どれもおいしいですよね。

ところで,最近,江戸菓子が京菓子化しているような気がしてしかたありません。例えば,桜もち。江戸菓子の白玉粉を使った桜もちが減って,道明寺が増えているような気がします。

櫻庭は白玉粉を使った桜もちが大好きなので(もちろん道明寺も好きですけど),去年は自分で作ってしまいました。意外と簡単ですよ。

これから桜の季節なので,自家製桜もちでお花見などいかがですか。