前回カスタムカーソルを作ったことの続き。
せっかくカーソルを変えたので、よくあるカーソルを追いかけるイメージというのを JavaFX でも作ってみようと思います。
ここではマウスが移動するイベントを拾って、その都度シーケンスに挿入して、古いものは捨てるということをやっています。
ようするにシーケンスの先頭は現在のマウスの位置、次が 1 つ前のイベントの時のマウスの位置、次が 2 つ前のイベント時のマウスの位置、というようになっています。
で、そのシーケンスをイメージの位置と同期 (つまり bind です) させてしまうというものです。
後は領域から出た時にイメージを非表示にして、領域に再び入ったら表示して、かつ位置も初期化するということをやってます。
完成品が右のイメージ。一番大きい Duke がマウスカーソルです。
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.Cursor;
import javafx.input.MouseEvent;
import javafx.scene.geometry.Rectangle;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import java.lang.System;
import java.net.URL;
import javafx.scene.image.Image;
var cursor: Cursor = Cursor {
awtType: java.awt.Cursor.CUSTOM_CURSOR
awtCursor: {
var toolkit:Toolkit = Toolkit.getDefaultToolkit();
var image: java.awt.Image
= toolkit.getImage(new URL("{__DIR__}duke0.gif"));
toolkit.createCustomCursor(image, new Point(8, 0), "MAGNIFIER");
}
};
// とりあえず、見えそうもない場所に設定
var previousX: Number[] = [-10000, -10000, -10000, -10000, -10000];
var previousY: Number[] = [-10000, -10000, -10000, -10000, -10000];
// それぞれのイメージの位置は (previousX[i], previousY[i]) に bind
// previousX[0], previousY[0] は現在の位置なので使用しない
var images: ImageView[] = [
ImageView {
x: bind previousX[4]
y: bind previousY[4]
image: Image {
url: "{__DIR__}duke4.gif"
},
},
ImageView {
x: bind previousX[3]
y: bind previousY[3]
image: Image {
url: "{__DIR__}duke3.gif"
},
},
ImageView {
x: bind previousX[2]
y: bind previousY[2]
image: Image {
url: "{__DIR__}duke2.gif"
},
},
ImageView {
x: bind previousX[1]
y: bind previousY[1]
image: Image {
url: "{__DIR__}duke1.gif"
},
},
];
Frame {
title: "CursorSample"
width: 200
height: 200
closeAction: function() {
java.lang.System.exit( 0 );
}
visible: true
stage: Stage {
content: [
Rectangle {
cursor: cursor
x: 10, y: 10
width: 160, height: 140
fill: Color.AQUAMARINE
onMouseMoved: function(event: MouseEvent) {
// x 座標をシーケンスの先頭に追加
// 最後を削除する
var x = event.getX();
insert x before previousX[0];
delete previousX[5];
// y 座標も同じ
var y = event.getY();
insert y before previousY[0];
delete previousY[5];
}
onMouseExited: function(event: MouseEvent) {
// マウスカーソルが領域から出たら、イメージを非表示にする
for (images in images) {
images.visible = false;
}
}
onMouseEntered: function(event: MouseEvent) {
// マウスカーソルが領域に入ったら、イメージを表示する
for (images in images) {
images.visible = true;
}
// 領域に入った場所でシーケンスを初期化
var x = event.getX();
previousX = [x, x, x, x];
var y = event.getY();
previousY = [y, y, y, y];
}
},
images
]
}
}
