Java/JavaFX/非同期処理

Top > Java > JavaFX > 非同期処理

JavaFXのバージョンアップのためJavaFX1.2を使用して記事を作成しています。

javafx1.2にバージョンアップされてクラスが変更になりました。
JavaFX1.1ではAbstractAsyncOperation?を使用していましたが、JavaFX1.2では使用できないのでの代わりに、 新たに追加されたjavafx.async.JavaTaskBase?を使用します。

非同期処理

DBへのアクセスや,計算に時間がかかるロジックなどは非同期で行う方が,パフォーマンスの低下を防ぐことができます。

非同期処理クラス

非同期処理はjavafx.async.JavaTaskBase?を継承したクラスを作成します。

JavaTaskBase?クラスは,非同期で処理する部分をJavaで記述する必要があります。

Java側の処理

Java側ではjavafx.async.RunnableFuture?インターフェースを実装します。

コールバックメソッドがないので、このクラスにDate型result変数を用意し時刻を保持させます。

runメソッドをオーバーライドし、スレッドを一定期間スリープさせ,スリープ後の時間を時間をresultにセットします。

Javaファイルを作成します。

	import java.util.Date;
	import javafx.async.RunnableFuture;

	//javafx.async.RunnableFutur実装
	public class AsyncTaskImpl implements RunnableFuture {

	    private Date result;
	    //コンストラクタで時刻セット
	    public AsyncTaskImpl(Date result) {
	        this.result = result;
	    }

	    public void run() {
	        try {
	            //1秒スリープ
	            Thread.sleep(1000L);
	        } catch (InterruptedException ex) {}
	        //現時刻をセット
	        result.setTime(System.currentTimeMillis());
	    }
	}

AsyncTaskImpl?.javaを作成しました。
AsyncTaskImpl?クラスのコンストラクタの引数であるDateクラスは,AsyncTaskImpl?クラスを生成したときに、生成した時刻をセットします。
runメソッドでは1秒間スリープした後,現在時刻をセットしています。

非同期処理がキャンセルされた場合,ブロックしている処理に対してInterruptedException?例外が発生します。
そのため,InterruptedException?例外を適切にキャッチしてrunメソッドを抜けないと,いつまでたっても処理が終わらいままになってしまいます。

JavaFX側の処理

javafx.async.JavaTaskBase?を継承したクラスを作成します。

	import javafx.async.JavaTaskBase;
	import java.util.Date;

	import async.AsyncTaskImpl;

	//JavaTaskBase継承
	public class AsyncTask extends JavaTaskBase {

	    public-read var result = new Date();
	    var task: AsyncTaskImpl;

	    //RunnableFuture を実装したクラスのインスタンスを返す
	    override function create() {
	        task = new AsyncTaskImpl(result);        
	    }
	}

AsyncTask? .fxを作成。

JavaTaskBase?を継承したこのクラスはDate型の変数resultと、AsyncTaskImpl?型の変数taskを用意ます。

create() で RunnableFuture? の実装クラスAsyncTaskImpl?のインスタンスを生成して変数task返します。

AsyncTask?を使用

AsyncTask?クラスを使用するJavaFXクラスを作成します。

	//結果をもたせる変数
	var result: Date = new Date();
 
	//非同期処理を5秒ごとに行うタイムライン
	Timeline {
	    //無制限に繰り返す
	    repeatCount: Timeline.INDEFINITE
	    //アニメーションを反転
	    autoReverse: true
	    keyFrames: [
	        //0秒時の処理
	        KeyFrame {
	            time: 0s
	            action: function() {                
	                var task: AsyncTask;
	                //非同期処理クラスを生成し、非同期処理を開始する
	                task = AsyncTask {
	                    //非同期処理後にコールされる関数
	                    onDone: function() : Void {
	                        result = task.result;
	                    }
	                }
	                task.start();
	            }
	        },
	        //0.5秒時の処理
	        KeyFrame {
	            time: 0.5s
	        }
	    ]
	}.play(); 
	 

実装している部分を記述しています。

