こんにちは。櫻です。
今回はJava SE8からSwingの代わりに標準GUIライブラリになるらしいJavaFXをScalaで利用してみようと言うネタです。
お試しでJDK8で動作させましたが、JavaFX8の機能は試せていません。
以下の環境で試してみました。
JDK | 1.8.0 b111 |
sbt | 0.13.0 |
scala | 2.10.3 |
scalafx | 8.0.0_M2 |
JavaFXとScalaFX
JavaFXはJavaのGUIライブラリでJDK8からはSwingに代わって標準のGUIライブラリになるそうです。
JavaFXについての詳細はJava技術最前線 - Java技術最前線:ITproが参考になります。
JavaFXではGUIの構成をxmlで記述する事ができ、それを編集するScene Builderというツールも提供されています。
iOSの開発でいうxibファイルとInterfaceBuilderの様なものです。
ScalaFXはこのUI部分をScalaのDSLで記述出来る様にしようというプロジェクトです。
http://code.google.com/p/scalafx/
下記の様なコードでUIの構成を記述できます。
stage = new JFXApp.PrimaryStage { title = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = new Rectangle { x = 25 y = 40 width = 100 height = 100 fill <== when (hover) choose Color.GREEN otherwise Color.RED } } }
準備
sbt用のディレクトリとbuild.sbtを作ります。以下、プロジェクトディレクトリを基準にしています。
$ mkdir -p src/{main,test}/scala
build.sbtは以下の様にしておきます。
scalaVersion := "2.10.3" libraryDependencies ++= Seq( "org.xerial" % "sqlite-jdbc" % "3.7.2", // sqliteを使わないなら不要 "org.scalafx" %% "scalafx" % "8.0.0-M2" )
この状態でsbtを実行すればよろしくやってくれます。
基本的な使い方は前述のリンク等を参考にするとして、個人的に良く使いそうなTableView、TreeView等の使い方を確認します。
(他にもWebView、TabPane、TreeTableView(JavaFX8で追加)等もありますが…)
TableView
TableViewを使う上で重要になるのは、TableViewクラスとTableColumnクラスです。
TableViewは型引数を一つ取ります。TableView[T](JavaではTableView
Tは1行の情報をもつオブジェクトの型です。
TableColumnは型引数を二つ取ります。一つはTableViewのTと同じもの、もう一つはその列で表現する型です。
TableColumn[T, U]はT型のレコードからU型のフィールドを表現する列という事になります。
たとえば
case class Record(id: Int, name: String, guest: Boolean = false)
というデータの一覧を表示するTableViewの場合、TableView[Record]というTableViewと、
TableColumn[Record, Int]、TableColumn[Record, String]、TableColumn[Record, Boolean]という3つのTableColumnを
組み立てていけば良い事になります。
object TableSample extends JFXApp { // 列の定義 val idColumn = new TableColumn[Record, Int]("id") { cellValueFactory = f => new ObjectProperty[Int](f.value, "id", f.value.id) prefWidth = 80 } val name = new TableColumn[Record, String]("name") { cellValueFactory = f => new StringProperty(f.value, "name", f.value.name) prefWidth = 100 } val guest = new TableColumn[Record, Boolean]("guest") { cellValueFactory = f => new ObjectProperty[Boolean](f.value, "guest", f.value.guest) } stage = new JFXApp.PrimaryStage { title = "Hello ScalaFX TableView" scene = new Scene { fill = Color.LIGHTBLUE root = new VBox { hgrow = Priority.ALWAYS content = new TableView[Record] { vgrow = Priority.ALWAYS columns ++= Seq(idColumn, name, guest) items = ObservableBuffer( Record(1, "name1", guest = true), Record(2, "name2", guest = true), Record(3, "name3"), Record(4, "name4") ) } } } } }
これを実行するとこのようになります。
TreeView
続いてTreeViewです。
TreeViewで重要なのはTreeView[T]とTreeItem[T]の二つのクラスです。
TreeView内の一つのノードを表すのがTreeItemクラスで、Tはそのノードに対応付けるデータの型です。
例えばTreeItem[String]で
root ├─ parent1 │ ├─ child1 │ ├─ ... │ └─ child9 └─ parent2 ├─ child1 ├─ ... └─ child9
という木を作成し表示するとこのようになります。
コードはこうなります。
object TreeSample extends JFXApp { val tree = new TreeView[String]() { vgrow = Priority.ALWAYS root = new TreeItem[String]("root") { children = Seq(nodes("parent1"), nodes("parent2")) } } stage = new JFXApp.PrimaryStage { title = "Hello ScalaFX TreeView" scene = new Scene { fill = Color.LIGHTBLUE root = new VBox { hgrow = Priority.ALWAYS content = tree } } } def nodes(name: String) = new TreeItem[String](name) { children = (1 until 10).map { i => new TreeItem[String]("child" + i) } } }
DB Viewerサンプル
TableViewやTreeViewの使い方に慣れておくと、ちょっとしたツールが簡単に作成できるようになります。
例えばJDBC経由でDBへ接続し、テーブルの一覧を取得しTreeViewで表示し、テーブルを選択するとその内容をTableViewで表示する…
の様な事が簡単にできたりします。
SQLiteのDBを開いてみた図
このサンプルで150行程度(実質100行程度?)で出来ています。
コードはこちら。
https://github.com/hatena-iti/scalafx-sample