JavaFX在拖放过程中获取鼠标事件

时间:2016-02-07 03:17:37

标签: java javafx drag-and-drop

我在我的应用程序中添加了一些拖放行为,用户可以将DnD填充到具有自定义逻辑和渲染代码的画布上。我需要获取鼠标相对于画布的位置(即0,0左上角),但DragEvent不允许我这样做,并且在DnD期间鼠标事件不会传递到画布。 / p>

是否可以在拖放过程中允许鼠标事件传递?

1 个答案:

答案 0 :(得分:1)

您可以在dragOver处理程序中执行此操作,该处理程序在鼠标在拖动期间注册处理程序的节点上移动时调用。

简单示例:

import java.util.stream.Stream;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class DragToCanvas extends Application {

    private Color draggingColor ;

    @Override
    public void start(Stage primaryStage) {
        Pane dragFromPane = new Pane();
        Canvas canvas = new Canvas(600, 600);
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.setFill(Color.ANTIQUEWHITE);
        gc.fillRect(0, 0, 600, 600);

        Label coordinateLabel = new Label("[ ]");
        coordinateLabel.setStyle("-fx-font-size: 24;");

        Color[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.BLACK} ;
        for (int i = 0;  i < colors.length; i++) {
            drawCircle(colors[i], dragFromPane, i);
        }

        canvas.setOnDragOver(e -> {
            if (draggingColor != null 
                    && e.getDragboard().hasString() 
                    && e.getDragboard().getString().equals("circle")) {
                e.acceptTransferModes(TransferMode.COPY);
            }
            coordinateLabel.setText(String.format("[%.1f, %.1f]", e.getX(), e.getY()));
        });

        canvas.setOnDragDropped(e -> {
            if (e.getDragboard().hasString() 
                    && e.getDragboard().getString().equals("circle")) {
                gc.setFill(draggingColor);
                gc.fillOval(e.getX()-25, e.getY()-25, 50, 50);
                draggingColor = null ;
                e.setDropCompleted(true);
            }
        });

        BorderPane root = new BorderPane();
        root.setCenter(canvas);
        root.setLeft(dragFromPane);
        root.setBottom(coordinateLabel);
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void drawCircle(Color c, Pane dragFromPane, int index) {
        Circle circle = new Circle(60, 60*(index+1), 25);
        circle.setFill(c);
        dragFromPane.getChildren().add(circle);
        circle.setOnDragDetected(e -> {
            Dragboard db = circle.startDragAndDrop(TransferMode.COPY);
            db.setDragView(circle.snapshot(null, null));
            ClipboardContent cc = new ClipboardContent();
            cc.putString("circle");
            db.setContent(cc);
            draggingColor = c ;
        });

    }

    public static void main(String[] args) {
        launch(args);
    }
}