CodeZine(コードジン)

特集ページ一覧

JavaFX 1.0 をいち早く体験してみる

JavaFX 1.0 Previewは0.7に比べてどこが変わったのか?

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/09/08 14:00

目次

FrameとStageによるグラフィック表示

 1.0では、SwingFrameの他に、グラフィック表示を行うFrameクラスを使って表示を行うこともできます。こちらのクラスを使った形に書き直してみましょう。

package fxsample;

import javafx.application.*;
import javafx.scene.geometry.Circle;
import javafx.scene.paint.Color;

Frame {
    title: "Title"
    width: 200
    height: 200
    visible: true
    
    stage: Stage {
        content: Circle {
            centerX: 100, centerY: 80
            radius: 50
            fill: Color.RED
        }
    }
}

 Frameは、javafx.applicationパッケージに用意されています。このクラスには「stage」というアトリビュートがあり、ここにjavafx.application.Stageクラスのインスタンスとして表示する内容を用意します。

 Stageは、Canvasにシェイプを組み込んでグラフィックを作成するのと同じ感覚でグラフィックを用意していくことができます。contentアトリビュートに、シェイプ関係のオブジェクトを配列として用意すれば良いのです。

 SwingのGUIを必要とせず、単にグラフィックだけを表示するのであれば、Frameを使った方がよりシンプルに表示を作成することができるでしょう。ただし、FrameのcontentではSwingコンポーネントは組み込むことができません。

アニメーションについて

 JavaFX Scriptでは、図形などのアトリビュートの値を連続して変更することで、簡易アニメーションを行うことができます。一例として、円をクリックすると、円が小さな点からゆっくりと大きな円に変化していくアニメーションを、0.7のスクリプトで作ってみましょう。

import javafx.ui.*;
import javafx.ui.canvas.*;

class AttrModel {
    attribute radius: Integer;
}

var model = AttrModel {
    radius: 50
};

Frame {
    title:"タイトル"
    width:200
    height:200
    visible:true
    content: Canvas {
        content: [
            Circle {
                cx: 100 cy: 80
                radius: bind model.radius
                fill: red
                onMouseClicked: operation(e){
                    model.radius = [0..50] dur 5000;
                }
            }
        ]
    }
}

 0.7では、クラスのアトリビュートを扱う場合には、モデルクラスを定義してアトリビュートをバインドしました。そして、モデルクラスのアトリビュートの値を操作することで、バインドされたオブジェクトのアトリビュートを変更していたわけです。

 ここでは、CircleのonMouseClickedにoperationを設定し、モデルクラスAttrModelのradiusの値を操作しています。[0..50] dur 5000とすることで、配列の全要素を5000ミリ秒かけて設定していくようにしてあります。これにより、5秒かけてCircleradius(直径)がゼロから50まで変化し、擬似アニメーション表示するわけです。

TimelineとKeyFrameによるアニメーション

 では、1.0では、アニメーションはどのように行うのでしょうか。1.0では、先の「durを使って配列の要素を一定時間内に設定していく」という機能がありません。ではどうするのかと言うと、「Timeline」という、アニメーションのための時間軸の管理をするクラスを利用します。この中に、「KeyFrame」というアニメーションのフレームに相当するクラスを用意し、これを使ってアニメーションを行ってゆくのです。

package fxsample;

import java.lang.System;
import javafx.application.*;
import javafx.scene.geometry.Circle;
import javafx.scene.paint.Color;
import javafx.animation.*;

var radiusNum = 50;

var timeline = Timeline {
    keyFrames : [
        for(i in [0..50]){
            KeyFrame {
                time: 100ms * i
                values: radiusNum => i
            }
        }
    ]
}

Frame {
    title: "Title"
    width: 200
    height: 200
    visible: true
    closeAction: function(){
        System.exit(0);
    }
    stage: Stage {
        content: [
            Circle {
                centerX: 100 centerY: 80
                radius: bind radiusNum
                fill: Color.RED
                onMouseClicked: function(e){
                    timeline.start();
                }
                
            }
        ]
    }
}
図10 赤い円をクリックすると、小さな点から次第に大きくなる。
図10 赤い円をクリックすると、小さな点から次第に大きくなる。

 ここでは、最初にTimelineクラスを用意しています。このクラスには「keyFrames」というアトリビュートが用意されており、ここにキーフレームとなるKeyFrameインスタンスを配列として設定することで、そこに設定したフレーム情報を順に設定してアニメーションを実行していきます。

 ここでは、for(i in [0..50])という繰り返し構文の中で、KeyFrameを用意しています。ちょっと不思議な感じがしますが、配列の[]内にforが置かれていますね。1.0では、こうした書き方も可能です。これにより、配列内に繰り返しを使って多数のKeyFrameインスタンスを設定しているのです。

 KeyFrameには、「time」と「values」というアトリビュートを用意しています。timeは、そのキーフレームが実行される経過時間を示します。ここでは、100ms * iという値が設定されていますね?「100ms」というのは、JavaFX Scriptに新たに加わった値のタイプ「Duration」の値です。Durationは、時間を示す値です。これは数値の後に時間の単位をつけて記述します。ここで使っている「100ms」というのは「100ミリ秒」を示す値です。これにiをかけて、それぞれのキーフレームのtimeを100ミリ秒の倍数で設定していたわけです。

 「values」は、キーフレームで設定される値に関するアトリビュートです。ここでは「radiusNum => i」という値が設定されていますね。これにより、radiusNumiの値が設定されます。valuesでは、この=>を使うことで、それぞれのキーフレームごとに特定の値を設定することができます。

 アニメーションの開始は、CircleonMouseClickedに用意したfunctionで行っています。ここでは、Timelineインスタンスの「start」を呼び出していますね。これで、このTimelineのkeyFrameに用意されたフレームを順に実行していき、アニメーションが行われるというわけです。

 また、ちょっと見落としてしまいがちですが、ここではごく普通の変数にアトリビュートをバインドしていますね。0.7では、ただの変数にバインドすることはできませんでした。わざわざ専用のモデルクラスを定義し、そのアトリビュートにバインドをしていました。が、1.0では、このように変数をバインドに利用することができます。1つ2つの値をバインドするのにいちいちクラスを定義するのは面倒ですから、ちょっとした値の操作ならこの方が簡単で便利です。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 掌田 津耶乃(ショウダ ツヤノ)

    三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。 ※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開中。またGoogle+プロフィールはこちら。

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5