torutkのブログ

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

JavaFX 8でcssファイルに定義したHBoxのスタイルが反映されない

JavaFXではGUI部品の見栄え(背景色、フォントなど)をAPIから設定する他に外部CSSファイルに記述して設定することが可能です。

例えば、Labelの見栄えについてはCSSファイルに次のように記述し、読み込ませることですべてのラベル部品の表示に反映できます。

.label {
    -fx-font-size: 11pt;
    -fx-font-family: "Meiryo UI";
    -fx-text-fill: red;
    -fx-opacity: 0.6;
}

CSSファイルの反映は、FXMLのルート要素に記述するか、APIでSceneに設定するかの方法があります。Scene Builderを使っていれば、一番下に敷いている(シーンの階層構造のもっとも上位の)コンテナのプロパティ"Stylesheets"にファイルを指定します。

プログラムを実行すれば、ラベルの見栄えがCSSの定義に合わせて変わります。

しかし、HBoxの見栄えを変えるべく次のようにCSSファイルに記述したところ、この記述は反映されませんでした。

.hbox {
    -fx-background-color: #1d1d1d;
}

API(setStyleメソッド)で直接HBoxインスタンスにスタイルを設定するか、FXML(Scene Builder)でHBoxのプロパティ"Style Class"にhbox(CSSで.hboxと定義するとクラスhboxとなる)を指定すると反映されました。しかし、HBoxを使う箇所で個々に定義する必要があります。

なぜかなぁと調べまわっていたところ、OracleJavaFXドキュメント「JavaFX: Working with JavaFX UI Components」の37章「Styling UI Controls」で次の注記がありました。

If a class does not have a style defined in the modena.css style sheet, define the style in your style sheet and assign it to each class instance as shown in Example 37-6. For example, layout panes do not have styles defined in the modena.css style sheet.

(超簡訳)JavaFX 8のデフォルトテーマであるmodena.cssに定義のないクラスは、自前のスタイルシートに定義した上にクラスのインスタンスに設定しなければならない。

ちなみに、/jre/lib/ext/jfxrt.jar の中にmodena.cssが含まれています。取り出して、ドンナクラスが定義されているかを調べてみました。

$ cat modena.css | grep -o -e "^\.[a-z][^ .:,]*"|sort|uniq
.accordion
.area-legend-symbol
.axis
.axis-minor-tick-mark
.axis-tick-mark
.bar-chart
.bar-legend-symbol
.bubble-legend-symbol
.button
.cell
.chart
.chart-alternative-column-fill
.chart-alternative-row-fill
.chart-area-symbol
.chart-bar
.chart-bubble
.chart-content
.chart-horizontal-grid-lines
.chart-horizontal-zero-line
.chart-legend
.chart-line-symbol
.chart-pie
.chart-pie-label
.chart-pie-label-line
.chart-series-area-fill
.chart-series-area-line
.chart-series-line
.chart-symbol
.chart-title
.chart-vertical-grid-lines
.chart-vertical-zero-line
.check-box
.check-box-table-cell
.check-menu-item
.choice-box
.color-palette
.color-picker
.combo-box
.combo-box-base
.combo-box-popup
.context-menu
.custom-color-dialog
.date-cell
.date-picker
.date-picker-popup
.default-color0
.default-color1
.default-color2
.default-color3
.default-color4
.default-color5
.default-color6
.default-color7
.html-editor
.html-editor-align-center
.html-editor-align-justify
.html-editor-align-left
.html-editor-align-right
.html-editor-background
.html-editor-bold
.html-editor-bullets
.html-editor-copy
.html-editor-cut
.html-editor-foreground
.html-editor-hr
.html-editor-indent
.html-editor-italic
.html-editor-numbers
.html-editor-outdent
.html-editor-paste
.html-editor-strike
.html-editor-underline
.hyperlink
.label
.list-cell
.list-view
.menu
.menu-bar
.menu-button
.menu-down-arrow
.menu-item
.menu-up-arrow
.mnemonic-underline
.negative
.pagination
.pie-legend-symbol
.progress-bar
.progress-indicator
.radio-button
.radio-menu-item
.root
.scroll-bar
.scroll-pane
.separator
.slider
.split-menu-button
.split-pane
.stacked-bar-chart
.table-cell
.table-row-cell
.table-view
.tab-pane
.text
.text-area
.text-input
.titled-pane
.toggle-button
.tool-bar
.tool-bar-overflow-button
.tooltip
.tree-cell
.tree-table-cell
.tree-table-row-cell
.tree-table-view
.tree-view
.web-view

となっています。なるほど、hboxやvbox、anchorpane、borderpaneなどのコンテナ系クラスの定義がありません。

HBoxにCSSの定義を割り当てるときは、APICSSのスタイルクラスを指定するかFXML(Scene Builder)でスタイルクラスを指定します。

APIでスタイルクラスを指定

HBox hbox = new HBox();
hbox.getStyleClass().add("hbox");

Scene Builderの場合は、画面に貼ったHBoxを選択しそのプロパティStyle Classでhboxを指定します。

HBoxにCSSで見栄えを与えるサンプルは、OracleJavaFXドキュメント「JavaFX: Working with Layouts in JavaFX」の3章「Styling Layout Panes with CSS」に記載されています。