JavaFXで画像を使ったボタンを作る方法

ちょっとしたメモです。

RIAを開発するとき、デザイナさんと連携して作ることが多いと思います。
ボタンのようなコントロールについても画像として素材を作ってもらい、それを組み込んで使うというシチュエーションも結構あることでしょう。
というわけでJavaFXで画像を使ってボタンを作る方法です。

JavaFXCSSを使って装飾することができます。HTMLのCSS2.1やCSS3をベースにしており、多くの場合同じプロパティを使うことができます。ただし、ベンダープレフィックス "-fx-" を付ける必要がありますが。

画像をボタンの背景として使いたい場合、CSS3のborder-image属性を使うことができます。次のようにCSSを作成します。

.img-button {
    -fx-border-image-source: url('img/btn.png');
    -fx-border-image-slice: 4 5 4 5 fill;
    -fx-border-image-width: 4 5 4 5;
    -fx-border-image-repeat: stretch;
    -fx-border-color: null;
    -fx-background-color: null;
    -fx-text-fill: white;
}
.img-button:hover {
    -fx-border-image-source: url('img/btn_hover.png');
}
.img-button:pressed {
    -fx-border-image-source: url('img/btn_pressed.png');
}
.img-button:disabled {
    -fx-border-image-source: url('img/btn_disabled.png');
}

border-image-slice プロパティを使うことで、画像を枠の部分と中央部分に分割し、枠部分の拡大率を保持したまま中央部分のみを拡大縮小する、いわゆる「9スライス」も指定可能です。fill も指定して、真ん中も塗りつぶすようにします。

border-image-width プロパティでボーダーの幅を指定します。border-image-repeat で stretch を指定すると、中央は引き伸ばされるようになります。
ベンダープレフィックスを取り除けば、HTMLのCSSと同じになることが分かります。

文字の色については -fx-text-fill プロパティで指定します。これはHTMLとは異なるので注意が必要です。
後は、border-color、background-color を null にして、従来の描画を消せばOKです。
hover や pressed といった疑似クラスもHTMLの場合と同じように指定可能です。

Java側では次のような感じでCSSを設定します。

        final Button imgBtn = new Button("これは画像を使ったボタンです");
        imgBtn.setPrefHeight(40);
        imgBtn.getStyleClass().add("img-button");

実行するとこんな感じで画像を背景にしたボタンが表示されます。わざと縦方向も伸ばしていますがちゃんと四隅を崩さずに伸ばしているのが分かりますね。

スクリーンショットじゃ分かりませんが、マウスオーバーやマウスクリックでも用意した画像に切り替わります。

とまあこんな感じで割とHTMLでのCSSと同じように書けそうです。HTMLデザインの技術を活かすことができるというのは結構なアドバンテージではないかと思っています。*1

*1:FlexでもCSSは使えますが、プロパティはHTMLで使うCSSとはかなり異なります。