我试图创建一个我创建的可拖动的节点。
我能够将节点放在窗格中我喜欢的位置,但是当它们拖动它们时,它们似乎只是自动输出。
我试过做一个Delta类,它只包含一个x和y,它们会在节点上按下鼠标时相应地更新。
nfaPane.setOnMousePressed(event -> { if (!event.getButton().equals(MouseButton.PRIMARY)) return; for (final NFANode node : nfaNodes) if (node.isHover()) return; final NFANode nfaNode = new NFANode(nfaNodes.size(), event.getX(), event.getY()); nfaPane.getChildren().add(nfaNode); nfaNodes.add(nfaNode); Delta dragDelta = new Delta(); nfaNode.setOnMousePressed(event1 -> { dragDelta.setDragDeltaX(nfaNode.getLayoutX()); dragDelta.setDragDeltaY(nfaNode.getLayoutY()); }); nfaNode.setOnMouseDragged(event1 -> { nfaNode.moveTo(event1.getSceneX() + dragDelta.getDragDeltaX(), event1.getSceneY() + dragDelta.getDragDeltaY()); }); });节点本身由NFANode类定义:
package sample; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Ellipse; import javafx.scene.text.Font; import javafx.scene.text.Text; /** * Created by David on 11/5/2016. */ public class NFANode extends Group { //private List<NFANode> next; public static final Font nfaFont = Font.font("Footlight MT Light", 25); private final Ellipse bubble; private final Text text; private double textWidth; public NFANode(int value, double x, double y) { this.text = new Text(x, y + 5, ""); renumber(value); this.text.setFont(nfaFont); textWidth = this.text.getBoundsInLocal().getWidth(); bubble = new Ellipse(x, y, this.text.getBoundsInLocal().getWidth() + 5, 25); this.text.setX(x - textWidth / 2); bubble.setStroke(Color.BLACK); bubble.setFill(Color.WHITE); getChildren().addAll(bubble, this.text); } public Text getText() { return text; } public void renumber(final int value) { final StringBuilder builder = new StringBuilder(); for (char c : String.valueOf(value).toCharArray()) builder.append((char) (c + 8272)); text.setText("Q" + builder.toString()); } public void moveTo(final double x, final double y) { bubble.setCenterX(x); bubble.setCenterY(y); text.setX(x - textWidth / 2); text.setY(y + 5); } }我很困惑为什么这会在拖动时影响节点的位置?
I'm attempting to make a node that I've created draggable.
I'm able to place the nodes at the point that I like in the pane, but when it comes to dragging them around, they just seem to be automatically offput.
I've tried making a Delta class that would just contain an x and y which would be updated accordingly during the pressing of the mouse on the node.
nfaPane.setOnMousePressed(event -> { if (!event.getButton().equals(MouseButton.PRIMARY)) return; for (final NFANode node : nfaNodes) if (node.isHover()) return; final NFANode nfaNode = new NFANode(nfaNodes.size(), event.getX(), event.getY()); nfaPane.getChildren().add(nfaNode); nfaNodes.add(nfaNode); Delta dragDelta = new Delta(); nfaNode.setOnMousePressed(event1 -> { dragDelta.setDragDeltaX(nfaNode.getLayoutX()); dragDelta.setDragDeltaY(nfaNode.getLayoutY()); }); nfaNode.setOnMouseDragged(event1 -> { nfaNode.moveTo(event1.getSceneX() + dragDelta.getDragDeltaX(), event1.getSceneY() + dragDelta.getDragDeltaY()); }); });The node itself is defined by the class NFANode:
package sample; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.shape.Ellipse; import javafx.scene.text.Font; import javafx.scene.text.Text; /** * Created by David on 11/5/2016. */ public class NFANode extends Group { //private List<NFANode> next; public static final Font nfaFont = Font.font("Footlight MT Light", 25); private final Ellipse bubble; private final Text text; private double textWidth; public NFANode(int value, double x, double y) { this.text = new Text(x, y + 5, ""); renumber(value); this.text.setFont(nfaFont); textWidth = this.text.getBoundsInLocal().getWidth(); bubble = new Ellipse(x, y, this.text.getBoundsInLocal().getWidth() + 5, 25); this.text.setX(x - textWidth / 2); bubble.setStroke(Color.BLACK); bubble.setFill(Color.WHITE); getChildren().addAll(bubble, this.text); } public Text getText() { return text; } public void renumber(final int value) { final StringBuilder builder = new StringBuilder(); for (char c : String.valueOf(value).toCharArray()) builder.append((char) (c + 8272)); text.setText("Q" + builder.toString()); } public void moveTo(final double x, final double y) { bubble.setCenterX(x); bubble.setCenterY(y); text.setX(x - textWidth / 2); text.setY(y + 5); } }I'm confused as to why this would affect the position of the node when dragged?
最满意答案
在按下鼠标时忘记了鼠标位置。
你有以下等式
mousePosition - mousePressedPosition = targetPosition - startPosition所以dragDelta应该是
startPosition - mousePressedPosition = targetPosition - mousePosition我个人更喜欢使用父级的坐标系,但使用场景坐标也应该有效,除非你有一些转换,不仅仅是翻译。
例
private static class Delta { private double dragDeltaX; private double dragDeltaY; public double getDragDeltaX() { return dragDeltaX; } public double getDragDeltaY() { return dragDeltaY; } public void setDragDelta(double x, double y) { this.dragDeltaX = x; this.dragDeltaY = y; } } @Override public void start(Stage primaryStage) { Circle c = new Circle(30); c.setLayoutX(50); c.setLayoutY(50); Pane root = new Pane(c); Delta dragDelta = new Delta(); c.setOnMousePressed(event1 -> { Point2D mouseInParent = c.localToParent(event1.getX(), event1.getY()); dragDelta.setDragDelta(c.getLayoutX() - mouseInParent.getX(), c.getLayoutY()-mouseInParent.getY()); event1.consume(); }); c.setOnMouseDragged(event1 -> { Point2D mouseInParent = c.localToParent(event1.getX(), event1.getY()); c.setLayoutX(mouseInParent.getX() + dragDelta.getDragDeltaX()); c.setLayoutY(mouseInParent.getY() + dragDelta.getDragDeltaY()); }); Scene scene = new Scene(root, 500, 500); primaryStage.setScene(scene); primaryStage.show(); }You forgot to take the mouse position into account when it's pressed.
You've got the following equation
mousePosition - mousePressedPosition = targetPosition - startPositionso dragDelta should be
startPosition - mousePressedPosition = targetPosition - mousePositionPersonally I prefer using the coordinate system of the parent, but using scene coordinates should work too, unless you've got some transformations in place, that are not just translations.
Example
private static class Delta { private double dragDeltaX; private double dragDeltaY; public double getDragDeltaX() { return dragDeltaX; } public double getDragDeltaY() { return dragDeltaY; } public void setDragDelta(double x, double y) { this.dragDeltaX = x; this.dragDeltaY = y; } } @Override public void start(Stage primaryStage) { Circle c = new Circle(30); c.setLayoutX(50); c.setLayoutY(50); Pane root = new Pane(c); Delta dragDelta = new Delta(); c.setOnMousePressed(event1 -> { Point2D mouseInParent = c.localToParent(event1.getX(), event1.getY()); dragDelta.setDragDelta(c.getLayoutX() - mouseInParent.getX(), c.getLayoutY()-mouseInParent.getY()); event1.consume(); }); c.setOnMouseDragged(event1 -> { Point2D mouseInParent = c.localToParent(event1.getX(), event1.getY()); c.setLayoutX(mouseInParent.getX() + dragDelta.getDragDeltaX()); c.setLayoutY(mouseInParent.getY() + dragDelta.getDragDeltaY()); }); Scene scene = new Scene(root, 500, 500); primaryStage.setScene(scene); primaryStage.show(); }更多推荐
发布评论