GUIベースのOSの決まり事は大きく二つある。イベント・ドリブンの仕組みと,ウインドウなどの描画に関する仕組みである。前者の基本的なアイデアはさまざまなOSで共通だが,後者については個別のOSによってかなり違う。そこで今回はイベント・ドリブンについて取り上げよう。

図3●イベント・ドリブンの基本概念。
OSがユーザの操作などにより発生したイベントを検出し,それを適切なアプリケーション・ソフトに通知する。アプリケーション・ソフトはイベントが発生する順番を考慮せずに,受け取ったイベントに対応する処理を実行する

 イベント・ドリブンとは,パソコンを操作したり,通信結果を受け取ったりして何らかの状態が変化したことを「イベント」の発生を伝搬することによってプログラムが動作する仕組みのことである(図3[拡大表示])。「事象駆動」という訳語を使うこともある。

 基本的にOSがイベントをアプリケーションに通知する。このとき,イベントが発生する手順を想定せずにアプリケーションを記述するのが基本である。このことが,GUIベースのアプリケーションとコンソール系のアプリケーションの大きな違いだと言える。コンソール・アプリケーションの場合,一つの画面しか基本的に存在しないので,多少なりとも複雑な処理を実現するにはモード切り替えの考え方が必要である。しかしGUIの場合,たいていマルチウインドウを利用できるので,別のウインドウにモードを任せることができる。

 モードの考え方は,ユーザ・インタフェースを設計するうえで「あまりよくない」とされていることの一つだ。モードを元に戻し忘れたり,切り替え損ねたりすることによる誤操作を生みやすいからだ。半面,プログラミングは楽になる。例えば「ここはカーソル・キーの入力はない」と決めつけてプログラミングできるからだ。イベント・ドリブンの場合,想定していないイベントが発生して誤動作させてしまうことがあり得る。その意味でも,モードの考え方は導入しない方がよいことが多い。モードを取り入れるとしても,モードによってボタンの有効/無効を切り替えるといった程度にとどめておく注4)。モードによって,動作そのものを変えるようなユーザ・インタフェースがよくない。極端な話,あるチェック・ボックスの値(これがモードを表現)によって,コマンド・ボタンの動作がデータの削除と追加を切り替えるようなユーザ・インタフェースでは,誤操作が頻繁に起きてしまうだろう。

すべて送るか,必要なものだけか

 それでは実際にアプリケーションがイベントをどうやって受け取っているかを見ていこう。大きく分けてその手法は二つある。アプリケーションに関連しうるイベントをOSがすべて通知してしまう方法と,アプリケーションがOSに通知してほしいイベントを登録しておき,該当するイベントが発生した時のみ通知する方法である(図4[拡大表示])。前者の例としてはWindows,後者の例としてはJDK 1.1以降のJavaや.NET Frameworkが挙げられる。後者のイベント・モデルを「委譲型(delegate)モデル」と呼ぶ。

 おそらくアプリケーションの実行効率としては前者よりも後者の方が有利だろう。だからこそJavaではAWTと呼ぶGUI部品のライブラリで採用していたイベント・モデルを破棄して,delegateモデルにしたのだ。ただアプリケーションの構造からすると,基本的には前者の方がわかりやすい。

図4●イベント・モデルの違い。
Windowsの場合,基本的にすべてのイベントをアプリケーションに通知する(a)。アプリケーションが処理しなかったイベントは,デフォルトのイベント・ハンドラに引き渡される。このことによって,共通の操作環境(例えばウインドウの拡大/縮小など)を実現している。一方Javaの場合,アプリケーションが仮想マシンに対して通知してほしいイベントをあらかじめ「依頼して」おく(b)。こうすることにより,効率のよいイベント処理を実現している
 
リスト1●.NET Frameworkを使ってGUIイベントを記述する例。
イベント処理メソッドの登録は,開発ツールが自動的に生成するコードの中に含まれている。このためプログラマはあまりこのことを意識しないで済む
 プログラムの構造を見ればこのこともわかりやすい。例えば.NET Frameworkの場合,「ボタンがクリックされた」というイベントを取り扱うプログラムは,まずイベント・ハンドラに「このメソッドに対応づけてください」というコードを記述する(リスト1[拡大表示])。Visual Studio .NETを使っていれば,この部分のコードは自動的に生成される。

(北郷 達郎、八木 玲子)