前回 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年当時の情報に基づいて記述してありますので、現在の状況とは異なっている場合があります。この点ご了承願います。