非同期処理はTimelineクラスを使用して0.5秒ごとに行うことにしました。
変数repeatCount、変数autoReverseを使用して永遠に繰り返すように設定しています。

JavaTaskBase?クラスを継承したAsyncTask? クラスは、生成するだけで自動的にrun関数がコールされます。
非同期処理クラスを使用するスクリプトが非同期処理が終わった後に、コールバック関数を設定したい場合,変数onDoneに代入される関数に記述します。
ここでは、スリープの後に時刻が代入されています。

下記にAsyncTask?クラスを使用したスクリプトを記述します。

	import javafx.animation.KeyFrame;
	import javafx.animation.Timeline;
	import javafx.scene.Scene;
	import javafx.scene.paint.Color;
	import javafx.scene.paint.RadialGradient;
	import javafx.scene.paint.Stop;
	import javafx.scene.shape.Circle;
	import javafx.scene.text.Font;
	import javafx.scene.text.Text;
	import javafx.stage.Stage;
	import java.util.Date;

	//結果をもたせる変数
	var result: Date = new Date();

	//非同期処理を5秒ごとに行うタイムライン
	Timeline {
	    //無制限に繰り返す
	    repeatCount: Timeline.INDEFINITE
	    //アニメーションを反転
	    autoReverse: true
	    keyFrames: [
	        //0秒時の処理
	        KeyFrame {
	            time: 0s
	            action: function() {                
	                var task: AsyncTask;
	                //非同期処理クラスを生成し、非同期処理を開始する
	                task = AsyncTask {
	                    //非同期処理後にコールされる関数
	                    onDone: function() : Void {
	                        result = task.result;
	                    }
	                }
	                task.start();
	            }
	        },
	        //5秒時の処理
	        KeyFrame {
	            time: 0.5s
	        }
	    ]
	}.play();

	//ボールを定義
	var circle = Circle {
	    //位置
	    centerX: 0
	    centerY: 0
	    //大きさ
	    radius: 20
	    //ボールの色
	    fill: RadialGradient {
	        //色の中心
	        centerX: 0.3
	        centerY: 0.3
	        //色の割合
	        stops: [
	            Stop {
	                offset: 0.0
	                color: Color.WHITE
	            },
	            Stop {
	                offset: 0.5
	                color: Color.BLUE
	            }
	        ]
	    }
	}

	//ボール水平のアニメーション
	Timeline {
	    //無制限繰り返す
	    repeatCount: Timeline.INDEFINITE
	    //アニメーション
	    autoReverse: true
	    keyFrames: [
	        KeyFrame {
	            time: 0s
	            //座標移動
	            values: circle.translateX => 20.0
	        },
	        KeyFrame {
	            time: 5s
	            //座標移動
	            values: circle.translateX => 280.0
	        },
	    ]
	//スタート
	}.play();

	//ボール垂直アニメーション
	Timeline {
	    //無制限繰り返す
	    repeatCount: Timeline.INDEFINITE
	    //アニメーション反転
	    autoReverse: true
	    keyFrames: [
	        KeyFrame {
	            time: 0s
	            //座標移動
	            values: circle.translateY => 20.0
	        },
	        KeyFrame {
	            time: 1.2s
	            //座標移動
	            values: circle.translateY => 180.0
	        },
	    ]
	//スタート
	}.play();

	Stage {
	    title: "async_sample"
	    scene: Scene {
	        width: 300
	        height: 200
	        content: [
	            circle,
	            Text {
	                font : Font {
	                    size: 20
	                }
	                fill:Color.RED,
	                x: 10,
	                y: 200
	                content: bind "{result}"
	            }
	        ]
	    }
	}

これを、実行するとアニメーションと、時刻が表示されます。
スレッドをスリープさせても、アニメーションは止まることなく、動いているのが確認できます。

AsyncTask.JPG

JavaFX1.2での実行です。


アクセス総数6457件

最終更新日: 2009-09-03 (木) 22:38:06 (2998d)

このページをブックマーク:

このページのURL(コピペして利用下さい):

TOP