how to make a Draggable Node in Javafx 2.0.


Question

how to make a Draggable Node in Javafx 2.0. The JavaFX is specially for GUI purpose only I need some sample thanks

1
3
6/26/2013 6:41:11 AM

Oracle provide a tutorial on draggable nodes.

Here is the makeDraggable method from the tutorial:

private Node makeDraggable(final Node node) {
final DragContext dragContext = new DragContext();
final Group wrapGroup = new Group(node);

wrapGroup.addEventFilter(
    MouseEvent.ANY,
    new EventHandler<MouseEvent>() {
        public void handle(final MouseEvent mouseEvent) {
            if (dragModeActiveProperty.get()) {
                // disable mouse events for all children
                mouseEvent.consume();
            }
         }
    });

wrapGroup.addEventFilter(
    MouseEvent.MOUSE_PRESSED,
    new EventHandler<MouseEvent>() {
        public void handle(final MouseEvent mouseEvent) {
            if (dragModeActiveProperty.get()) {
                // remember initial mouse cursor coordinates
                // and node position
                dragContext.mouseAnchorX = mouseEvent.getX();
                dragContext.mouseAnchorY = mouseEvent.getY();
                dragContext.initialTranslateX =
                    node.getTranslateX();
                dragContext.initialTranslateY =
                    node.getTranslateY();
            }
        }
    });

wrapGroup.addEventFilter(
    MouseEvent.MOUSE_DRAGGED,
    new EventHandler<MouseEvent>() {
        public void handle(final MouseEvent mouseEvent) {
            if (dragModeActiveProperty.get()) {
                // shift node from its initial position by delta
                // calculated from mouse cursor movement
                node.setTranslateX(
                    dragContext.initialTranslateX
                        + mouseEvent.getX()
                        - dragContext.mouseAnchorX);
                node.setTranslateY(
                    dragContext.initialTranslateY
                        + mouseEvent.getY()
                        - dragContext.mouseAnchorY);
            }
        }
    });

return wrapGroup;

}

Sometimes you don't need the filters and drag context and can just do something simpler by acting on various mouse events like in this example:

static class Delta { double x, y; }
// make a node movable by dragging it around with the mouse.
private void enableDrag(final Circle circle) {
final Delta dragDelta = new Delta();
circle.setOnMousePressed(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    // record a delta distance for the drag and drop operation.
    dragDelta.x = circle.getCenterX() - mouseEvent.getX();
    dragDelta.y = circle.getCenterY() - mouseEvent.getY();
    circle.getScene().setCursor(Cursor.MOVE);
  }
});
circle.setOnMouseReleased(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    circle.getScene().setCursor(Cursor.HAND);
  }
});
circle.setOnMouseDragged(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    circle.setCenterX(mouseEvent.getX() + dragDelta.x);
    circle.setCenterY(mouseEvent.getY() + dragDelta.y);
  }
});
circle.setOnMouseEntered(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    if (!mouseEvent.isPrimaryButtonDown()) {
      circle.getScene().setCursor(Cursor.HAND);
    }
  }
});
circle.setOnMouseExited(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    if (!mouseEvent.isPrimaryButtonDown()) {
      circle.getScene().setCursor(Cursor.DEFAULT);
    }
  }
});
}

The same technique for dragging nodes around can also be used to drag around stages:

static class Delta { double x, y; }
/** makes a stage draggable using a given node */
public static void makeDraggable(final Stage stage, final Node byNode) {
final Delta dragDelta = new Delta();
byNode.setOnMousePressed(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    // record a delta distance for the drag and drop operation.
    dragDelta.x = stage.getX() - mouseEvent.getScreenX();
    dragDelta.y = stage.getY() - mouseEvent.getScreenY();
    byNode.setCursor(Cursor.MOVE);
  }
});
byNode.setOnMouseReleased(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    byNode.setCursor(Cursor.HAND);
  }
});
byNode.setOnMouseDragged(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    stage.setX(mouseEvent.getScreenX() + dragDelta.x);
    stage.setY(mouseEvent.getScreenY() + dragDelta.y);
  }
});
byNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    if (!mouseEvent.isPrimaryButtonDown()) {
      byNode.setCursor(Cursor.HAND);
    }
  }
});
byNode.setOnMouseExited(new EventHandler<MouseEvent>() {
  @Override public void handle(MouseEvent mouseEvent) {
    if (!mouseEvent.isPrimaryButtonDown()) {
      byNode.setCursor(Cursor.DEFAULT);
    }
  }
});
}

Sample for dragging around a parent node (that contains multiple child nodes). This example is more generic then the circle based example from above as it does not rely on centerX/Y properties which most nodes don't have, instead it works on layoutX/Y which are available to all nodes placed in a parent Group or Pane.

import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.scene.text.TextBoundsType;
import javafx.stage.Stage;

public class TextOnCircleWithDragging extends Application {
    private static final int W = 400;
    private static final int H = 400;
    private static final int R = 15;

    @Override
    public void start(Stage stage) {
        final StackPane circleWithText = new StackPane(
                createCircle(),
                createText()
        );
        circleWithText.relocate(
                W/2 - R/2,
                H/2 - R/2
        );

        makeDraggable(circleWithText);

        stage.setScene(
                new Scene(
                        new Pane(circleWithText),
                        W, H
                )
        );
        stage.show();
    }

    private Circle createCircle() {
        final Circle circle = new Circle(R);
        circle.setFill(Color.PALEGREEN);
        circle.relocate(0, 0);

        return circle;
    }

    private Text createText() {
        final Text text = new Text("A");
        text.setBoundsType(TextBoundsType.VISUAL);

        return text;
    }

    private void makeDraggable(Node node) {
        final Delta dragDelta = new Delta();

        node.setOnMouseEntered(me -> {
            if (!me.isPrimaryButtonDown()) {
                node.getScene().setCursor(Cursor.HAND);
            }
        });
        node.setOnMouseExited(me -> {
            if (!me.isPrimaryButtonDown()) {
                node.getScene().setCursor(Cursor.DEFAULT);
            }
        });
        node.setOnMousePressed(me -> {
            if (me.isPrimaryButtonDown()) {
                node.getScene().setCursor(Cursor.DEFAULT);
            }
            dragDelta.x = me.getX();
            dragDelta.y = me.getY();
            node.getScene().setCursor(Cursor.MOVE);
        });
        node.setOnMouseReleased(me -> {
            if (!me.isPrimaryButtonDown()) {
                node.getScene().setCursor(Cursor.DEFAULT);
            }
        });
        node.setOnMouseDragged(me -> {
            node.setLayoutX(node.getLayoutX() + me.getX() - dragDelta.x);
            node.setLayoutY(node.getLayoutY() + me.getY() - dragDelta.y);
        });
    }

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

    private class Delta {
        public double x;
        public double y;
    }
}

Lag Adjustment

If you are seeing the dragged node lag behind the cursor and wish to address that, then see Xanatos's answer to:

Where he suggests you may wish to set:

-Dprism.vsync=false

To workaround issue https://bugs.openjdk.java.net/browse/JDK-8087922.

13
5/23/2017 12:10:35 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon