Eclipseのプラグイン開発の独自の(JFaceの)ダイアログの作り方について。
|
独自のダイアログを作るには、org.eclipse.jface.dialogs.Dialogを継承したクラスを作る。
import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.widgets.Shell;
public class MyDialog extends Dialog { public MyDialog(Shell parentShell) { super(parentShell); } 〜 }
使う側は以下のようにする。
import org.eclipse.jface.window.Window;
MyDialog dialog = new MyDialog(shell); if (dialog.open() == Window.OK) { // ok } else { // cancel }
ダイアログ(ウィンドウ)のタイトルはshellに対してセットする。
public class MyDialog extends Dialog { private String windowTitle; public MyDialog(Shell parentShell, String windowTitle) { super(parentShell); this.windowTitle = windowTitle; }
@Override public void create() { super.create(); getShell().setText(windowTitle); } 〜 }
コンストラクターの第1引数でshellを渡しているので、そこにsetText()すれば良さそうな気もするが、
このshellにはnullが渡ってくる可能性があるので、getShell()に対してセットする方が良い。
ただしgetShell()で返ってくるshellはsuper.create()
の中で作られるので、コンストラクター時点ではgetShell()は使えない。
そこで、create()をオーバーライドして、その中でgetShell()を呼び出すようにしている。
JFaceのダイアログは、デフォルトではサイズを変えることが出来ない。[2013-09-15]
RESIZEのスタイルを指定するとサイズを変えることが出来るようになる。
public class MyDialog extends Dialog { public MyDialog(Shell parentShell) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); }
ダイアログの本体へのコンポーネントの配置はcreateDialogArea()で行う。
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control;
@Override protected Control createDialogArea(Composite parent) { Composite composite = (Composite)super.createDialogArea(parent); // SWTのコンポーネントを配置 return composite; }
ダイアログに設定された値に応じてOKボタンの使用可否を切り替える例。
import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.widgets.Button;
private void refreshOkButton() {
Button okButton = super.getButton(IDialogConstants.OK_ID);
if (okButton == null) {
return;
}
if (validateOk()) {
okButton.setEnabled(true);
} else {
okButton.setEnabled(false);
}
}
private boolean validateOk() { return コンポーネントの値をチェック; }
refreshOkButton()メソッドは、各コンポーネントにリスナーをセットして、そこから呼び出す想定。
DialogクラスにgetButton()というメソッドがあるので、そこにボタンのIDを渡してやればButtonインスタンスが取れる。
(試してないけど、たぶんIDialogConstants.CANCEL_ID
でキャンセルボタンも取れるはず
。キャンセルの可否を切り替えるような場面は想像できないけどw(キャンセルボタンを使用不可にするくらいなら、最初からキャンセルボタンを表示しない方がいいし))
プログラム内からOKボタンを押したのと同じ処理を行う例。
(ダイアログにツリーしか無くて、そのツリーの要素をダブルクリックしたらOKボタンを押したのと同じ処理にしたいとか)
private void pushOkButton() { Button okButton = super.getButton(IDialogConstants.OK_ID); if (okButton != null && okButton.isEnabled()) { okPressed(); } }
okPressed()はOKボタンが押されたときに呼ばれるメソッドなので、それを自分で呼んでやる。
同様にcancelPressed()というメソッドもあるので、たぶんCANCELボタンと同じ動作はそれを呼べば出来るだろう。
Dialogクラスは、デフォルトではOKとCANCELのボタンが配置される。
他のボタンを配置したい(あるいはOKとCANCELのどちらかだけ表示したいような)場合は、createButtonsForButtonBar()をオーバーライドする。
@Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); // createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); }
createButton()は、Buttonインスタンスを作るメソッド。
引数 | 内容 | |
---|---|---|
1 | parent | ボタンを作る領域(buttonBar) |
2 | id | ボタンに付けるID |
3 | label | ボタンに表示される文字列 |
4 | defaultButton | trueを渡すとデフォルトボタンになる |
また、OK_IDとCANCEL_ID以外のIDを割り当てた場合は、buttonPressed()をオーバーライドする必要があるようだ。
(これを記述しないと、そのボタンを押しても何も処理されないと思われる^^;)
@Override protected void buttonPressed(int buttonId) { if (buttonId == 独自に割り当てたID) { 〜 } else { super.buttonPressed(buttonId); } }