前回 Eclipse4.4 に SWTとWindowBuilerのインストール手順を書きました。
今度は、WindowBuilderを使って 簡単なSWTのプログラムを作ります。
作るプログラムは FXML + Scene Builder 同様
TextFieldに名前を入力し、ボタンをクリックすると ***さん こんにちは と表示する。
さらに簡単なメニューを付けプログラムを終了する。
こんなプログラムにします。
- プロジェクトの作成
メニューから ファイル → 新規 → Javaプロジェクト とたどり
新規Javaプロジェクトのダイアログで プロジェクト名に「SwtTest」と入力し、「次へ」をクリック
ビルドパス設定ダイアログでは、ライブラリタグを開き
「外部JAR追加」をクリック 前回 インストールした SWTのフォルダを開き swt.jarを追加「完了」をクリックすると プロジェクトができました。
- Visual クラス作成パッケージエクスポーラーの src を右クリック >新規 > その他をクリック
新規ダイアログで WindowBuilder > SWTデザイナー > SWT とたどり シェルを選択 「次へ」
パッケージ名・名前を入力し 「完了」をクリック
こんなソースが生成されました。(Mainform.java)
package
com.nobotta;
import
org.eclipse.swt.SWT;
import
org.eclipse.swt.widgets.Display;
import
org.eclipse.swt.widgets.Shell;
public
class
Mainform
extends
Shell {
/**
* Launch the application.
* @param args
*/
public
static
void
main(String args[]) {
try
{
Display display = Display.getDefault();
Mainform shell =
new
Mainform(display);
shell.open();
shell.layout();
while
(!shell.isDisposed()) {
if
(!display.readAndDispatch()) {
display.sleep();
}
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
* @param display
*/
public
Mainform(Display display) {
super
(display, SWT.SHELL_TRIM);
createContents();
}
/**
* Create contents of the shell.
*/
protected
void
createContents() {
setText(
"SWT Application"
);
setSize(
450
,
300
);
}
@Override
protected
void
checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
- 画面デザインMainform.java を開いて 画面下側の Designをクリックして しばらくすると 下のような デザイン画面が開きます。
パレットから Layout Controlなど部品を選択し 中央の画面領域にドラッグし 必要に応じ プロパティを設定します。
作成した画面
私自身あまり詳しくないので、すみませんが SWTでの画面デザインの詳しい方法は他のサイトを参考にしてください。(SWTの公式ページが一番詳しいようです) - イベントハンドラの実装
画面のコントロール または Structure > コンポーネント の要素 を 右クリックし Add event handler をクリックすると、コードのイベントハンドラ部分が開くので それぞれ実行する処理を入力します。
OKボタンクリック時btnOK.addSelectionListener(
new
SelectionAdapter() {
@Override
public
void
widgetSelected(SelectionEvent arg0) {
lblAnswer.setText(txtName.getText() +
"さん こんにちは"
);
}
});
閉じるメニュークリック時
mntmNewItem.addSelectionListener(
new
SelectionAdapter() {
@Override
public
void
widgetSelected(SelectionEvent arg0) {
shell.close();
}
});
- プログラム全体
ソース全体は以下のようになります。
コンパイルエラーを避けるため コントロール類の定義のスコープを一部変更しています。package
com.nobotta;
import
org.eclipse.swt.SWT;
import
org.eclipse.swt.events.SelectionAdapter;
import
org.eclipse.swt.events.SelectionEvent;
import
org.eclipse.swt.layout.GridData;
import
org.eclipse.swt.layout.GridLayout;
import
org.eclipse.swt.widgets.Button;
import
org.eclipse.swt.widgets.Display;
import
org.eclipse.swt.widgets.Label;
import
org.eclipse.swt.widgets.Menu;
import
org.eclipse.swt.widgets.MenuItem;
import
org.eclipse.swt.widgets.Shell;
import
org.eclipse.swt.widgets.Text;
public
class
Mainform
extends
Shell {
/**
* Launch the application.
* @param args
*/
static
Mainform shell;
private
Text txtName;
private
Label lblAnswer;
public
static
void
main(String args[]) {
try
{
Display display = Display.getDefault();
shell =
new
Mainform(display);
shell.open();
shell.layout();
while
(!shell.isDisposed()) {
if
(!display.readAndDispatch()) {
display.sleep();
}
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* Create the shell.
* @param display
*/
public
Mainform(Display display) {
super
(display, SWT.SHELL_TRIM);
setLayout(
new
GridLayout(
2
,
false
));
Menu menu =
new
Menu(
this
, SWT.BAR);
setMenuBar(menu);
MenuItem mntmNewSubmenu =
new
MenuItem(menu, SWT.CASCADE);
mntmNewSubmenu.setText(
"ファイル(&F)"
);
Menu menu_1 =
new
Menu(mntmNewSubmenu);
mntmNewSubmenu.setMenu(menu_1);
MenuItem mntmNewItem =
new
MenuItem(menu_1, SWT.NONE);
mntmNewItem.addSelectionListener(
new
SelectionAdapter() {
@Override
public
void
widgetSelected(SelectionEvent arg0) {
shell.close();
}
});
mntmNewItem.setText(
"閉じる(&X)"
);
Label lblNewLabel =
new
Label(
this
, SWT.HORIZONTAL);
lblNewLabel.setText(
"名前を入力してください"
);
txtName =
new
Text(
this
, SWT.BORDER);
txtName.setLayoutData(
new
GridData(SWT.FILL, SWT.CENTER,
true
,
false
,
1
,
1
));
Label lblNewLabel_1 =
new
Label(
this
, SWT.NONE);
lblNewLabel_1.setText(
"ボタンをクリックしてください"
);
Button btnOK =
new
Button(
this
, SWT.NONE);
btnOK.addSelectionListener(
new
SelectionAdapter() {
@Override
public
void
widgetSelected(SelectionEvent arg0) {
lblAnswer.setText(txtName.getText() +
"さん こんにちは"
);
}
});
btnOK.setText(
"OK"
);
new
Label(
this
, SWT.NONE);
lblAnswer =
new
Label(
this
, SWT.NONE);
lblAnswer.setText(
" "
);
createContents();
}
/**
* Create contents of the shell.
*/
protected
void
createContents() {
setText(
"SWT Application"
);
setSize(
450
,
300
);
}
@Override
protected
void
checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
なぜか lblAnswerに ハイライト表示したように spaceを埋めておかないと ボタンをクリックしても 何も表示されません。
- 実行結果
名前を入力し ボタンをクリックすると 目的どおり 挨拶メッセージが表示されました。
メニューで ファイル > 閉じる とクリックすると プログラムが終了します。
また Alt + F、Alt + X としても プログラムが終了します。成功です !!!
FXML + Scene Builderとの比較
SWT + WindowBuilder で FXML + Scene Builder で作ったGUIプログラムと同様のプログラムを作成しました。
- デザイン画面でコントロールを削除すると、イベントハンドラも削除される。
- デザイン画面から イベントハンドラの追加・修正を指定すると対応するコードが開く。
など Visual Studioと同じように デザイン画面とコードEditorが同期して 現時点では Scene Builderより WindowBuilderのほうが使いやすい印象を受けました。
ただ JavaFXでは、CSS・JavaScriptを使えるなど 知らなかったことばっかり もっと勉強しないと・・・
コメント
swt.jarなんてどこにありますか?
Eclipceのサイト構成が2015年当時から、変わっていて分かりにくかったみたいですね。私も探しちゃいました。
ここ http://download.eclipse.org/eclipse/downloads/drops4/R-4.8-201806110500/#SWT
のページの 「SWT Binary and Source」に あるZIPからお使いのOSに対応したZIPをダウンロード・解凍し その中のswt.jarをご利用ください。
なお、本記事は2015年当時の情報に基づいて記述してありますので、現在の状況とは異なっている場合があります。この点ご了承願います。