Evald
Evald

Reputation: 122

Path dragging in javafx

im trying to create an event for path dragging in javafx, however, using setLayoutX/Y will drop the Path element below the cursos at mouse pressed but will have a smooth dragging on mouse dragged. I am using setTranslateX/Y method and it does not drop Path below the cursos, however dragging is not smooth and makes Path node jump backwards and forward on dragging. Path is created as a freedraw object.

I create a Path using this code:

EventHandler<MouseEvent> mouseEventHandler = new EventHandler<MouseEvent>() {
@Override
public void handle (MouseEvent e) {
    if (i == 0) {
    if (e.getEventType() == MouseEvent.MOUSE_PRESSED) {
        j = 1;
        path = new Path();
        path.setStroke(color);
        path.setStrokeWidth(10);
        root.getChildren().add(path);
        path.getElements().add(new MoveTo(e.getX(), e.getY()));
    }
    if (e.getEventType() == MouseEvent.MOUSE_DRAGGED) {
        if (j == 1) {
        path.getElements().add(new LineTo(e.getX(), e.getY()));
        }
    }
    if (e.getEventType() == MouseEvent.MOUSE_RELEASED) {
        if (j == 1) {
        path.getElements().add(new LineTo(e.getX(), e.getY()));
        path.setOnMouseEntered(new PathEventHandler(paths.size()));
        path.setOnMouseExited(new PathEventHandler(paths.size()));
        path.setOnMousePressed(new PathEventHandler(paths.size()));
        path.setOnMouseDragged(new PathEventHandler(paths.size()));
        path.setOnMouseReleased(new PathEventHandler(paths.size()));
        path.setOnMouseClicked(new PathEventHandler(paths.size()));
        paths.add(path);
        cachePath.add(path);
        cacheType.add("Create");
        j = 0;
        }
    }
}

For dragging created Path from paths list i use this code:

class PathEventHandler implements EventHandler<MouseEvent>{
//element number in paths
public int n;
public PathEventHandler(int n){
    this.n=n;
}
@Override
public void handle(MouseEvent me) {
    if (me.getEventType() == MouseEvent.MOUSE_ENTERED) {
        paths.get(n).setEffect(new DropShadow(20, Color.BLACK));
    }
    if (me.getEventType() == MouseEvent.MOUSE_EXITED) {
        paths.get(n).setEffect(null);
    }
    if (i == 2) {
    if (me.getEventType() == MouseEvent.MOUSE_PRESSED) {
        x = me.getX();
        y = me.getY();
    } 
    if (me.getEventType() == MouseEvent.MOUSE_DRAGGED) {
        paths.get(n).setTranslateX(me.getX() - x + paths.get(n).getTranslateX());
        paths.get(n).setTranslateY(me.getY() - y + paths.get(n).getTranslateY()); 
        /*paths.get(n).setTranslateX(me.getX());
        paths.get(n).setTranslateY(me.getY()); */
        listX.add(paths.get(n).getTranslateX());
        listY.add(paths.get(n).getTranslateY());
        x = me.getX();
        y = me.getY();
    }
    if (me.getEventType() == MouseEvent.MOUSE_RELEASED) {
        cachePath.add(paths.get(n));
        cacheType.add("Relocate");
    }
    if (me.getEventType() == MouseEvent.MOUSE_CLICKED) {
        if (me.getButton() == MouseButton.SECONDARY) {
        root.getChildren().remove(paths.get(n));
        cachePath.add(paths.get(n));
        cacheType.add("Remove");
        }
    }
    }
}

Upvotes: 1

Views: 910

Answers (1)

Lalith J.
Lalith J.

Reputation: 1391

You have to add the Path to a Group and then you can Drag Smoothly. I do not know why you are using the path list but that will not required further because we have a Path object warped by a Group Object and you can do changes to the Path object there. If you still need the list for some reason you can collect Group object to a list then use it to garb the Path.

Then take a look at this and made these changes

  if (e.getEventType() == MouseEvent.MOUSE_RELEASED) {
                    if (j == 1) {
                        paths.add(path);
                        root.getChildren().add(new DragablePath(path));
                        cachePath.add(path);
                         cacheType.add("Create");


                    }
                }

Here is the DragablePath class and DragContext class . You can use "DragablePath Event Handlers" as same as you used "Path Event Handlers".

class DragablePath extends Group {

    private final Node node;

    DragablePath(Node node) {
        this.node = node;
        this.getChildren().add(node);
        final DragContext dragContext = new DragContext();
        this.addEventFilter(
                MouseEvent.ANY,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        mouseEvent.consume();

                    }
                });
       this.addEventFilter(
                MouseEvent.MOUSE_ENTERED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        node.setEffect(new DropShadow(20, Color.BLACK));

                    }
                });
        this.addEventFilter(
                MouseEvent.MOUSE_EXITED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        node.setEffect(null);

                    }
                });

        this.addEventFilter(
                MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {
                        dragContext.mouseAnchorX = mouseEvent.getX();
                        dragContext.mouseAnchorY = mouseEvent.getY();
                        dragContext.initialTranslateX = node.getTranslateX();
                        dragContext.initialTranslateY = node.getTranslateY();

                    }
                });
        this.addEventFilter(
                MouseEvent.MOUSE_DRAGGED,
                new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(final MouseEvent mouseEvent) {

                        node.setTranslateX(
                                dragContext.initialTranslateX
                                + mouseEvent.getX()
                                - dragContext.mouseAnchorX);
                        node.setTranslateY(
                                dragContext.initialTranslateY
                                + mouseEvent.getY()
                                - dragContext.mouseAnchorY);

                    }
                });
        this.addEventFilter(
                MouseEvent.MOUSE_RELEASED,
                new EventHandler<MouseEvent>() {

                    @Override
                    public void handle(final MouseEvent mouseEvent) {

                    }
                });

    }
}

private static final class DragContext {

    public double mouseAnchorX;
    public double mouseAnchorY;
    public double initialTranslateX;
    public double initialTranslateY;

}

**Tip: You can enable antialiasing hints by setSmooth(true) of Shape.

Upvotes: 1

Related Questions