JavaFXドラッグアンドドロップ
JavaFXを用い、マウスでドラッグアンドドロップを実行するサンプルプログラムの紹介です。
2枚のPaneを並べ、Circleをマウスを使って隣のPaneへ移動させています。見た目は移動しているだけですが、
隣のPaneの上に移動すると、そのPaneにCircleをaddしています。
準備
まずはPaneを2枚用意して並べます。
pane[0] = new Pane();
pane[1] = new Pane();
pane[0].setBackground(new Background(new BackgroundFill( Color.LIGHTBLUE , CornerRadii.EMPTY , new Insets(5))));
pane[1].setBackground(new Background(new BackgroundFill( Color.LAWNGREEN , CornerRadii.EMPTY , new Insets(5))));
for(int i=0;i<pane.length;i++){ pane[i].setPrefSize(150, 150); }
fpane.getChildren().addAll( pane );
Pane間にすきまがあるように見えますが、Insets(5)を採っているので実際には空いていません。
次にCircle。1つでよいのですが、寂しいので2つ用意しました。
circle[0] = new Circle(0,0,10);
circle[1] = new Circle(0,0,10);
circle[0].setFill(Color.GREEN);
circle[1].setFill(Color.RED);
circle[0].setTranslateX(100);
circle[0].setTranslateY(75);
circle[1].setTranslateX(50);
circle[1].setTranslateY(75);
pane[0].getChildren().addAll( circle );
イベントの準備
Pane、Circleそれぞれにイベントを設定します。
private void setEvent(){
//Paneにイベントを設定
EventHandler<MouseDragEvent> mouseDrag = ( event ) -> this.mouseDrag( event );
for(int i=0;i<pane.length;i++){
pane[i].addEventHandler( MouseDragEvent.MOUSE_DRAG_OVER, mouseDrag );
}
//サークルにイベントを設定
EventHandler<MouseDragEvent> mouseReleased = ( event ) -> this.mouseReleased( event );
EventHandler<MouseEvent> mouseDragDetected = ( event ) -> this.mouseDetected( event );
for(int i=0;i<circle.length;i++){
circle[i].addEventHandler( MouseDragEvent.MOUSE_DRAG_RELEASED, mouseReleased );
circle[i].addEventHandler( MouseEvent.DRAG_DETECTED, mouseDragDetected );
}
}
ドラッグされる側、Circleには、
MouseEvent.DRAG_DETECTED マウスドラッグを検知
MouseDragEvent.MOUSE_DRAG_RELEASED マウスドラッグ終了
の2つのイベントを設定します。
ドラッグを受ける側、Paneには、
MouseDragEvent.MOUSE_DRAG_OVER
を設定します。
イベント発生の順序
Circle上でマウスボタンが押し、押したままマウスを動かすと、MouseEvent.DRAG_DETECTEDイベントが発生します。
まず、マウスの形状とCircleの色を変え、押されたCircleをとっておきます。
//アクティブサークルの設定
activecircle = (Circle)event.getSource();
//ドラッグ中の色とマウス形状を変更
activecircle.setBlendMode( BlendMode.OVERLAY);
scene.setCursor( Cursor.CLOSED_HAND);
このイベントの中で下記1文を加えると、以降MouseDragEventが有効になります。
activecircle.startFullDrag();
ことあと、ボタン楽天 を押したままマウスを動かすとCircleののっているPaneでMouseDragEvent.MOUSE_DRAG_OVERイベントが発生します。
このイベントはPaneの範囲外にマウスが出ても発生してしまいます。領域外であれば何もせずに戻るように設定しておきます。
if( p.getLayoutBounds().contains(e.getX(),e.getY()) ==false ){ return; }
マウスが隣のPaneに移ったときは、Circleも隣に移します。
if( p.getChildren().contains(activecircle)==false ){ p.getChildren().add( activecircle ); }
Circleの位置をマウスの位置に一致させ、マウスの動きに追従させます。
activecircle.setTranslateX( e.getX() );
activecircle.setTranslateY( e.getY() );
マウスボタンを離すと、MouseDragEvent.MOUSE_DRAG_RELEASEDイベントが発生して、以降MouseDragEventも無効になります。
Circleの色とマウス形状を元に戻して、ドラッグアンドドロップ終了です。
activecircle.setBlendMode( BlendMode.SRC_OVER);
scene.setCursor( Cursor.DEFAULT);
サンプルプログラム
ページトップの動画のソースコードは以下の通り。
package tomojavalib.swingfx;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.effect.BlendMode;
import javafx.scene.input.MouseDragEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class DragTestFx extends Application {
Pane[] pane = new Pane[2];
Circle[] circle = new Circle[2];
Circle activecircle = null;
Scene scene = null;
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("JavaFX楽天 ");
FlowPane fpane = new FlowPane();
scene = new Scene(fpane, 320, 240);
//Paneを二つ準備する
pane[0] = new Pane();
pane[1] = new Pane();
pane[0].setBackground(new Background(new BackgroundFill( Color.LIGHTBLUE , CornerRadii.EMPTY , new Insets(5))));
pane[1].setBackground(new Background(new BackgroundFill( Color.LAWNGREEN , CornerRadii.EMPTY , new Insets(5))));
for(int i=0;i<pane.length;i++){ pane[i].setPrefSize(150, 150); }
fpane.getChildren().addAll( pane );
circle[0] = new Circle(0,0,10);
circle[1] = new Circle(0,0,10);
circle[0].setFill(Color.GREEN);
circle[1].setFill(Color.RED);
circle[0].setTranslateX(100);
circle[0].setTranslateY(75);
circle[1].setTranslateX(50);
circle[1].setTranslateY(75);
pane[0].getChildren().addAll( circle );
stage.setScene(scene);
this.setEvent();
stage.show();
}
private void setEvent(){
//Paneにイベントを設定
EventHandler<MouseDragEvent> mouseDrag = ( event ) -> this.mouseDrag( event );
for(int i=0;i<pane.length;i++){
pane[i].addEventHandler( MouseDragEvent.MOUSE_DRAG_OVER, mouseDrag );
}
//サークルにイベントを設定
EventHandler<MouseDragEvent> mouseReleased = ( event ) -> this.mouseReleased( event );
EventHandler<MouseEvent> mouseDragDetected = ( event ) -> this.mouseDetected( event );
for(int i=0;i<circle.length;i++){
circle[i].addEventHandler( MouseDragEvent.MOUSE_DRAG_RELEASED, mouseReleased );
circle[i].addEventHandler( MouseEvent.DRAG_DETECTED, mouseDragDetected );
}
}
private void mouseDetected(MouseEvent event) {
System.out.println("drag detected");
//アクティブサークルの設定
activecircle = (Circle)event.getSource();
//ドラッグ中の色とマウス形状を変更
activecircle.setBlendMode( BlendMode.OVERLAY);
scene.setCursor( Cursor.CLOSED_HAND);
//ドラッグ開始
activecircle.startFullDrag();
event.consume();
}
private void mouseReleased( MouseDragEvent event) {
System.out.println("mouse released");
event.consume();
//サークルの色とマウスの形状を元に戻す
activecircle.setBlendMode( BlendMode.SRC_OVER);
scene.setCursor( Cursor.DEFAULT);
}
private void mouseDrag( MouseEvent e){
Pane p = (Pane)e.getSource();
//マウスがパネル領域内に無ければリターン
if( p.getLayoutBounds().contains(e.getX(),e.getY()) ==false ){ return; }
e.consume();
String s = p.toString();
System.out.println( "マウスドラッグ:"+s +" "+ e.getX() +" "+ e.getY() );
//Pane内にサークルが無ければ追加する
if( p.getChildren().contains(activecircle)==false ){ p.getChildren().add( activecircle ); }
//サークルの位置を変更
activecircle.setTranslateX( e.getX() );
activecircle.setTranslateY( e.getY() );
}
}
最終更新日: 2018-12-04 08:32:23