Standard Widget Toolkit
概要
SWT (Standard Widget Toolkit) は IBM が Eclipse 用に開発した GUI ライブラリです。JNI を使用することで昔の Swing で問題となっていたグラフィック描画のボトルネックを回避し、当時の Swing ベースのアプリケーションと比較して格段の速さを誇っていました。
J2SE 1.4 以降は Swing のグラフィックが高速になったため速度的な優位性はなくなりましたが、
AWT/Swing に慣れているプログラマ向けの注意点は以下の通り。
- SWT コンポーネントは継承して使うよう設計されていません。既存のウィジェットをゴリゴリと組み合わせてゆくスタイルです。
- ウィンドウリソースの開放処理はプログラマが明示的に行う必要があります。
- コンストラクタで親のコンポジットを指定します。つまり SWT コンポーネントは親から順に作成する必要があります。
- イベント処理の連携が煩雑になるためあまりお勧めできませんが、いざとなればAWT や Swing と SWT を混在させる事が可能です。
SWT 開発の準備
SWT は JNI を使用していますが、必要なネイティブライブラリはまとめて JAR に格納されているため、プラットフォームごとの JAR を入手してクラスパスを通すだけで利用が可能です。
- eclipse.org からプラットフォームごとの Stable 版 (Windows であれば swt-3.3.1.1-win32-win32-x86.zip) をダウンロードします。
- ダウンロードした ZIP ファイルを解凍して
swt.jar
を取り出します。 - クラスパスの通るディレクトリ (
${java.home}/lib/ext
,${jre.home}/lib/ext
など) に保存するか、または明示的にクラスパスを通してコンパイルと実行を行います。
ウィンドウの表示
SWT のウィンドウ表示も非常に簡単。Display
がディスプレイデバイスを表しており、その上にウィンドウを表す Shell
を構築します。
SWT では表示中のウィンドウ残っていても main() が終了すればプログラムも終了してしまいます。このためウィンドウが閉じるまでイベントキューからメッセージを拾ってディスパッチするというループ処理が必要です。
プログラムの終了前には使用したリソースを Display#dispose() で明示的に開放します。
Display display = Display.getDefault();
// ウィンドウの構築と表示
Shell shell = new Shell(display);
shell.setText("ウィンドウタイトル");
Rectangle area = display.getBounds();
area.x = (area.width - 400) / 2 + area.x;
area.y = (area.height - 300) / 2 + area.y;
area.width = 400;
area.height = 300;
shell.setBounds(area);
shell.open();
// メッセージループ
while(! shell.isDisposed()){
if(! display.readAndDispatch()){
display.sleep();
}
}
display.dispose();
Shell のコンストラクタには以下のウィンドウスタイルを論理和で指定することができます。
SWT.BORDER | ウィンドウ枠の表示 |
SWT.CLOSE | タイトルバーの閉じるボタンの有効化 |
SWT.MIN | タイトルバーの最小化ボタンの有効化 |
SWT.MAX | タイトルバーの最大化ボタンの有効化 |
SWT.RESIZE | ウィンドウのリサイズの有効化 |
SWT.TITLE | タイトルバーの有無 |
SWT.NO_TRIM | 装飾なしの組み合わせ |
SWT.SHELL_TRIM | 一般的なウィンドウの組み合わせ (CLOSE|TITLE|MIN|MAX|RESIZE) |
SWT.DIALOG_TRIM | 一般的なダイアログの組み合わせ (CLOSE|TITLE|BORDER) |
SWT.MODELESS | モードレスウィンドウ |
SWT.PRIMARY_MODAL | プライマリモーダルウィンドウ |
SWT.APPLICATION_MODAL | アプリケーションモーダルウィンドウ |
SWT.SYSTEM_MODAL | システムモーダルウィンドウ |
タブの表示
タブ切り替えの表示は TabFolder
クラスを使用します。
これにに必要な数だけ TabItem
を追加してゆき、タブ内容となるコンポーネントを TabItem#setControl() で指定します。
shell.setLayout(new FillLayout());
TabFolder tabFolder = new TabFolder(shell, SWT.NULL);
TabItem tab1 = new TabItem(tabFolder, SWT.NULL);
tab1.setText("タブ1");
Label greeting = new Label(tabFolder, SWT.NULL);
greeting.setText("hello, world");
tab1.setControl(greeting);
TabItem tab2 = new TabItem(tabFolder, SWT.NULL);
tab2.setText("タブ2");
TabItem tab3 = new TabItem(tabFolder, SWT.NULL);
tab3.setText("タブ3");