2017-07-29 64 views
0

如何将位于第一个容器中的节点连接到第二个容器中的另一个节点,即如果我有一个具有子节点的窗格,我将如何连接它到另一个窗格子节点,我只管理连接节点是相同的容器,但这不是我所需要的,我想要这样的东西。我如何用一条线连接两个节点

enter code here 
public class Main extends Application { 

    static Pane root = new Pane(); 


    @Override 
    public void start(Stage primaryStage) throws Exception{ 

     Circuit c1 = new Circuit(10,10); 
     Circuit c2 = new Circuit(200,10); 
     Circuit c3 = new Circuit(10,200); 
     Circuit c4 = new Circuit(200,200); 

     root.getChildren().addAll(c1, c2, c3, c4); 

     primaryStage.setScene(new Scene(root, 300, 275)); 
     primaryStage.show(); 
    } 


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

的电路级

enter code here 

import static sample.Main.root; 

public class Circuit extends Pane{ 

Circuit(int LOCATION_X, int LOCATION_Y){ 
    setStyle("-fx-background-color: red"); 
    setPrefSize(150,150); 

    setLayoutX(LOCATION_X); 
    setLayoutY(LOCATION_Y); 

    createCircle cir = new createCircle(); 

    cir.setLayoutX(75); 
    cir.setLayoutY(75); 

    // register handlers 
    cir.setOnDragDetected(startHandler); 
    cir.setOnMouseDragReleased(dragReleaseHandler); 
    cir.setOnMouseDragEntered(dragEnteredHandler); 

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

    getChildren().add(cir); 



    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()); 
      } 
     } 
    }); 
} 

    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); 
     } 
     }; 

} 

从其中所述导线将拉出并连接到

enter code here 

public class createCircle extends Circle { 

createCircle(){ 

    super(25, Color.BLACK.deriveColor(0, 1, 1, 0.5)); 
} 

} 

enter image description here

+0

最终,你连接的东西在同一个容器中(例如它们当然都在场景的根部),而不是直接。将该行添加到要连接的节点的公共祖先。 –

+0

或在顶部添加不可见的窗格并在那里绘制一条线。 –

+0

通过将该行添加到共同的祖先中,你是什么意思?我想将窗格的子节点连接到另一个窗格,共同的祖先将是添加到场景中的主根。情况是会有多个如上所述的电路,并且我必须能够检测到电路连接到哪个电路。 –

回答

1

你混合坐标系统中的点。

Bounds bounds = sourceNode.getBoundsInParent(); 

会给你的sourceNodesourceNode的母公司,这将是目前的Circuit实例的坐标系中的边界(如果我正确地读你的代码)。但是,您正在使用这些边界来计算放置在根节点中的线的坐标,因此您需要根的坐标系中的坐标。

你可以做这样的事情

Bounds boundsInScene = sourceNode.localToScene(sourceNode.getBoundsInLocal()); 
Bounds boundsInRoot = root.sceneToLocal(boundsInScene); 

变换坐标现在boundsInRoot代表sourceNoderoot的坐标系中的边界,所以你可以用它来计算该行的坐标。在整个代码中可能需要进行类似的转换。

+0

是的,我可以看到电线没有,但它仍然有问题,只有从最后一个电路我可以自由地拖动电线,但它不会连接,但当我从电路1拖动线自动连接到电路2和当电路3停止时,电路2连接到电路3。 –