ウィンドウを描いてみた

現在のJavaFXではアラートなどサブウィンドウの表示はあまり見栄えの良いものがありませんので作ってみました。

動作サンプルソースコードです。

JavaFXで用意されているメソッド

JavaFX1.2.1では簡単な確認ダイアログやアラートダイアログを表示する関数が用意されています。

import javafx.stage.Alert;

Alert.inform("情報", "お知らせです");
Alert.confirm("確認", "保存します。");
Alert.question("確認", "よろしいですか?");

confirmでは「了解」「取消」、questionでは「はい」「いいえ」タイプの確認ダイアログが表示されますが、これはプラットフォームに依存するシステムダイアログです。プラットフォームに依存しないようなスクリプトを書けるのがJavaFXの特徴ではありますが、ディスクトップ環境ではどうしても味気ないですね・・・。

というわけでカスタムノードで作ってみました。CustomNodeは使い慣れると簡単に新しいノードを作れるのは非常に強力です。そのほとんどは、既存のシェイプなどを組み合わせればいいので簡単なのです。

使用方法というかインターフェイス

使う側から考えて実装するのが良い方法です。

    Window {
        title: "Simple Window - サンプル"
        width: 300, height: 200
        content: [
            HBox {
                layoutX: 10, layoutY: 10
                spacing: 5
                content: [
                    Label {
                        text: "Your Name"
                    }
                    TextBox {}
                ]
            }
        ]
    }

こんな感じでウィンドウを作れるようにしました。

一部だけ角丸にしたい・・・

Rectangleを使えば角丸の長方形は簡単に描画できるのですが、四辺とも角丸になってしまいます。ここで作りたいのは上部だけ角丸のシェイプです。このような場合は、Pathを使って描画します。
以下、抜粋。

                Path {
                    elements: [
                        MoveTo { x:0, y:frameHeight }
                        VLineTo { y:frameArc }
                        ArcTo { x:frameArc, y:0, radiusX:frameArc, radiusY:frameArc, sweepFlag:true }
                        HLineTo { x:bind width - frameArc }
                        ArcTo { x:bind width, y:frameArc , radiusX:frameArc, radiusY:frameArc, sweepFlag:true }
                        VLineTo { y:frameHeight }
                    ]
                    fill: bind LinearGradient {
                        startX : 0.0, startY : 0.0
                        endX : 0.0, endY : 1.0
                        stops: [
                            Stop {color : brightColor(frame), offset: 0.0},
                            Stop {color : frame, offset: 1.0},
                        ]
                    }
                    stroke: bind frame
                    onMouseReleased: function(event) {
                        if (not draggable) return;
                        window.layoutX += window.translateX;
                        window.layoutY += window.translateY;
                        window.translateX = 0;
                        window.translateY = 0;
                    }
                    onMouseDragged: function(event) {
                        if (not draggable) return;
                        window.translateX = event.dragX;
                        window.translateY = event.dragY;
                    }
                }

elementsでは始点を決めた後、次のポイントまでのラインの種別を決めていきます。垂直線、弧、水平線、弧、垂直線といった感じで上部のタイトルバーを書いているわけです。簡単ですね!
まだ塗りは基本色からグラデーションを作ってみました。さらにタイトルバーにはマウスイベントを仕込んでおき、ドラッグできるようにしています。

あ・・・閉じられないやw