2

I am busying writing a simple application using JavaFX2. The goal is just to plot 2 nodes (the nodes are movable by dragging them) and then have a function to draw lines between these nodes. I finished the functions to add and move nodes (at the moment I am just using Ellipse shapes but I am going to replace it later with my own node class) but now I am struggling with the connecting lines. The actions to add a node or a line is from a dropdown menu and I have the following code on the line function:

 private void drawLine(MenuItem line) {

    final BooleanProperty lineActive = new SimpleBooleanProperty(false);
    final BooleanProperty clickOne = new SimpleBooleanProperty(false);
    final BooleanProperty clickTwo = new SimpleBooleanProperty(false);

    line.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {              
            lineActive.set(true);
        }
    });

    nodeGroup.setOnMousePressed(new EventHandler<MouseEvent>() {
        public void handle(final MouseEvent t1) {
            clickOne.set(true);

            if (lineActive.get()) {

                if (clickOne.get()) {
                    //get x and y of first node
                    x1 = ((Ellipse) t1.getTarget()).getCenterX();
                    y1 = ((Ellipse) t1.getTarget()).getCenterY();
                    clickOne.set(false);
                    clickTwo.set(true);
                }

                if (clickTwo.get()) {
                    nodeGroup.setOnMouseClicked(new EventHandler<MouseEvent>() {
                        public void handle(MouseEvent t2) {
                            //get x and y of second node
                            x2 = ((Ellipse) t2.getTarget()).getCenterX();
                            y2 = ((Ellipse) t2.getTarget()).getCenterY();

                            //draw line between nodes
                            final Line line = new Line();
                            line.setStartX(x1);
                            line.setStartY(y1);
                            line.setEndX(x2);
                            line.setEndY(y2);

                            canvas.getChildren().add(line);

                            clickTwo.set(false);
                            lineActive.set(false);                     
                        }
                    });
                }
            }
        }
    });
}

I just have the booleans to check for the first and second click to get the center of each node. My first question is when I click on the line function and add a line between 2 nodes, it doesn't seem to end the function, and any other nodes I click on gets a line to it. How can I prevent it from executing more than once.

And my second question is how can I "connect" the line to the nodes that if the node moves, the line stays in the center of the node?

Thanks.

Jacques
  • 55
  • 1
  • 6
  • I added `line.startXProperty().bind(((Ellipse) t1.getTarget()).layoutXProperty().add(((Ellipse) t1.getTarget()).centerXProperty()));` for every coord. Now it seems to work. But I still have the problem that the function draws multiple lines everytime I click a node. How can I solve that problem. And regards to my line connecting method. Is there perhaps a more elegant way of doing it? – Jacques Dec 06 '12 at 13:06

2 Answers2

2

I think there is a couple of things which could make this simpler...

  1. Do not use booleans when you have more than two states (no click, click one, click two) use an enum instead. Then you only need one variable to look after.
  2. Only ever set one mouse listener on the nodeGroup and check which state you're in and have the appropriate code there instead of separate mouse listeners.

I imagine that the program is setting the listener for the second click and not resetting it to the listener for the first click when it completes.

Andy Till
  • 3,371
  • 2
  • 18
  • 23
0

Since i am new to Stack Overflow , I tried something on your problem First add line between two labels

final Line line = new Line();

@Override
public void initialize(URL arg0, ResourceBundle arg1) 
{
    // TODO Auto-generated method stub

     line.setStartX(lblDragTest.getLayoutX());
     line.setStartY(lblDragTest.getLayoutY());
     line.setEndX(lblNew.getLayoutX());
     line.setEndY(lblNew.getLayoutY());
     rootAnchorPane.getChildren().add(line);

}

And then add this methods...

// This code handles label move
//set lblDragMousePressed method to Mouse Pressed event for lblDrag
@FXML
public void lblDragMousePressed(MouseEvent m)
{
    System.out.println("Mouse is pressed");     
    prevLblCordX= (int) lblDragTest.getLayoutX();
    prevLblCordY= (int) lblDragTest.getLayoutY();
    prevMouseCordX= (int) m.getX();
    prevMouseCordY= (int) m.getY();     
}
//set this method on mouse released event for lblDrag
@FXML
public void lblDragMouseReleased(MouseEvent m)
{       
    System.out.println("Label Dragged");    
}
// set this method on Mouse Drag event for lblDrag
@FXML
public void lblDragMouseDragged(MouseEvent m)
{   

    diffX= (int) (m.getX()- prevMouseCordX);
    diffY= (int) (m.getY()-prevMouseCordY );        
    int x = (int) (diffX+lblDragTest.getLayoutX()-rootAnchorPane.getLayoutX());
    int y = (int) (diffY+lblDragTest.getLayoutY()-rootAnchorPane.getLayoutY());     
    if (y > 0 && x > 0 && y < rootAnchorPane.getHeight() && x < rootAnchorPane.getWidth()) 
    { 
     lblDragTest.setLayoutX(x);
     lblDragTest.setLayoutY(y);
    }

    line.setStartX(lblDragTest.getLayoutX());
    line.setStartY(lblDragTest.getLayoutY());
    line.setEndX(lblNew.getLayoutX());
    line.setEndY(lblNew.getLayoutY());
    // rootAnchorPane.getChildren().add(line);      
}
Kundan
  • 261
  • 4
  • 11