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.

JavaFX 1 Application class

はじめに Introduction

この記事ではブラウザの作成を通して, JavaFXの土台となるクラスについて解説します. javafx.WebViewというクラスを使うとWebページのロードや表示をとても簡単に行うことができます. 自分を含めたJavaFX入門者の理解に繋がれば幸いです.

Developing a simple web browser, I am going to explain JavaFX classes. It is easy to load and display a web page and make a simple web browser with JavaFX. I am glad if this article makes beginners includes me understand JavaFX.

準備と実行 Preparation and Run

準備 Preparation

JavaFXの環境構築は次の記事に書いてあります.
The following is how to prepare JavaFX. https://jumpaku.hatenablog.com/entry/2015/09/21/170800jumpaku.hatenablog.com

作業 Works

  1. JavaFXJREを含んだ新規プロジェクトを作成する
    Create new project which contains JavaFX JRE.
  2. WebBrowserクラスを作成し以下のソースコードを記述する
    Create WebBrowser class and write source code as follows.
  3. 実行するとgoogleのページが表示される
    Run application and google page is displayed.

ソースコード Source code

package jumpaku.webbrowser;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.web.WebView;

public class WebBrowser extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            WebView webView = new WebView();
            webView.getEngine().load("https://www.google.co.jp/");
            Scene scene = new Scene(webView);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String... args) {
        Application.launch(WebBrowser.class, args);
    }
}

解説 Explanation

JavaFXのアプリケーションはApplicationクラスを継承して作成します. 今回はApplicationクラスを継承してWebBrowserクラスを作成しました.

Extending Application class, JavaFX application is written. I made WebBrowser class extending Application class.

Applicationクラスの継承

Applicationクラスには主に次の4つメソッドがあります.

  1. launch アプリケーションの起動
  2. init 初期化処理
  3. start エントリポイント
  4. stop 終了処理

launchメソッドを呼び出すとアプリケーションが起動します. launchメソッドは1度だけ呼び出す事ができ, 第一引数は次の様にApplicationクラスを継承したクラスでなければいけません.

Application.launch(Class<? extends Application> appClass, String... args);

また次の様に引数を1つだけにする事も出来ますがその場合Applicationのサブクラスのメソッド内でしか呼び出せません.

Application.launch(String... args);

アプリケーションが起動されるとまずinitメソッドが呼び出されます. initメソッドをオーバーライドする事で初期化処理を実装する事ができます.

次にstartメソッドが呼び出されます. startメソッドはエントリポイントであり, initメソッドの後に開始準備が整ったら呼び出さます.

Platform.exitメソッドを呼び出すかウィンドウが閉じられるとアプリケーションが終了します. この時にstopメソッドが呼び出されます. stopメソッドをオーバーライドする事で終了処理を実装する事ができます. System.exitメソッドでもアプリケーションを終了する事ができますがその場合stopメソッドは呼び出されません. initメソッドとstopメソッドはオーバーライドしない場合は何もしません.

WebBrowserクラスの解説

Applicationクラスを継承する時はstartメソッドをオーバーライドする必要があります. 今回のWebBrowserクラスではstartメソッドでGUI部品の組み立てを行っています. startメソッドに渡されたprimaryStageはプラットフォームによって生成されたものです. StageクラスはGUI部品の配置の土台となるクラスで, ウィンドウの管理をします.

まずWebViewというGUI部品を生成してgoogleのページをロードしました. WebViewクラスはウェブエンジンを管理しその内容を表示します. 次にこのWebViewオブジェクトをSceneオブジェクトに保持させます. Sceneクラスは全てのGUI部品を保持するクラスで, シーングラフというGUI部品同士の構造を管理します. そしてこのSceneオブジェクトをprimaryStageにセットします. Stageオブジェクトのshowメソッドを呼び出す事でウィンドウを表示します.

mainメソッド内ではlaunchメソッドを呼び出してアプリケーションを起動しています.

Extend Application class

Application class has important 4 methods.

  1. launch - Run application
  2. init - Initialize application
  3. start - Entry point
  4. stop - Finalize application

When launch method is called, the application runs. You can call launch method only once. First argument must be extending Application class as follows.

