<更新記録>
2007年 12月 12日
作成

姉妹サイト検索 Web検索


ApplicationWindow

ApplicationWindow

ウィンドウの作成は、Shellクラスを直接使用するほかに、ApplicationWindowというクラスを使うことでも可能です。 ShellクラスがSWTのAPIであるのに対し、ApplicationWindowクラスは、JFaceのAPIです。

最もシンプルなApplicationWindowクラスを使ったプログラム例を示します。

ApplicationWindowDemonstracte.java
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.widgets.Display;

public class ApplicationWindowDemonstrate extends ApplicationWindow {
	private ApplicationWindowDemonstrate() {
		super(null);
	}
	
	public static void main(String[] args) {
		// (1)
		ApplicationWindow w = new ApplicationWindowDemonstrate();
		// (2)
		w.setBlockOnOpen(true);
		// (3)
		w.open();
		// (4)
		Display.getCurrent().dispose();
	}
}

SWTのプログラムと比較しながら話を進めて行きます。

FirstSWT.java
package swt;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class FirstSWT {

	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		
		shell.pack();
		shell.open();
		
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		
		display.dispose();
	}
}

まずはコンストラクタの部分の説明をします。

ApplicationWindowDemonstrate()コンストラクタでは、単純にsuper(null)を呼んで、 ApplicationWindow(Shell)のコンストラクタをnullで呼んでいます。 ここでは、nullを指定することによって、最上位ウィンドウを作成しています。

また、HelloSWTでウィンドウを作成するときには、 らかじめDisplayインスタンスを作成しておかなければなりませんでしたが、 Displayインスタンスは、ApplicationWindowが内部で生成してくれます。 この、内部で生成したDisplayインスタンスは、Display.getCurrent()メソッドで取得することができます。

次に、mainの中身の説明をします。
(1)では、ApplicationWindowのインスタンスを作成しています。 このインスタンスには(2)と(3)の操作を行うことができます。

(2)では、(3)の操作でウィンドウをオープンしたときに、 メッセージループを行うか行わないかを指定しています。 もしも(2)の処理を行わないか、falseを指定した場合には、(3)の操作でウィンドウをオープンしても、 何も起こらずにプログラムが終了します (実際にはウィンドウはオープンされますが、メッセージループが発生せずにすぐにプログラムが終了し、 何も起こらなかったように見える)。 つまり(3)の操作と同時に、 HelloSWT のサンプルの(5)の処理を自動的にやってくれる か否かを設定しているわけです。

(3)の操作で、ウィンドウがオープンします。 この部分のApplicationWindowDemonstrate.javaのソースを青色で示していますが、 対応する処理のFirstSWT.javaのソースの部分も黄色で示しています。 ApplicationWindowクラスを使うと、この(3)の操作1つで、SWTプログラミングで行っていた10行ほどのソースが短縮することが出来るのです。

(4)で、Displayインスタンスが管理していたシステムリソースを開放しています。 DisplayインスタンスはApplicationWindowクラスが自動的に作成してしまうので、 そのインスタンスは手元にありません。 Display.getCurrent()により、カレントスレッドに関連づいたインスタンス取得することができる ので、それによって取得したインスタンスに対して dispose()メソッドを呼び出しています。

外にも、ApplicationWindowクラスの使い方がありますが、それは他のページで記述します。

controlの配置

ApplicationWindowクラスの提供するフレームワークによってウィンドウを作成する場合、 controlやcompositeの配置はApplicationWindow#createContents(Composite parent)メソッドで行います。

ApplicationWindowクラスのcreateContents(Composite)メソッドは、何もcontrolを配置しません。 ApplicationWindowクラスを継承したクラスは、createContents(Composite)メソッドをオーバーライドして、 その中にcontrolの作成処理を記述します。

ApplicationWindowDemonstrate2.java
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;

public class ApplicationWindowDemonstrate2 extends ApplicationWindow {

	private ApplicationWindowDemonstrate2() {
		super(null);
	}
	
	protected Control createContents(Composite parent) {
		parent.getShell().setText("これがウィンドウのタイトル");
		
		// parent引数を親にmyComposite作成
		Composite myComposite = new Composite(parent, SWT.NONE);
		
		// myCompositeを親にmyLabel作成
		Label myLabel = new Label(myComposite, SWT.CENTER);
		myLabel.setText("つんでれ萌えー");
		myLabel.setSize(400, 100);
		
		myComposite.pack();
		parent.pack();
		
		return parent;
	}
	
	public static void main(String[] args) {
		Window w = new ApplicationWindowDemonstrate2();
		w.setBlockOnOpen(true);
		w.open();
		
		Display.getCurrent().dispose();
	}
}

controlを配置するために記述された部分は、createContents(Composite)メソッドです。 これは、ApplicationWindowDemonstrate2クラスの親クラスであるApplicationWindowクラスに定義されているメソッドです。 このメソッドを子クラスで再定義することで、そこで作成されたcontrolが描画されます。 その際、作成するcontrolの親として指定するのはparent引数です。

ウィンドウのタイトルは、parent.getShell().setText(String)で設定可能です。 getShell()メソッドは、Controlクラスで定義されていたメソッドでした。

createContents(Composite)メソッドは、Controlクラスを戻り値として返さなくてはなりません。 戻り値として返す値は、引数で取得したparentを返せばいいです。

ウンチクですが、引数のparentには、ApplicationWindowLayoutという、特殊なレイアウトが関連づけらています。 ApplicationWindowLayoutというレイアウトは、EclipseAPIとして提供されているものではありません。 これは、ApplicationWindowクラスの内部クラスです。 この ApplicationWindowLayoutは、メニューバー、ツールバー、ステータスバー等を配置するために設定されています。 なので、parentに関連づけられているこのレイアウトは、変更してはいけません。

ウンチクが続きます。 引数parentには、最初からLabelクラスのcontrolが1つだけ格納されています。 これはウィンドウのタイトルを表示するためのcontrolです。 むやみに削除等の変更をしてはいけません。

parentに1つ以上のコントロール(control及びそのサブクラスのオブジェクト)を追加するには、まず、 子コンポジット(コンテナ)を1つ追加して、その中にコントロールを複数配置するのが安全です。 サンプルプログラムでも、myCompositeを作成して、その子としてmyLabelを追加しています。 このように、ApplicationWindowクラスの提供するフレームワークを使用して作成するウィンドウにcontrolを配置するには、 Shellで直接ウィンドウを作成する場合に比べて、幾らかの制約があり、 それらを守るのは煩わしいかもしれませんが、 それ以上に、ApplicationWindowクラスが自動化してくれる部分には助けられます。

ApplicationWindowクラスが自動化してくれる部分についての説明は、 このページ以外で、個々に記載することにします。


Powered by VeryEasyCMS