我正在尝试创建一个我已创建可拖动的节点。
我可以将节点放在窗格中我喜欢的位置,但是当它们拖动它们时,它们似乎只是自动输出。
我已经尝试制作一个只包含x和y的Delta类,在节点上按下鼠标时会相应地更新。
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);
}
}
我很困惑为什么这会在拖动时影响节点的位置?
答案 0 :(得分:0)
按下鼠标时忘记了鼠标位置。
你有以下等式
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();
}