OSTRACISM CO.

C#とObjective-CとJavaと...

ダイアログ

 一般的なGUIアプリでは、細かい設定を行うためにダイアログを利用する。
 ダイアログには各種のGUI部品を配置して、ユーザとのやり取りを行う。

C#

public class TCreateIndexFileDlg : System.Windows.Forms.Form {
	...
}
 .NETのSystem.Windows.Forms.Formはあらゆるタイプのウィンドウの機能を持っており、ダイアログもFormで作成する。Visual Studioでグラフィカルにダイアログ画面を作成すると自動的にソースに反映される。基本的に.NET環境ではGUI部品の配置はコードとして記述される。
private void menuCreateIndexFile_Click(object sender, System.EventArgs e) {
	...
	TCreateIndexFileDlg dlg = new TCreateIndexFileDlg();
	dlg.Setup(ref m_gs);
	if(dlg.ShowDialog() == DialogResult.OK) {
		...
	}
	dlg.Dispose();
}
 ダイアログを表示するユーザーアクションが発生したら、ダイアログのインスタンスを作成し、適切な初期化の後にShowDialogメソッドを呼び出す。終了したらインスタンスをDisposeする。
private void btnIndexFilePathRef_Click(object sender, System.EventArgs e) {
	...
	if(saveFileDialog.ShowDialog() == DialogResult.OK)
		edtIndexFilePath.Text = saveFileDialog.FileName;
}
 標準ファイル保存ダイアログはSystem.Windows.Forms.SaveFileDialogを使う。
 標準ファイル保存ダイアログはVisual StudioでグラフィカルにGUI部品を並べる一環として配置でき、ダイアログが初期化されたときにインスタンスが作られている。

Objective-C

@interface TCreateIndexFileDlg : NSObject
{
	...
}
 CocoaにおいてはまずInterface Builderでダイアログをグラフィカルに作る。次にダイアログの動作をコードで記述する方法を選ばなくてはいけない。ダイアログ(フォームのあるウィンドウ)のクラスであるNSPanelを継承したサブクラスを新設する方法がひとつ。ダイアログを制御する独立のクラスを新設するのがひとつ。
 TCreateIndexFileDlgは後者の制御クラスで、Interface BuilderでNSObjectクラスを継承したサブクラスを用意して、インスタンス化して、GGG4Mクラスインスタンスのアウトレットに登録している。TCreateIndexFileDlgにはダイアログウィンドウをアウトレットとして登録している。
- (IBAction)menuCreateIndexFileAction:(id)sender {
	...
	[createIndexFileDlg setup:m_gs];
	if ([createIndexFileDlg doModal]) {
		...
	}
}

- (BOOL)doModal {
	m_result = NO;
	[NSApp runModalForWindow: window];
	return m_result;
}
 Cocoaではアプリケーションが起動して.nibファイルが読み込まれた段階で全てのダイアログのインスタンスが生成されている。ダイアログを表示するアクションに対しては既存のダイアログインスタンスを引数にNSAppクラスのrunModalForWindowメソッドを呼び出すことになる。
 runModalForWindowはstopModalメソッドが呼ばれるまで制御が帰ってこない。呼び出した側のスレッドのウィンドウはブロックされる。
- (IBAction)indexFilePathRefAction:(id)sender
{
	...
	NSSavePanel *dlg = [NSSavePanel savePanel];
	...
	if ([dlg runModalForDirectory:dir file:name] == NSFileHandlingPanelOKButton)
		[tfIndexFilePath setStringValue:[dlg filename]];
}
 標準ファイル保存ダイアログはNSSavePanelを使う。

Java

public class TCreateIndexFileDlg extends javax.swing.JDialog {
	...
}
 NetBeansで新規にダイアログクラスを作る場合、通常はSwingのjavax.swing.JDialogを継承したクラスになる。.NETもCocoaもダイアログという名前を避けてるような気配だが、Swingはまっとうにダイアログという名前を使っている。結局ダイアログはウィンドウの特殊な状態であり特別独立にクラス化すべきものでないという考えが.NETやCocoaには感じられるが、設計の古いSwingは当時(Windows APIやMac OS Toolboxで)一般的だったダイアログという概念を普通に取り入れてクラス化している。
private void menuCreateIndexFileActionPerformed(java.awt.event.ActionEvent evt) {
	...
	TCreateIndexFileDlg dlg = new TCreateIndexFileDlg(m_mainWindow, true);
	dlg.setup(m_gs);
	if (dlg.doModal()) {
		...
	}
}

public boolean doModal() {
	setVisible(true);
	return m_result;
}
 普通にダイアログのクラスをインスタンス化し、表示する。
 javax.swing.JDialogクラスのsetVisible(true)メソッドはsetVisible(false)が呼ばれるまで制御が帰ってこない。呼び出した側のスレッドのウィンドウはブロックされる。
private void btnSelectIndexFilePathActionPerformed(java.awt.event.ActionEvent evt) {
	JFileChooser dlg = new JFileChooser();
	...
	dlg.setFileFilter(filter);
	if(dlg.showSaveDialog(this) == JFileChooser.APPROVE_OPTION)
		tfIndexFilePath.setText(dlg.getSelectedFile().getPath());

}
 標準ファイル保存ダイアログはjavax.swing.JFileChooserを使う。ファイルのフィルタリングのための仕組みがまた大げさで、javax.swing.filechooser.FileFilter抽象クラスを継承具体化したクラスを独自に用意しそのインスタンスを渡すというものだ。あんまりなので、Sun製のサンプルExampleFileFilter.javaをそのまま使っている(パッケージだけ変更)。

2005.07.31
「インデックス」へ戻る

OSTRACISM CO.
OSTRA / Takeshi Yoneki