如何在Rectangle中创建一个centerXProperty来绑定?

问题描述:

我正在开发一个视频注释程序。在视频中看到的对象可能被标记为感兴趣的对象,并且如果它们正在交互,则用户可以在两个注释之间画一条线。在可见级别上,对象注释基本上是透明的,它们之间的关系是Line s。此时,计算矩形的中心很容易,但我无法将Line的开始和结束绑定到相应的Rectangle的中心。我曾尝试以下方法:如何在Rectangle中创建一个centerXProperty来绑定?

创建一个计算的中心x和y的矩形类内的两个DoubleBinding S:

private DoubleBinding centerXBinding = new DoubleBinding() { 
    @Override 
    protected double computeValue() { 
     return getX() + getWidth()/2; 
    } 
}; 

,然后将其绑定到新创建的Line

`currentRelation.startXProperty().bind(startShape.centerXBinding());` 

在控制器...

结果是好的,起初,行开始和结束点正是我想避开t下摆,但是当Rectangle被拖到另一个位置时,线条末端不会移动到任何地方! 有没有人看到这个问题?

UPDATE:

一个Rectangle的运动是通过计算偏移量和更新翻译值像translateX完成:

public class MyRectangle extends Rectangle { 

    private double orgSceneX; 
    private double orgSceneY; 
    private double orgTranslateX; 
    private double orgTranslateY; 

    private void initEventHandling() { 
     this.setOnMousePressed(mousePress -> { 
      if (mousePress.getButton() == MouseButton.PRIMARY) { 
       orgSceneX = mousePress.getSceneX(); 
       orgSceneY = mousePress.getSceneY(); 
       orgTranslateX = ((MyRectangle) mousePress.getSource()).getTranslateX(); 
       orgTranslateY = ((MyRectangle) mousePress.getSource()).getTranslateY(); 
       mousePress.consume(); 
      } else if (mousePress.getButton() == MouseButton.SECONDARY) { 
        System.out.println(LOG_TAG + ": right mouse button PRESS on " + this.getId() + ", event not consumed"); 
      } 
     }); 

     this.setOnMouseDragged(mouseDrag -> { 
      if (mouseDrag.getButton() == MouseButton.PRIMARY) { 

       double offsetX = mouseDrag.getSceneX() - orgSceneX; 
       double offsetY = mouseDrag.getSceneY() - orgSceneY; 
       double updateTranslateX = orgTranslateX + offsetX; 
       double updateTranslateY = orgTranslateY + offsetY; 
       this.setTranslateX(updateTranslateX); 
       this.setTranslateY(updateTranslateY); 
       mouseDrag.consume(); 
      } 
     }); 
    } 
} 

你的绑定需要无效时,无论是xPropertywidthProperty是无效(这样绑定它的任何东西都知道要重新计算)。您可以通过调用自定义绑定的构造函数中bind method做到这一点:

private DoubleBinding centerXBinding = new DoubleBinding() { 

    { 
     bind(xProperty(), widthProperty()); 
    } 

    @Override 
    protected double computeValue() { 
     return getX() + getWidth()/2; 
    } 
}; 

注意,你也可以做

private DoubleBinding centerXBinding = xProperty().add(widthProperty().divide(2)); 

两者之间的选择真的只是一个你更喜欢哪一种风格的问题。

绑定到xwidth属性显然假定您正在通过更改其中一个或两个属性来移动矩形。如果您正在通过一些其他方式的矩形(例如,通过改变其translateXtranslateY属性中的一个,或通过改变其转换的列表),那么你就需要观察boundsInParentProperty代替:

private DoubleBinding centerXBinding = new DoubleBinding() { 

    { 
     bind(boundsInParentProperty()); 
    } 

    @Override 
    protected double computeValue() { 
     Bounds bounds = getBoundsInParent(); 
     return (bounds.getMinX() + bounds.getMaxX())/2 ; 
    } 
} 

这种绑定将在父坐标系中给出矩形中心的x坐标(通常是你想要的坐标系)。

+0

不幸的是,我正在通过'translateX'移动'Rectangle',所以这个解决方案(尽管是正确的)不是让绑定工作的解决方案。当我的翻译完成后,你知道该怎么办? – deHaar

+1

@deHaar这就是人们发布不包含[MCVE]的问题时如此令人沮丧的原因:不能保证他们描述的问题是由他们发布的代码造成的,而不是由他们未发布的其他代码造成的这是这里的情况)。请更新您的问题。 (或者,显然,改变你的方法,以便通过改变'x'来移动矩形。) –

+0

对于令人沮丧的抱歉抱歉,我更新了带'Rectangle'移动代码的问题。我的解决方案有相应的属性,所以我会将这个方法改为与翻译值绑定,因为它们会被渲染。如果你知道更好的方法,请告诉我。 – deHaar