JavaFX Dragged Element正在翻转

时间:2016-05-19 09:46:30

标签: javafx draggable pane

我尝试轻松拖动窗格设置。我的结果很有趣。 在Node内拖动Pane会产生跳跃效应吗? 拖动点跳转到给定位置,然后拖动回到最后一个位置。

任何帮助?

import java.util.concurrent.atomic.AtomicReference;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.PickResult;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class DrawPolygon extends Application {

    Group g ;
    PickResult pickResult;
    Node intersectedNode;
    final AtomicReference<MouseEvent> deltaEvent = new AtomicReference<MouseEvent>();


    @Override
    public void start(Stage stage) {

        Group root = new Group();
        Scene scene = new Scene(root, 600, 800);
        stage.setScene(scene);
          g = new Group();

        Rectangle blue = new Rectangle();
        blue.setFill(Color.BLUE);
        blue.setWidth(25);
        blue.setHeight(25);

        blue.setX(50);
        blue.setY(50);

        Rectangle red = new Rectangle();
        red.setFill(Color.RED);
        red.setWidth(25);
        red.setHeight(25);

        red.setX(150);
        red.setY(150);

        Rectangle yellow = new Rectangle();
        yellow.setFill(Color.YELLOW);
        yellow.setWidth(25);
        yellow.setHeight(25);

        yellow.setX(250);
        yellow.setY(250);


        blue.addEventFilter(MouseEvent.MOUSE_CLICKED, onMouseClickedEventHandler);
        red.addEventFilter(MouseEvent.MOUSE_CLICKED, onMouseClickedEventHandler);
        yellow.addEventFilter(MouseEvent.MOUSE_CLICKED, onMouseClickedEventHandler);

        blue.addEventFilter(MouseEvent.MOUSE_PRESSED, onMousePressedEventHandler);
        red.addEventFilter(MouseEvent.MOUSE_PRESSED, onMousePressedEventHandler);
        yellow.addEventFilter(MouseEvent.MOUSE_PRESSED, onMousePressedEventHandler);

        blue.addEventFilter(MouseEvent.MOUSE_DRAGGED, onMouseDraggedEventHandler);
        red.addEventFilter(MouseEvent.MOUSE_DRAGGED, onMouseDraggedEventHandler);
        yellow.addEventFilter(MouseEvent.MOUSE_DRAGGED, onMouseDraggedEventHandler);

        blue.addEventFilter(MouseEvent.MOUSE_RELEASED, onMouseReleasedEventHandler);
        red.addEventFilter(MouseEvent.MOUSE_RELEASED, onMouseReleasedEventHandler);
        yellow.addEventFilter(MouseEvent.MOUSE_RELEASED, onMouseReleasedEventHandler);

        g.getChildren().add(blue);
        g.getChildren().add(red);
        g.getChildren().add(yellow);

        scene.setRoot(g);
        stage.show();

    }

    EventHandler<MouseEvent> onMouseClickedEventHandler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            System.out.print("C");
        }
    };
    EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            System.out.print("P");
            pickResult = event.getPickResult();
            intersectedNode = pickResult.getIntersectedNode();
            deltaEvent.set(event);
        }
    };
    EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            System.out.print("D");
            final double deltaX = event.getX() - deltaEvent.get().getX();
            final double deltaY = event.getY() - deltaEvent.get().getY();           
            intersectedNode.setLayoutX(event.getX() - deltaX);
            intersectedNode.setLayoutY(event.getY() - deltaY);
            deltaEvent.set(event);
            g.layout();


        }
    };
    EventHandler<MouseEvent> onMouseReleasedEventHandler = new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent event) {
            System.out.println("R");
        }
    };

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

1 个答案:

答案 0 :(得分:0)

您正在使用相对于Node s的位置,这会影响计算,除此之外,Node也会被移动:

newLayoutX = event.getX() - deltaX
           = event.getX() - (event.getX() - deltaEvent.get().getX())
           = deltaEvent.get().getX()

这显然是错误的,因为事件坐标位于Node注册的坐标EventHandler中。

解决方案

使用父坐标

附加说明:

  • 使用AtomicReference代替非final字段,您无法获益。
  • 你没有过滤事件,你正在处理它们;因此,应使用addEventHandler代替addEventFilter。此外,您可以使用方便的方法,使您的代码更简单。
  • 您可以将事件处理程序添加到Group,而不是将事件处理程序添加到每个子节点,而不需要“手动”转换坐标。
Group g;
Node intersectedNode;
private Point2D dragStart;
private final Set<Node> draggable = new HashSet<>();

@Override
public void start(Stage stage) {
    g = new Group();
    Scene scene = new Scene(g, 600, 800);
    stage.setScene(scene);

    Rectangle blue = new Rectangle();

    ...

    yellow.setY(250);

    draggable.addAll(Arrays.asList(red, blue, yellow));

    g.getChildren().addAll(blue, red, yellow);

    g.setOnMouseClicked(onMouseClickedEventHandler);
    g.setOnMousePressed(onMousePressedEventHandler);
    g.setOnMouseDragged(onMouseDraggedEventHandler);
    g.setOnMouseReleased(onMouseReleasedEventHandler);

    scene.setRoot(g);
    stage.show();

}

EventHandler<MouseEvent> onMousePressedEventHandler = new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        System.out.print("P");
        PickResult pickResult = event.getPickResult();
        intersectedNode = pickResult.getIntersectedNode();
        System.out.println(intersectedNode);
        if (draggable.contains(intersectedNode)) {
            dragStart = new Point2D(intersectedNode.getLayoutX() - event.getX(), intersectedNode.getLayoutY() - event.getY());
        } else {
            intersectedNode = null;
        }
    }
};
EventHandler<MouseEvent> onMouseDraggedEventHandler = new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent event) {
        System.out.print("D");
        if (intersectedNode != null) {
            intersectedNode.setLayoutX(event.getX() + dragStart.getX());
            intersectedNode.setLayoutY(event.getY() + dragStart.getY());
        }
    }
};