JavaFX 2 Scene graph and Node

はじめに Introduction

この記事では以下の記事で作成したウェブブラウザを改造します. そしてこの改造を通してJavaFXGUIを構成する方法, 特にシーングラフについて解説します.

I modified the web browser that was made on my article as follows. With making a web browser, I am going to explain how to set up JavaFX GUI elements, and what is scene graph.

jumpaku.hatenablog.com

作業 Works

  1. JavaFXJREを含んだ新規プロジェクトを作成する
    Create new project contains JavaFX JRE.
  2. WebBrowserクラスを作成し以下のソースコードを記述する
    Create WebBrowser class and write source code as follows.
  3. 実行すると簡単なブラウザが起動される
    Run application and you can use simple web browser.

ソースコード Source code

package jumpaku.webbrowser;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.web.*;
import javafx.stage.Stage;

public final class WebBrowser extends Application {
    
    public static void main(String[] args) {
        launch(args);
    }

    private WebEngine engine = null;
    
    @Override
    public void start(Stage primaryStage) {
        WebView view = new WebView();
        engine = view.getEngine();
        
        TextField input = new TextField("https://www.google.co.jp/");
        
        engine.load(input.getText());
        
        Button go = new Button("Go");
        go.setOnMouseClicked(e -> engine.load(input.getText()));
        
        Button next = new Button("Next");
        next.setOnMouseClicked(e -> goHistory(1));
        
        Button prev = new Button("Prev");
        prev.setOnMouseClicked(e -> goHistory(-1));
        
        primaryStage.setScene(
                new Scene(
                        new VBox(
                                new ToolBar(
                                        prev, next, input, go),
                                view)));
        primaryStage.show();
    }
    
    private void goHistory(int offset){
        WebHistory history = engine.getHistory();
        int size = history.getEntries().size();
        int dist = history.getCurrentIndex() + offset;
        
        if(0 <= dist && dist < size){
            history.go(offset);
        }
    }
}

説明 Explanation

シーングラフ

JavaFXGUIを構成する部品をノードと呼びます. 特に子ノードを持てるノードをブランチ, 子ノードを持てないノードをリーフと呼びます. JavaFXGUIの構造は木構造となっており, これをシーングラフと呼びます. シーングラフのルートは親ノードを持ちません. ルート以外のノードは1個の親ノードと0個以上の子ノードを持ちます. ノードはNodeクラスで表されます. NodeクラスはGUI部品の大きさや位置, イベントハンドラ, 変換, ID, CSSスタイルなどを設定する事ができます. 今回使用したVBox, ToolBar, Button, TextField, WebViewを含む全てのGUI部品はNodeクラスのサブクラスです.

JavaFXではプロパティがサポートされています. プロパティとは値の変更を自動的に反映する仕組みです. Nodeクラスにも多くのプロパティがあります. 今回はプロパティについては説明しません.

WebBrowserクラス

WebBrowserクラスはApplicationクラスを継承しています. startメソッドをオーバーライドし, GUI部品の作成とシーングラフの組み立てをします.

startメソッドではまずWebViewオブジェクトを生成し, そのウェブエンジンをprivateフィールドengineで保持します.

次にTextFieldオブジェクトを生成します. この時コンストラクタで初期テキストとしてGoogleのURLを設定します.

それからアプリケーション起動時にGoogleが開かれる様にGoogleのページをロードします.

そして前のページに戻るprevボタン, 次のページに進むnextボタン, 入力されたurlを開くgoボタンをそれぞれ生成します. それぞれのボタンにはコンストラクタでボタンのラベルに表示される文字列を設定します. またButtonクラスのsetOnMouseClickedメソッドでボタンがクリックされた時に実行されるイベントハンドラを設定します. ここではイベントハンドララムダ式を利用しています.

そうして作成したGUI部品, ノードからシーングラフを組み立てます. VBoxオブジェクトがルートとなり, その子ノードにToolBarオブジェクトとviewを保持します. VBoxクラスは子ノードを縦に並べてレイアウトします. ToolBarオブジェクトはprev, next, input, goを子ノードとして保持します. Sceneオブジェクトを生成し, primaryStageに設定します. Sceneオブジェクトにはコンストラクタにルートを渡してシーングラフを設定します.

最後にprimaryStageのshowメソッドでウィンドウを表示します.

WebBrowserクラスはプライベートなフィールドengineを持ちます. engineはstartメソッドで初期化され, goHistoryメソッドで使用されます. goHistoryメソッドは引数のoffset分だけ閲覧履歴を移動します.

Scene Graph

GUI element of JavaFX is called node. Branch is a node that can not have any child nodes. Leaf is a node that can have some child nodes. Scene graph is a tree structure of nodes. Root of a scene graph has no parent node. Node but root has a parent and 0 or more children. Nodes are represented by Node class. You can control bounds, position, event handler, transformation, id, and CSS style of GUI elements with Node class. GUI elements includes VBox, ToolBar, TextField, and WebView class that are used in this WebBrowser are subclass of Node class.

JavaFX supports properties. Properties helps us to listen changes of values. Node class has many properties of that state. I'm sorry, this article does not explain JavaFX properties.

WebBrowser class

WebBrowser class inherits Application class. In overridden start method, GUI elements and a scene graph are constructed. In start method, first, WebView object constructed, web engine of that is set to a private field engine.

Next, TextField object is constructed with initial text string.

Google page is loaded to open google at start of the application.

Then, prev button to go previous page, next button to go next page, and go button to load input URL are constructed. Constructor of Button class sets text of label of the button with given string. Lambda expression given, setOnMouseClicked method is called to set event handler that is handled when mouse is clicked on the button.

After that, scene graph is made of these GUI elements, nodes. VBox object is the root that has 2 children Toolbar object and view. VBox class layouts children vertically. ToolBar object has 4 children pre, next, input, and go. Scene object is constructed with root of scene graph to set to that. The Scene object is set to primaryStage.

Finally, show method of primaryStage is called to show a window.

A field of WebBrowser class, engine is initialized in start method and used in goHistory method. goHistory method moves current page in web history by offset.

まとめ Summary

  • GUI部品はNodeクラスのサブクラス
    GUI elements are subclass of Node class.
  • シーングラフは木構造
    Scene graph is tree structure.