FormLayoutは、その他の FillLayout、RowLayout、GridLayout とは異なったアプローチでレイアウトを行います。
FormLayoutは、コントロール同士の相対位置でレイアウト していきます。 例えば、以下のようにコントロールが配置されていたとします。
+------------+ | |+--------+ | StyledText || Button | | |+--------+ +------------+ +--------------+ | progress bar | +--------------+これを口語的に表すと、 「ButtonはStyledTextの右側にあり、 progress barはStyledTextの下側にある。」 となります。 FormLayoutは、これと同じ考え方をレイアウトに適用します。
これからFormLayout、FormData、FormAttachmentクラスについて説明しますが、 覚えるまではややややこしいです。 他のレイアウトを知っていると、なんだかこの方法はまどろっこしいような気がしますが、 場面によっては、至ってシンプルにレイアウトを行うことができるので便利ですので、 是非覚えましょう。
FormLayoutを使ったレイアウティングは、 FormLayoutクラス、 FormDataクラス、 FormAttachmentクラスを使います。 まずコンポジットにFormLayoutをセットし、そこに複数のコントロールを格納します。 次に、格納するコントロールにFormDataオブジェクトを関連付けます。 この手順までは他のレイアウトと同じです。 違うのはここからです。それぞれのコントロールにセットされたFormDataオブジェクトには、 複数のFormAttachmentオブジェクトを格納します。
+------------+ 1 : 1 +-----------+
| FormLayout |------@| Composite |
+------------+ +-----------+
1@
|x
+---------+
| Control |
+---------+
1@
|1
+----------------+ x : 1 +----------+
| FormAttachment |------@| FormData |
+----------------+ +----------+
FormDataクラスの説明をする前に、FormAttachmentの説明が必要です。 FormAttachmentは、親コンポジットからの相対距離もしくは兄弟コントロールからの相対距離を表現するためのクラスです。 FormAttachmentクラスが表現するのは、あくまでも距離だけです。 方向(ベクトル)は、FormDataの適切なフィールドに格納されることで現されます。
FormAttachmentクラスには、いくつかのコンストラクタが用意されています。
FormAttachment() FormAttachment(Control control) FormAttachment(Control control, int offset) FormAttachment(Control control, int offset, int alignment) FormAttachment(int numerator) FormAttachment(int numerator, int offset) FormAttachment(int numerator, int denominator, int offset)
引数がゼロのものは、まずはインスタンスを作成して、その後にパブリックなフィールドに値を代入して使います。
controlを引数にとるものは、そのcontrolとの相対位置を定義するためのコンストラクタです。 offset引数は、controlとの距離をピクセル数で表します。
controlを引数にとらないものは、親compositeからの相対距離を定義するためのコンストラクタです。 引数が1つのものは、親compositeの左上隅からの相対距離を、0から100の範囲(パーセンテージ)で指定します。 引数が2つのものは、親compositeの左上隅からの相対距離をパーセンテージ指定した位置から、 さらにoffsetの位置だけ移動した場所に指定します。 引数が3つのものは、denominatorに分母を、numeratorに分子を指定して、 numeratorは0からdenominatorまでの数値で指定します。そしてそこからoffsetずれた場所を指定します。
FormDataクラスは、その中に6つのフィールドを持ちます。
FormAttachment top FormAttachment left FormAttachment right FormAttachment bottom int width int heightまず、widthとheightフィールドは、controlの横幅と縦幅を指定します。 そしてtop、left、right、bottomのフィールドは、そのウィジェットのそれぞれ 上辺、左辺、右辺、下辺が、どこに位置するのかを決定するためのものです。
FormLayout、FormData、FormAttachmentの3つを使ったサンプルを示します。
オレンジ色の線と赤色の線は、FormAttachmentによって相対位置を指定した部分です
(画像を加工してあります)。
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class FormLayoutComposite extends Composite {
public FormLayoutComposite(Composite parent) {
super(parent, SWT.NONE);
FormLayout layout = new FormLayout();
setLayout(layout);
/* 各controlの作成 */
Text text = new Text(this, SWT.MULTI);
text.setText("ここはテキストエリアです。");
Button ok = new Button(this, SWT.NONE);
ok.setText("OK");
Button cancel = new Button(this, SWT.NONE);
cancel.setText("Cancel");
/* textの位置を指定 */
FormData data = new FormData();
// textの上辺を親の上端から0%の位置に
data.top = new FormAttachment(0, 0);
// textの左辺を親の左端から0%の位置に
data.left = new FormAttachment(0, 0);
// textの右辺を親の左端から100%の位置に
data.right = new FormAttachment(100);
// textの下辺を親の上端から3/4の位置に
data.bottom = new FormAttachment(3, 4, 0);
// textにFormDataオブジェクト関連づけ
text.setLayoutData(data);
/* cancelの位置を指定 */
// 新しくFormDataオブジェクトを作成
data = new FormData();
// cancelの上辺をtextの下辺に
data.top = new FormAttachment(text);
// cancelの右辺を親の左端から100%の位置に
data.right = new FormAttachment(100);
// calcelにFormDataオブジェクト関連づけ
cancel.setLayoutData(data);
/* okの位置を指定 */
// 新しくFormDataオブジェクトを作成
data = new FormData();
// okの上辺をtextの下辺に
data.top = new FormAttachment(text);
// okの右辺をcancelの左辺に
data.right = new FormAttachment(cancel);
// okにFormDataオブジェクト関連づけ
ok.setLayoutData(data);
}
}