画面の操作をブロックする

いわゆるモーダルダイアログなど、一時的にメインとなる画面の操作をブロックしたい事があります。また単にブロックするだけではなく、背景を暗くする・スモークをかける・フェードイン/アウトするなどのエフェクトがあるとよりリッチなGUIとなります。また、背景を暗くする事などはメインとなるダイアログ等を目立たせるという効果もあり、LightBox系のコンポーネントでも使われているテクニックです。
今回はそんなメイン画面をブロックするようなユーティリティクラスをJavaFXで実装したので紹介します。



サンプルはこちらから、OverlayBlockerを選択して確認ください。

OverlayBlocker

OverlayBlockerの使い方は単純で、インスタンスを生成し、ブロックする場合はblock関数、解除する場合はunblock関数を呼び出すだけです。

var overlay:OverlayBlocker = OverlayBlocker {};
overlay.block(scene);
// 解除
overlay.unblock(scene);

それぞれの引数としてSceneオブジェクトが必要です。

仕組み

Java(Swing)でも似たようなことは出来ますが、実装する場合はGlassPaneを使うなど意外と面倒です*1JavaFXの場合はアニメーションやエフェクトなどの仕組みは充分に揃っているため、実装は容易になります。ソースコードこちら

ポイントは2つです。

var overlayBox:Rectangle = Rectangle {
    fill: fill
    opacity: bind boxOpacity
    blocksMouse: true
};// Rectangle - background blocker

まず、このoverlayBoxが画面全体をブロックするための矩形であり、すべてのノードの上にSceneと同じ大きさで配置されます。したがって、全画面がカバーされます。また、blocksMouseをtrueに設定することで、下に配置されるコンポーネントにマウスイベントを伝播させないようにしています。

2つ目のポイントはどうやってoverlayBoxを配置するかですが、実は単純で、Sceneのcontentの最後に追加してやればOKです。

insert overlayBox into scene.content;

後は、overlayBoxが切り替わるタイミングを少し遅延させたり、overlayBoxの色を調整したり、表示されているコンポーネントにブラーのエフェクトをかけたりと、アレンジは自由にすることができるでしょう。

オプション

現状で対応しているオプションは以下の通りです。

  • fill / ブロックするウィンドウの色(デフォルト黒)
  • opacity / ブロックするウィンドウの透明度(デフォルト0.4)
  • delay / ブロックするまでの間(デフォルト0.1s)
  • blur / ブラー効果(デフォルトtrue)

JavaFXの強み

このようにSwingではなかなか面倒であったようなエフェクトがJavaFXでは簡単に実装できます。応用例としてはさらにoverlayBoxよりさらに前面にウィンドウを配置することでモーダルウィンドウにしたり、ゲームのゲームオーバー時に背景を暗くしてGAMEOVERというロゴを表示したり、ホラー風味に全体を赤くブロックして上から血がしたたるようなアニメーションを配置したりと簡単に作れるでしょう。
この簡単に作れてしまうのがJavaFXの強みだと思います。

*1:実装方法はFilthy Rich Clientという本に載っています