2012-12-06 99 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

相關問題