Shady Watson
Shady Watson

Reputation: 114

How do i connect two nodes with a line

How do I connect a node which lies in the first container to another node in the second container, i.e if i have a pane which has a sub node in it how will i connect it to another pane sub node, I've only manged to connect nodes that are is the same container but that's is not what i need, i want something like this.

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

The circuit Class

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

 }

The point from where the wire will drawn out and connected to

enter code here

 public class createCircle extends Circle {

createCircle(){

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

}

enter image description here

Upvotes: 0

Views: 637

Answers (1)

James_D
James_D

Reputation: 209358

You are mixing coordinate systems.

Bounds bounds = sourceNode.getBoundsInParent();

will give you the bounds of sourceNode in the coordinate system of the sourceNode's parent, which is going to be the current Circuit instance (if I read your code correctly). However, you are using those bounds to calculate the coordinates of the line, which is placed in the root node, so you need the coordinates in the coordinate system of the root.

You can transform the coordinates by doing something like

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

Now boundsInRoot represents the bounds of sourceNode in the coordinate system of root, so you can use it to compute the coordinates of the line. There are likely similar transforms you need to make throughout the code.

Upvotes: 1

Related Questions