torutkのブログ

ソフトウェア・エンジニアのブログ

JavaFXでカレンダー表示プログラムを作る(DatePickerのポップアップ利用)(続々々)

はじめに

JavaFX でカレンダー表示を位置から作った、という内容を紹介しているブログを見つけました。こちらは、GridPaneを使って実現していました。
Java8でカレンダーを表示してみる - なるとブレイク

最初、TableViewを使ってカレンダー表示を作ろうとして挫折したので、これは部品選択を間違っていたようです。

色の設定

前々回(id:torutk:20160705)は、カレンダー表示の文字と余白を小さくするため、CSSファイルを読み込み適用するコードと、JavaFX 8標準の modena テーマのCSSファイルをJDKから取り出しDatePickerの表示設定を上書きしました。

前回(id:torutk:20160706)は、ウィンドウのタイトルバーと枠を取っ払いました。

今回は、次の色の設定をしてみることとします。

  • カレンダー表示で先月および来月の日付を薄くします。
  • 今日の表示の色を変更します。
  • 土日祝日の色変更(できるか?)
先月および来月の日付の表示色

JavaFX 8の modena テーマのCSSファイルから、カレンダー表示(.date-picker-popup)のあたりを探します。

.date-picker-popup > * > .previous-month,
.date-picker-popup > * > .next-month {
    -fx-background: derive(-fx-control-inner-background, -4%);
}

先月の日付、来月の日付となるセルについては、背景色を暗くしています。
deriveは色に対する関数で、JavaSE 8のJavaFX CSSリファレンス・ガイドには次の説明があります。

derive関数は、色を取得し、その色のさらに明るいバージョンまたは暗いバージョンを計算します。2つ目のパラメータは明度オフセットで、派生する色をどの程度明るくまたは暗くするかを表します。正の割合は色を明るくすることを示し、負の割合は色を暗くすることを示します。値を-100%にすると完全に黒になり、0%にすると明度に変化はなく、100%にすると完全に白になります。

このセレクタを使って、文字色を設定します。

.date-picker-popup > * > .next-month,
.date-picker-popup > * > .previous-month {
    -fx-text-fill: derive(-fx-text-base-color, 80%);
}

文字色は、明るくすることで背景色に近づき薄くなります。

今日の表示の色

modena テーマのCSSファイルから、カレンダー表示(.date-picker-popup)のあたりを探します。

.date-picker-popup > * > .today {
    -fx-background-color: -fx-control-inner-background, derive(-fx-selection-bar-non-focused, -20%), -fx-control-inner-background;
    -fx-background-insets: 1, 2, 3;
}

ここで、-fx-background-colorには3つの色が指定されています。なんでしょうか?
JavaFX CSSリファレンス・ガイド のRegionの解説に、

  • fx-background-colorプロパティは、1つ以上のカンマ区切りの値の系列です。系列の値の数によって、ペイントされる背景の矩形の数が決まります。背景の矩形は、この値を使用して指定した順にペイントされます。各背景の矩形では、半径および枠が異なる場合があります。

とあります。どうやら1つ目、2つ目、3つ目で背景となる矩形の大きさや形状が違っていて、それぞれの色を指定すると繰り返し背景が重ねて塗りつぶされるようです。
では、異なる背景の矩形とは? 解説の続きに、

  • fx-background-radiusプロパティおよび-fx-background-insetsプロパティは、カンマ区切りの値の系列(または値セット)です。特定の背景に使用される半径および枠の値は、-fx-background-radius系列および-fx-background-insets系列の対応する位置にあります。

とあります。ちょっと分かりにくいですが、-fx-background-radiusと-fx-background-insetsで複数の背景の形状を設定するのだと読み取れます。

解説の続きに

たとえば、-fx-background-colorプロパティに3つの値からなる系列が指定されているとします。3つの値からなる系列は、-fx-background-radiusプロパティおよび-fx-background-insetsプロパティにも指定されている必要があります。最初の背景は最初の半径値および最初の枠値を使用してペイントされ、2つ目の背景は2つ目の半径値および2つ目の枠値を使用してペイントされ、以下同じように続きます。

とあります。ここで、日付を表示するセルに設定されている-fx-background-radiusを調べてみましたが、直接指定している個所は見当たりませんでした。どうなっているのかな?
表示させてみると、1ピクセルずつ小さくなる矩形でした。つまり、異なる色を複数設定すると枠線のように見えることになります。

そこで、枠線相当の色を赤系にして今日の日付表示を目立たせることとします。

.date-picker-popup > * > .today {
    -fx-background-color: -fx-control-inner-background, magenta, -fx-control-inner-background;
}

ところが、プログラムを実行すると、赤枠は表示されたものの日付の数値が表示されません。

かなりあてずっぽうで試行錯誤をしてみたところ、次の設定を追加すると表示されるようになりました。

.date-picker-popup > * > .today:hover,
.date-picker-popup > * > .today.selected {
    -fx-background-color: -fx-selection-bar, derive(-fx-selection-bar-non-focused, -20%), -fx-selection-bar;
}

この設定は、もともと modena.css にあるものと同じ設定をしているだけなのですが・・・。

土日祝日の色変更(できるか?)

時間切れにつき後日取り組み。

ここまでのプログラム

ここまでを反映したプログラムは次にあります。

https://github.com/torutk/calendar/tree/v0.1.3