2012-12-06 132 views
2

我在忙着使用JavaFX2编写一个简单的应用程序。目标是绘制2个节点(节点可以通过拖动来移动),然后有一个在这些节点之间画线的函数。 我完成了添加和移动节点的功能(目前我只是使用椭圆形状,但我稍后将用自己的节点类替换它),但现在我正在用连接线挣扎。该行动以添加一个节点或一条线是从一个下拉菜单,我有上线的功能如下代码:JavaFX - 在两个节点之间绘制一条线

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

我只是有布尔检查第一和第二点击得到的中心每个节点。 我的第一个问题是,当我点击行功能并在2个节点之间添加一条线时,它似乎不会结束该功能,而我点击的任何其他节点都会获得一条线。我怎样才能防止它多次执行。

而我的第二个问题是,如何将线连接到节点,如果节点移动,线保持在节点的中心?

谢谢。

+0

我加 ' line.startXProperty()。bind(((Ellipse)t1.getTarget())。layoutXProperty()。add((Ellipse)t1.getTarget())。centerXProperty()));' 对于每个坐标。 现在它似乎工作。 但我仍然有问题,每次点击一个节点时,该函数会绘制多行。我该如何解决这个问题。并视我的线路连接方法。有没有更好的做法呢? – Jacques

回答

2

我认为有几件事情可能使这个简单...

  1. 不要使用布尔值,当你有两个以上的状态(无点击,点击一个,单击二)使用枚举代替。那么你只需要一个变量来照顾。
  2. 只能在nodeGroup上设置一个鼠标侦听器,并检查您所在的状态,并在其中具有适当的代码,而不是单独的鼠标侦听器。

我想,程序设置第二次点击的侦听器,并且在完成时不会将其重置为侦听器的第一次点击。

+0

谢谢,我会考虑这一点,并重新考虑我的方法。 – Jacques

0

由于我是新来的堆栈溢出,我尝试了两种标签

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

} 

之间,然后在你的问题 先加线的东西添加此方法...

// 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);  
} 
+0

它给出你想要的输出。 – Kundan

相关问题