読者です 読者をやめる 読者になる 読者になる

きくらげ観察日記

好きなことを、適当に。

ScalaFXでデフォルトのCSSが見当たらない

Scala

ScalaFXの練習として、とりあえず公式にあるサンプルを写経していた所、次のような現象に遭遇しました。

問題になったコードは以下の通り。ほぼ下記のサイトのコードそのままです。
http://www.scalafx.org/docs/faq_TableView_with_Custom_cell/

import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.beans.property.{StringProperty, ObjectProperty}
import scalafx.collections.ObservableBuffer
import scalafx.scene.Scene
import scalafx.scene.control.TableColumn._
import scalafx.scene.control.{TableCell, TableColumn, TableView}
import scalafx.scene.paint.Color
import scalafx.scene.shape.Circle

class Person(firstName_ : String, 
             lastName_ : String, 
             favoriteColor_ : Color) {
  val firstName = new StringProperty(this, "firstName", firstName_)
  val lastName = new StringProperty(this, "lastName", lastName_)
  val favoriteColor = new ObjectProperty(this, "favoriteColor", 
                                         favoriteColor_)
}

object TableWithCustomCellDemo extends JFXApp {

  val characters = ObservableBuffer[Person](
    new Person("Peggy", "Sue", Color.Violet),
    new Person("Rocky", "Raccoon", Color.GreenYellow),
    new Person("Bungalow ", "Bill", Color.DarkSalmon)
  )

  stage = new PrimaryStage {
    title = "TableView with custom color cell"
    scene = new Scene {
      content = new TableView[Person](characters) {
        columns ++= List(
          new TableColumn[Person, String] {
            text = "First Name"
            cellValueFactory = { _.value.firstName }
            prefWidth = 100
          },
          new TableColumn[Person, String]() {
            text = "Last Name"
            cellValueFactory = { _.value.lastName }
            prefWidth = 100
          },
          new TableColumn[Person, Color] {
            text = "Favorite Color"
            cellValueFactory = { _.value.favoriteColor }
            cellFactory = { _ => 
              new TableCell[Person, Color] {
                item.onChange { (_, _, newColor) => 
                  graphic = new Circle {fill = newColor; radius = 8}
                }
              }
            }
            prefWidth = 100
          }
        )
      }
    }
  }
}

これを実行すると、次のような画面が表示されます。

f:id:cloudear8:20160223085301p:plain

やたらとしょぼい表示ですが、一応TableViewによる表の表示ができています。
ところで、これを公式のサンプルにあるスクリーンショットと見比べてみましょう。

f:id:cloudear8:20160223085516p:plain

……
なんだこのクオリティの差は……。
(※画像はイメージです)って小さく書かれてたとしてもキレるレベルですねこれは。

さらにログをよく見てみると、このウィンドウを表示する際に以下のようなwarningが出ていることに気付きました。

2 23, 2016 8:37:43 午前 com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "com/sun/javafx/scene/control/skin/modena/modena.css" not found.

javafxで用意されているデフォルトのCSSファイルらしきものをうまく読み込めていないようです。
調べてみると、JavaFXのjarファイルの位置がJava8で変更になったにも関わらず、sbt側がそれを検知できていないことが原因のようです。
元のパスは"$JAVA_HOME/jre/lib/jfxrt.jar"、変更先は"$JAVA_HOME/jre/lib/ext/jfxrt.jar"ということなので、build.sbtに以下を追記

lazy val root = (project in file(".")).
  settings(
    // ...(その他の設定)
    unmanagedJars in Compile += {
        val ps = new sys.SystemProperties
        val jh = ps("java.home")
        Attributed.blank(file(jh) / "lib/ext/jfxrt.jar")
    }
  )

sbt runすると、ちゃんとmodena.cssが読み込まれていることが確認できます。

f:id:cloudear8:20160223090731p:plain

Scalaファンクショナルデザイン ―関数型プログラミングの設計と理解

Scalaファンクショナルデザイン ―関数型プログラミングの設計と理解

JavaFX & Java8プログラミング―Javaによる新しいGUIプログラミング入門

JavaFX & Java8プログラミング―Javaによる新しいGUIプログラミング入門