JavaFX - 在两个节点之间绘制一条线

时间:2012-12-06 12:20:43

标签: java line javafx-2 nodes

我在忙着用JavaFX2编写一个简单的应用程序。目标只是绘制2个节点(通过拖动节点可以移动节点)然后具有在这些节点之间绘制线的功能。 我完成了添加和移动节点的功能(目前我只使用Ellipse形状但我稍后会用自己的节点类替换它)但现在我正在努力处理连接线。添加节点或行的操作来自下拉菜单,我在行功能上有以下代码:

 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个节点之间添加一条线时,它似乎不会结束该函数,而我点击的任何其他节点都会得到一条线。如何防止它多次执行。

我的第二个问题是如何将线“连接”到节点,如果节点移动,线路仍然在节点的中心?

感谢。

2 个答案:

答案 0 :(得分:2)

我认为有一些事情可以使这更简单......

  1. 当您有两个以上的状态(没有点击,点击一个,点击两个)时,请不要使用布隆代替使用枚举。然后你只需要一个变量来照顾。
  2. 只在nodeGroup上设置一个鼠标侦听器,并检查您所处的状态,并在那里拥有相应的代码,而不是单独的鼠标侦听器。
  3. 我认为程序正在为第二次单击设置侦听器,并且在完成后第一次单击时不会将其重置为侦听器。

答案 1 :(得分:0)

由于我是Stack Overflow的新手,我尝试了一些问题 首先在两个标签之间添加行

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