Application.launch(Class<? extends Application> appClass, String... args);

You can call this method with one argument as follows. Then, launch method must be called from method of a sub class extending Application class.

Application.launch(String... args);

When you run an application, first, init method is called. You can implement initialization overriding init method.

After init method, if application is ready, start method is called. It is the entry point.

When Platform.exit is called or the last window is closed, application is ended. At that time, stop method is called. You can implement finalization overriding stop method. You can end application using System.exit but stop is not called. Without overriding, init method and stop method do nothing.

Implement WebBrowser class

When you extend Application class, you must override start method. start method of WebBrowser class constructs GUI parts. Given primaryStage in start method is created by platform. Stage class is a foundation of arrangement of GUI parts and manages window.

First, I generated a WebView object which is a GUI parts and load google page. WebView class manages a web engine and displays contents of that. Next, creating Scene object, I set WebView object to that. Scene class contains GUI parts manages scene graph which is structure of GUI parts. Then, I set Scene object to primaryState. After that, I displayed a window calling primaryStage.show

In main method, calling launch, I run the application.

まとめ Summary

  • startメソッドをオーバーライドしてApplicationクラスを継承
    Override start method to extend Application class.
  • Aplication.launchで起動
    Call Aplication.launch method to launch the application.
  • Stageクラスはウィンドウの土台
    Stage class is foundation of window.
  • Sceneクラスはシーングラフの親玉
    Scene class is boss of scene graph.
  • WebViewは便利
    WebView class is convenient.

次回 Next

もう少し立派なWebブラウザを作ります. Develop more useful web browser.

jumpaku.hatenablog.com

学年割り電卓 GakunenWari Calculator

旧学年割り電卓は新たに学年割り電卓2になりました.

Old GakunenWari Calculator is updated to GakunenWari Calculator 2.

https://jumpaku.github.io/GakunenWari/

以下の旧学年割り電卓は現在公開されていません. The following GakunenWari Calculator is stopped.

学年割りとは?

割り勘とは合計金額を参加者数で割って1人当たりの支払額を決める方法です.支払額は次の式で表す事ができます.

1人当たりの支払額 = 合計金額 / 参加者数

これに対し, 学年割りとは学年によって1人当たりの支払額を変える支払額決定法です.この場合の支払額は次の式で表す事ができます.

i年生1人当たりの支払額 = 重みi x 1人当たりの基本支払額

多くの場合, 学年割りでは学年が高い程, 支払額が多くなります.
そして学年割り計算は少し計算が大変です.

使い方

私が作った学年割り電卓はWebアプリなのでインストールせずにスマートフォンで使用する事ができます.
使用手順は以下の通りです.

  1. ブラウザで次のページにアクセスする https://jumpaku.github.io/GakunenWari/
  2. 各欄に合計金額, 学年間金額差, そして各学年の参加者数を入力する
  3. "学年割り"ボタンを押す

これで各学年で参加者1人当たりの支払額が計算されます.

補足

What's Gakunen-Wari?

Warikan(割り勘) means "Split the bill".
For example, college students who belong to a club go to restaurant together, and they split the bill if they are the same grade.
The entire bill is split (divided evenly) between all participants. It is represented by the following formula.

Payment amount of a participant = Total amount / Number of participants

However, if their grade are different, the payment amount of a participant is often changed by his/her grade.
It is represented by the following formula.

Payment amount of a i-th grader = weight_i x basic amount of a participant

Usually, the higher the grade of a participant is, the more his/her amount increase.
Japanese call this splitting Gakunen-Wari(学年割り).
Gakunen(学年) means "school grade".
Gakunen-Wari calculation is little complex.

How to use

You can use GakunenWari on your smart phone browser without installation because it is a web application.
The following is how to use GakunenWari.

  1. Access here. https://jumpaku.github.io/GakunenWari/
  2. Input total amount into "合計金額", difference of amount per grade into "学年間金額差", number of participants into each blank.
  3. Press the button "学年割り".

You can get the result of calculation.

Note

ガベこれ GabeColle

f:id:Jumpaku:20180226132331p:plain f:id:Jumpaku:20180226132307p:plain f:id:Jumpaku:20180226132313p:plain f:id:Jumpaku:20180226132318p:plain

