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

シーングラフ

JavaFX

JavaFX シリーズ目次

前回の Hello, World! の時に GUI はツリー構造で表せるということを書きました。

たとえば、下の絵に示した GUI はこんな構造になります。

[Scene]-[VBox]-+-[HBox]-+-[Label]
               |        +-[TextField]
               |        +-[Button]
               +-[WebView]

f:id:skrb:20120215212004p:image


このような GUI を表すツリー構造を JavaFX ではシーングラフと呼びます。

グラフといっても、棒グラフとか円グラフとかのグラフではなく、グラフ理論のグラフです。

もともと、シーングラフは 3D CG で使われていた言葉で、Java 3D もシーングラフを使用して 3D CG を構築します。でも、3D に限定する必要はまったくなく Adobe の Illsutrator などもシーングラフを使っています。

今までの Swing も同じようにツリー構造で GUI を表していました。しかし、ツリーに追加できるのは Swing のコンポーネントだけという違いがあります。JavaFX ではコントロールはもちろん、四角や丸などの今までは Java 2D で描画していた要素もシーングラフに記述することができます。

たとえば、下の GUI は...

[Scene]-[Group]-+-[Circle]
                +-[GridPane]-+-[Label]
                             +-[TextField]
                             +-[Label]
                             +-[TextField]

f:id:skrb:20120215214807p:image

Swing であれば、Circle は Java 2D で書かなくてはいけなかったので、JComponent のサブクラスを作成して paintComponent メソッドをオーバーライドする必要がありました。

でも、JavaFX だったら、単純にシーングラフに追加すればいいだけです。

現状、JavaFX は 3D の機能は限定的なのですが、視点の位置 (カメラ) やライトなどもシーングラフに記述することができます。

しかし、前回も書いたように Java だとシーングラフが分かりにくい。ということで、これからは FXML が主流になると思います。

たとえば、はじめのブラウザの場合、FXML がどうなるかというと、こんな感じ。

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.web.*?>

<VBox xmlns:fx="http://javafx.com/fxml"
      prefWidth="1000" prefHeight="740"
      fx:controller="custombrowser.CustomBrowser">
    <children>
        <HBox>
            <children>
                <Label text="URL:" />
                <TextField prefColumnCount="40" />
                <Button text="Load" />
            </children>
        </HBox>
        <WebView />
    </children>
</VBox>

でも、これだけじゃステージに該当するコントロールが表示されるだけです。

ブラウザには何も表示されませんし、ボタンを押しても何も変化はありません。FXML は GUI の構造を記述することはできますが、振る舞いは記述できません*1。振る舞いは Java で書く必要があります。

ということは FXML で書いた要素と Java を連携させる必要があります。次回はそこら辺について書く予定です。

*1:厳密には書くことができるのですが、それはまた別の機会に書きます。