2017-07-29 87 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。 –

相關問題