Introduction

ガベこれとは私のチームで開発したゲームです. このゲームはガベージコレクションを題材にしています. ガベージコレクションとはプログラミングでメモリの管理を自動的に行う仕組みです. このゲームはガベージコレクションを画面上に生成される円をクリックして消す行為で表現しました.
今回のリリースは学校祭出品用なのでQuitボタンとTwitter機能が無効になっています.

Rule

Game1, Game2, Game3の各ゲーム画面によって細かいルールは異なります. しかし基本は以下の通りです.

  1. 画面上に円形のオブジェクトが生成される(alloc)
  2. プレイヤは不必要なオブジェクトを破棄する(free)
  3. 不必要なオブジェクトとはROOTから矢印を辿って到達できないものである

Source code

ここを見るhttps://github.com/GabeColle/GabeColle

How to play

  1. ここからダウンロードGabeColle.zip - Google ドライブ
  2. GabeColle.zipを展開
  3. GabeColle.exeを実行

サイズが約54MBと大きいです.

New version

学校祭展示用だったGabeColle 1 を一般公開の為にに少し変更して, GabeColle 2 としました.

Changes

  • 全画面モードをウィンドウモードに変更
  • Quitボタンを有効化
  • Twitter機能を有効化

Introduction

GabeColle is a game developed by our team. The motif of this game is Garbage Collection. Garbage Collection is a form of automatic memory management. You click circles on the screen and erase them. This is simulation of Garbage Collection.
This release is for college festival. Therefore Quit button and Twitter button is disabled.

Rule

There are some difference of detail rule between 3 game scenes, Game1, Game2, and Game3, however, basic rule is same. Basic rule is as follows.

  1. Circle objects are constructed on your screen.(alloc)
  2. You click and destruct them if they are no use objects.(free)
  3. If you cannot arrive to a object from ROOT passing through some allows, the object is no use object.

Source code

  1. See herehttps://github.com/GabeColle/GabeColle

Download

  1. Download from GabeColle.zip - Google ドライブ.
  2. Extract GabeColle.zip
  3. Execute GabeColle.exe

This file size is 54MB, it is large.

Version 2

GabeColle 1 was for college festival. To release for public, we made little changes.

Changes

StreetRunner

Street Runner

f:id:Jumpaku:20170328161310p:plain f:id:Jumpaku:20170328161336p:plain

ゲーム情報

  • タイトル : StreetRunner
  • 作者 :
  • ジャンル : 対戦
  • プレイ時間 : 10分程度
  • プラットフォーム : Windows
  • 言語 : 日本語
  • 利用ライブラリ : Siv3D

Information

  • Title : StreetRunner
  • Developer :
  • Genle: Fight
  • Playtime : 10m
  • Platform : Windows
  • language : Japanese
  • Library : Siv3D

What’s this?

Street Runnerは2人用の対戦ゲームです.

How to start

  1. ここからダウンロードします https://github.com/StreatRunner/StreetRunner
  2. Game/StreetRunner.exeを実行します

How to play

  • プレイヤ2人は画面の前で左右に座ります
  • 自分のキャラクタが先にゴールへ到達したプレイヤが勝者となります
  • 使用するボタンは左のプレイヤはW,A,S,D,右のプレイヤは↑,←,↓,→で,使い方は次の通りです
    • W(↑) ジャンプ
    • A(←) 左へ移動
    • S(↓) アタック
    • D(→) 右へ移動
  • 次の場合は相手はスタート位置まで戻ります
    • 自分の攻撃が相手に当たる
    • 相手とすれ違う時に自分の方が高い位置にいる

What’s this

Street Runner is a computer battle game for 2 players.

How to start

  1. Download from https://github.com/StreatRunner/StreetRunner
  2. Execute Game/StreetRunner.exe

How to play

  • 2 players sit in front of screen side by side.
  • If you goal before your opponent does, you are winner.
  • Left player uses W,A,S,and D. Right player uses ↑,←,↓,and →.
    • W(↑) Jump
    • A(←) Go left
    • S(↓) Attack
    • D(→) Go right
  • Your opponent returns if
    • Your attack collides your opponent
    • you are higher than your opponent as 2 players pass each other