Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFx通过拖放将两个子节点连接到一条线_Java_User Interface_Javafx_Nodes_Drag - Fatal编程技术网

JavaFx通过拖放将两个子节点连接到一条线

JavaFx通过拖放将两个子节点连接到一条线,java,user-interface,javafx,nodes,drag,Java,User Interface,Javafx,Nodes,Drag,我有两个节点。我想单击一个节点,将光标拖到另一个节点上,释放光标后用一条线连接两个节点 我已经设置了所有eventhandler——拖放行是可行的,但它不会绑定到第二个节点 public class LinkHandler { static Node hoverNode; } 此类用于查找光标悬停在哪个节点上 private void setLinkHandlers(Node node) { Line line = new Line(); this.getChildre

我有两个节点。我想单击一个节点,将光标拖到另一个节点上,释放光标后用一条线连接两个节点

我已经设置了所有eventhandler——拖放行是可行的,但它不会绑定到第二个节点

public class LinkHandler {
    static Node hoverNode;
}
此类用于查找光标悬停在哪个节点上

private void setLinkHandlers(Node node) {
    Line line = new Line();
    this.getChildren().add(line);

    // On mouse hover, set LinkHandler.hoverNode
    node.setOnMouseDragEntered( (MouseEvent mouseEvent) -> {
        LinkHandler.setHoverNode(node);
        System.out.println(node);
    });

    // On mouse exit, remove LinkHandler.hoverNode
    node.setOnMouseDragExited( (MouseEvent mouseEvent) -> {
       // PLEASE NOTE: I have tried commenting and uncommenting the line below. Neither works.
       // LinkHandler.setHoverNode(null);
    });

    // On mouse press, set Line startpoint
    node.setOnMousePressed( (MouseEvent mouseEvent) -> {
        // Stop BorderPane from being dragged
        LinkHandler.isConnecting = true;

        // Bind startpoint to node position
        line.startXProperty().bind(node.layoutXProperty());
        line.startYProperty().bind(node.layoutYProperty());
    });

    // On mouse released, either bind Line to LinkHandler.hoverNode, or remove if hoverNode = null
    node.setOnMouseReleased( (MouseEvent mouseEvent) -> {
        // Allow BorderPane to be dragged again
        LinkHandler.isConnecting = false;

        // If there is a node to connect to...
        if(LinkHandler.getHoverNode() != null) {
            // Bind end position to the node's position
            line.endXProperty().bind(LinkHandler.getHoverNode().layoutXProperty());
            line.endYProperty().bind(LinkHandler.getHoverNode().layoutYProperty());
        } else {
            // Otherwise print error
            System.out.println("Not hovering over a node. Cannot create connection.");
        }
    });

    // Temporarily bind Line endpoint to mouse position.
    node.setOnMouseDragged( (MouseEvent mouseEvent) -> {
        line.setEndX(mouseEvent.getX());
        line.setEndY(mouseEvent.getY());
    });
}
这是大量代码,因此我将尝试对其进行总结:

  • 拖动代理后,将LinkHandler.hoverNode设置为此节点
  • dragExit时,将LinkHandler.hoverNode设置为null
  • 按下鼠标时,将线起始位置绑定到此节点位置
  • 当鼠标标记时,临时将“行结束位置”设置为“鼠标位置”
  • 释放鼠标后,将行结束位置绑定到LinkerHandler.hoverNode位置,或删除行为hoverNode为null
我认为问题在于这段代码:

    // On mouse hover, set LinkHandler.hoverNode
    node.setOnMouseDragEntered( (MouseEvent mouseEvent) -> {
        LinkHandler.setHoverNode(node);
        System.out.println(node);
    });

    // On mouse exit, remove LinkHandler.hoverNode
    node.setOnMouseDragExited( (MouseEvent mouseEvent) -> {
       // LinkHandler.setHoverNode(null);
    });

我认为这个电话打得不好。此代码应用于的节点是BorderPane的子节点,它具有自己的onMouseDrag功能请注意,您从未初始化完全拖动,因此事件从未传递到拖动的开始节点以外的节点。要更改此设置,请为开始节点调用
startFullDrag()

以下示例演示如何将线捕捉到圆的中心:

public static Circle createCircle(double x, double y) {
    return new Circle(x, y, 20, Color.BLACK.deriveColor(0, 1, 1, 0.5));
}

@Override
public void start(Stage primaryStage) {

    Node[] circles = new Node[]{
        createCircle(40, 40),
        createCircle(240, 40),
        createCircle(40, 240),
        createCircle(240, 240)
    };
    Pane root = new Pane(circles);

    class DragStartHandler implements EventHandler<MouseEvent> {

        public Line line;

        @Override
        public void handle(MouseEvent event) {
            if (line == null) {
                Node sourceNode = (Node) event.getSource();
                line = new Line();
                Bounds bounds = sourceNode.getBoundsInParent();

                // start line at center of node
                line.setStartX((bounds.getMinX() + bounds.getMaxX()) / 2);
                line.setStartY((bounds.getMinY() + bounds.getMaxY()) / 2);
                line.setEndX(line.getStartX());
                line.setEndY(line.getStartY());
                sourceNode.startFullDrag();
                root.getChildren().add(0, line);
            }
        }
    }

    DragStartHandler startHandler = new DragStartHandler();
    EventHandler<MouseDragEvent> dragReleaseHandler = evt -> {
        if (evt.getGestureSource() == evt.getSource()) {
            // remove line, if it starts and ends in the same node
            root.getChildren().remove(startHandler.line);
        }
        evt.consume();
        startHandler.line = null;
    };
    EventHandler<MouseEvent> dragEnteredHandler = evt -> {
        if (startHandler.line != null) {
            // snap line end to node center
            Node node = (Node) evt.getSource();
            Bounds bounds = node.getBoundsInParent();
            startHandler.line.setEndX((bounds.getMinX() + bounds.getMaxX()) / 2);
            startHandler.line.setEndY((bounds.getMinY() + bounds.getMaxY()) / 2);
        }
    };

    for (Node n : circles) {
        // register handlers
        n.setOnDragDetected(startHandler);
        n.setOnMouseDragReleased(dragReleaseHandler);
        n.setOnMouseDragEntered(dragEnteredHandler);

        // add info allowing to identify this node as drag source/target
        n.setUserData(Boolean.TRUE);
    }

    root.setOnMouseReleased(evt -> {
        // mouse released outside of a target -> remove line
        root.getChildren().remove(startHandler.line);
        startHandler.line = null;
    });
    root.setOnMouseDragged(evt -> {
        if (startHandler.line != null) {
            Node pickResult = evt.getPickResult().getIntersectedNode();
            if (pickResult == null || pickResult.getUserData() != Boolean.TRUE) {
                // mouse outside of target -> set line end to mouse position
                startHandler.line.setEndX(evt.getX());
                startHandler.line.setEndY(evt.getY());
            }
        }
    });

    Scene scene = new Scene(root, 280, 280);

    primaryStage.setScene(scene);
    primaryStage.show();
}
公共静态圆createCircle(双x,双y){
返回新的圆(x,y,20,Color.BLACK.deriveColor(0,1,1,0.5));
}
@凌驾
公共无效开始(阶段primaryStage){
节点[]圆=新节点[]{
createCircle(40,40),
createCircle(240,40),
createCircle(40240),
createCircle(240240)
};
窗格根=新窗格(圆圈);
类DragStartHandler实现EventHandler{
公共线路;
@凌驾
公共无效句柄(MouseeEvent事件){
如果(行==null){
Node sourceNode=(Node)event.getSource();
行=新行();
Bounds Bounds=sourceNode.getBoundsInParent();
//节点中心的起始线
line.setStartX((bounds.getMinX()+bounds.getMaxX())/2);
line.setStartY((bounds.getMinY()+bounds.getMaxY())/2);
line.setEndX(line.getStartX());
line.setEndY(line.getStartY());
sourceNode.startFullDrag();
root.getChildren().add(0,行);
}
}
}
DragStartHandler startHandler=新的DragStartHandler();
EventHandler DragreeLeaseHandler=evt->{
if(evt.getGestureSource()==evt.getSource()){
//删除在同一节点中开始和结束的线
root.getChildren().remove(startHandler.line);
}
evt.consume();
startHandler.line=null;
};
EventHandler dragEnteredHandler=evt->{
if(startHandler.line!=null){
//将线端点捕捉到节点中心
Node Node=(Node)evt.getSource();
Bounds=node.getBoundsInParent();
startHandler.line.setEndX((bounds.getMinX()+bounds.getMaxX())/2);
startHandler.line.setEndY((bounds.getMinY()+bounds.getMaxY())/2);
}
};
用于(节点n:圆){
//寄存器处理程序
n、 检测到SetOnDrag(startHandler);
n、 setOnMouseDragReleased(dragReleaseHandler);
n、 setOnMouseDragEntered(dragEnteredHandler);
//添加允许将此节点标识为拖动源/目标的信息
n、 setUserData(Boolean.TRUE);
}
root.setOnMouseReleased(evt->{
//鼠标在目标外释放->删除线
root.getChildren().remove(startHandler.line);
startHandler.line=null;
});
root.setonMouseDrawed(evt->{
if(startHandler.line!=null){
节点pickResult=evt.getPickResult().getIntersectedNode();
if(pickResult==null | | pickResult.getUserData()!=Boolean.TRUE){
//鼠标移到目标之外->将线端设置为鼠标位置
startHandler.line.setEndX(evt.getX());
startHandler.line.setEndY(evt.getY());
}
}
});
场景=新场景(根,280,280);
初级阶段。场景(场景);
primaryStage.show();
}

我在
setOnDragDetected
事件处理程序中加入了
startFullDrag()
命令,但由于某些原因,它仍然无法工作
setOnMouseDragEntered
从不点火。