Javafx 如何在要绑定到的矩形中创建centerXProperty?

Javafx 如何在要绑定到的矩形中创建centerXProperty?,javafx,properties,binding,Javafx,Properties,Binding,我正在开发一个视频注释程序。视频中看到的对象可以标记为感兴趣的对象,如果它们正在交互,用户可以在两个注释之间画一条线。在可见级别上,对象注释基本上是透明的Rectangles,它们之间的关系是Lines。此时,计算矩形的中心很容易,但我无法将行的起点和终点绑定到相应的矩形的中心。我尝试了以下方法: 在计算中心x和y的矩形类内创建两个DoubleBindings: private DoubleBinding centerXBinding = new DoubleBinding() { @

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

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

private DoubleBinding centerXBinding = new DoubleBinding() { 
    @Override
    protected double computeValue() {
        return getX() + getWidth() / 2;
    }
};
然后将其绑定到新创建的

`currentRelation.startXProperty().bind(startShape.centerXBinding());`
在控制器中

结果是好的,首先,线的起点和终点正是我想要的位置,但是当一个
矩形
被拖到另一个位置时,线的终点不会移动到任何地方! 有人看到问题了吗

更新:

通过计算偏移量并更新平移值(如
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();
            }
        });
    }
}

xProperty
widthProperty
无效时,您的绑定需要无效(以便绑定到它的任何东西都知道要重新计算)。可以通过在自定义绑定的构造函数中调用:

private DoubleBinding centerXBinding = new DoubleBinding() { 

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

    @Override
    protected double computeValue() {
        return getX() + getWidth() / 2;
    }
};
注意你也可以这样做

private DoubleBinding centerXBinding = xProperty().add(widthProperty().divide(2));
两者之间的选择实际上只是你喜欢哪种风格的问题

显然,绑定到
x
width
属性会假定您通过更改其中一个或两个属性来移动矩形。如果通过其他方式移动矩形(例如,通过更改其
translateX
translateY
属性之一,或通过更改其变换列表),则需要观察
boundsInParentProperty

private DoubleBinding centerXBinding = new DoubleBinding() {

    {
        bind(boundsInParentProperty());
    }

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

此绑定将提供父坐标系(通常是您想要的坐标系)中矩形中心的x坐标。

xProperty
widthProperty
无效时,绑定需要无效(以便绑定到它的任何对象都知道重新计算)。可以通过在自定义绑定的构造函数中调用:

private DoubleBinding centerXBinding = new DoubleBinding() { 

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

    @Override
    protected double computeValue() {
        return getX() + getWidth() / 2;
    }
};
注意你也可以这样做

private DoubleBinding centerXBinding = xProperty().add(widthProperty().divide(2));
两者之间的选择实际上只是你喜欢哪种风格的问题

显然,绑定到
x
width
属性会假定您通过更改其中一个或两个属性来移动矩形。如果通过其他方式移动矩形(例如,通过更改其
translateX
translateY
属性之一,或通过更改其变换列表),则需要观察
boundsInParentProperty

private DoubleBinding centerXBinding = new DoubleBinding() {

    {
        bind(boundsInParentProperty());
    }

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

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

很遗憾,我正在通过
translateX
移动
矩形
,因此此解决方案(尽管正确)不是使绑定工作的解决方案。你知道当我的动作是通过翻译完成的时候该怎么做吗?@deHaar这就是为什么当人们发布的问题中没有包含a的时候会如此令人沮丧:不能保证他们描述的问题是由他们发布的代码引起的,而不是由他们没有发布的其他代码引起的(这里就是这种情况)。请更新您的问题。(或者,很明显,改变你的方法,通过改变
x
来移动矩形)很抱歉让人沮丧,我用移动
矩形的代码更新了这个问题。我的解决方案有相应的属性,因此我将把aproach更改为具有转换值的绑定,因为它们是被中断的。如果您知道任何更好的方法,请让我知道。@deHaar请参阅答案编辑。你为什么要平移矩形而不是使用改变其
x
y
坐标的方法(更明显一些)呢?不,没有……至少没有一个原因,但事实是它在那样的教程中,并且正在工作。是的,调整
x
y
坐标是最明显的方法(当思考而不是阅读和复制粘贴时)。尽管如此,您在更新的答案中发布的绑定仍能正常工作,非常感谢。很遗憾,我正在通过
translateX
移动
矩形
,因此此解决方案(尽管正确)不是使绑定工作的解决方案。你知道当我的动作是通过翻译完成的时候该怎么做吗?@deHaar这就是为什么当人们发布的问题中没有包含a的时候会如此令人沮丧:不能保证他们描述的问题是由他们发布的代码引起的,而不是由他们没有发布的其他代码引起的(这里就是这种情况)。请更新您的问题。(或者,很明显,改变你的方法,通过改变
x
来移动矩形)很抱歉让人沮丧,我用移动
矩形的代码更新了这个问题。我的解决方案有相应的属性,因此我将把aproach更改为具有转换值的绑定,因为它们是被中断的。如果您知道任何更好的方法,请让我知道。@deHaar请参阅答案编辑。你为什么要平移矩形而不是使用改变其
x
y
坐标的方法(更明显一些)呢?不,没有……至少没有一个原因,但事实是它在那样的教程中,并且正在工作。是的,调整
x
y
坐标是最明显的方法(当思考而不是阅读和复制粘贴时)。尽管如此