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

JavaFX-在两个节点之间绘制一条线,java,line,javafx-2,nodes,Java,Line,Javafx 2,Nodes,我正在忙着用JavaFX2编写一个简单的应用程序。目标只是绘制2个节点(通过拖动节点可以移动节点),然后使用函数在这些节点之间绘制线。 我完成了添加和移动节点的功能(目前我只使用椭圆形状,但稍后我将用我自己的节点类替换它),但现在我正在处理连接线。添加节点或线条的操作来自下拉菜单,我在线条功能上有以下代码: private void drawLine(MenuItem line) { final BooleanProperty lineActive = new SimpleBoole

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

 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);                     
                        }
                    });
                }
            }
        }
    });
}
private void drawine(菜单项线){
final BooleanProperty lineActive=新的SimpleBoleAnProperty(false);
final BooleanProperty clickOne=新的SimpleBoleanProperty(false);
final BooleanProperty clickTwo=新的SimpleBoleanProperty(false);
line.setOnAction(新的EventHandler(){
公共无效句柄(ActionEvent t){
lineActive.set(真);
}
});
nodeGroup.setOnMousePressed(新的EventHandler(){
公共无效句柄(最终MouseEvent t1){
单击一个。设置(true);
if(lineActive.get()){
如果(单击一个。获取()){
//获取第一个节点的x和y
x1=((椭圆)t1.getTarget()).getCenterX();
y1=((椭圆)t1.getTarget()).getCenterY();
单击一个。设置(false);
单击两个。设置(true);
}
如果(单击两个。获取()){
setOnMouseClicked(新建EventHandler()){
公共无效句柄(MouseEvent t2){
//获取第二个节点的x和y
x2=((椭圆)t2.getTarget()).getCenterX();
y2=((椭圆)t2.getTarget()).getCenterY();
//在节点之间画线
最后一行=新行();
行。设置开始x(x1);
行。设置起始值(y1);
行。setEndX(x2);
行。setEndY(y2);
canvas.getChildren().add(行);
单击两个。设置(false);
lineActive.set(false);
}
});
}
}
}
});
}
我只是用布尔函数来检查第一次和第二次单击以获得每个节点的中心。 我的第一个问题是,当我单击line函数并在两个节点之间添加一条线时,它似乎并没有结束函数,我单击的任何其他节点都会得到一条线。如何防止它执行多次

我的第二个问题是,如何将线“连接”到节点上,如果节点移动,线会停留在节点的中心


谢谢。

我想有几件事可以让这更简单

  • 如果有两个以上的状态(无单击、单击一、单击二),请不要使用布尔值,而是使用枚举。那么您只需要处理一个变量
  • 只能在节点组上设置一个鼠标侦听器,并检查您处于哪个状态,并且在那里有适当的代码,而不是单独的鼠标侦听器

  • 我想象程序正在为第二次单击设置侦听器,而不是在完成第一次单击时将其重置为侦听器。

    由于我不熟悉堆栈溢出,我尝试了解决您的问题的方法 首先在两个标签之间添加行

    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);      
    }
    
    //此代码处理标签移动
    //为lblDrag将LBLDFragmusePressed方法设置为鼠标按下事件
    @FXML
    公共空间LBLDM(MouseeEvent m)
    {
    System.out.println(“按下鼠标”);
    PREVLBRCORDX=(int)lblDragTest.getLayoutX();
    PREVLBRCORDY=(int)lblDragTest.getLayoutY();
    prevMouseCordX=(int)m.getX();
    prevMouseCordY=(int)m.getY();
    }
    //在lblDrag的鼠标释放事件上设置此方法
    @FXML
    已释放公共无效LBLDL(MouseEvent m)
    {       
    System.out.println(“标签拖动”);
    }
    //在lblDrag的鼠标拖动事件上设置此方法
    @FXML
    公共空白LBLDM(MouseEvent m)
    {   
    diffX=(int)(m.getX()-prevMouseCordX);
    diffY=(int)(m.getY()-prevMouseCordY);
    int x=(int)(diffX+lblDragTest.getLayoutX()-rootancorpane.getLayoutX());
    int y=(int)(diffY+lblDragTest.getLayoutY()-rootAnchorPane.getLayoutY());
    如果(y>0&&x>0&&y
    I添加了
    line.startXProperty().bind((椭圆)t1.getTarget()).layoutXProperty().add((椭圆)t1.getTarget()).centerXProperty())用于每个坐标。现在它似乎起作用了。但我仍然存在一个问题,即每次单击节点时,函数都会绘制多条线。我怎样才能解决那个问题。关于我的线路连接方法。也许有更优雅的方法吗?谢谢,我会考虑一下,重新考虑我的方法。