JavaFX实现链接属性

JavaFX实现链接属性,javafx,javafx-8,Javafx,Javafx 8,在JavaFX中实现链接或相互依赖属性的最佳方法是什么 例如,我有一个区间,我想用三个整数属性来表示,lower,upper和range,这样range=upper-lower,如果您试图设置范围,它也会设置upper(到lower+range) 这在传统的JavaBean(set/get方法)中很简单,但是JavaFX属性包含了可观察的概念和绑定,并且似乎很快变得复杂 我尝试过绑定,但这会使目标属性不可设置,也会导致双向绑定,但我只能绑定“相等”,而不能绑定表达式 我已经开始将range实现为

在JavaFX中实现链接或相互依赖属性的最佳方法是什么

例如,我有一个区间,我想用三个整数属性来表示,
lower
upper
range
,这样
range=upper-lower
,如果您试图设置范围,它也会设置upper(到
lower+range

这在传统的JavaBean(set/get方法)中很简单,但是JavaFX属性包含了可观察的概念和绑定,并且似乎很快变得复杂

我尝试过绑定,但这会使目标属性不可设置,也会导致双向绑定,但我只能绑定“相等”,而不能绑定表达式

我已经开始将
range
实现为
javafx.beans.property.IntegerProperty
,但处理侦听器等似乎需要大量工作

有没有更简单的方法

编辑: 这就是使用JavaBean模式时的情况:

private int lower = 0;
private int upper = 0;

public int getLower() {
    return lower;
}
public void setLower(int lower) {
    this.lower = lower;
}

public int getUpper() {
    return upper;
}
public void setUpper(int upper) {
    this.upper = upper;
}

public int getRange() {
    return upper - lower;
}
public void setRange(int range) {
    upper = lower + range;
}
我将如何以JavaFX的方式实现这一点? 这是我试过的

IntegerProperty lower = new SimpleIntegerProperty(this, "lower", 0);
IntegerProperty upper = new SimpleIntegerProperty(this, "upper", 0);
IntegerProperty range = new SimpleIntegerProperty(this, "range", 0);

public LinkedPropTest() { // Constructor
    lower.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
        range.setValue(upper.getValue() - lower.getValue());
    });
    upper.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
        range.setValue(upper.getValue() - lower.getValue());
    });
    range.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
        upper.setValue(range.getValue() + lower.getValue());
    });
}
IntegerProperty lower=新的SimpleIntegerProperty(这个“lower”,0);
IntegerProperty upper=新的SimpleIntegerProperty(此“upper”,0);
IntegerProperty范围=新的SimpleIntegerProperty(此“范围”,0);
public linkedoptest(){//构造函数
lower.addListener((observeValueOk,我们需要:

  • 两个默认的
    IntegerProperty
    对象作为
    SimpleIntegerProperty
  • 还有一个自定义的
    IntegerProperty
    ,它派生自,用于根据您的需要实现一些特殊行为
因此,我们将您的财产作为成员:

private final IntegerProperty lower = new SimpleIntegerProperty(0);
private final IntegerProperty upper = new SimpleIntegerProperty(0);
private final IntegerProperty range = new IntegerPropertyBase() {

    {
        upper.addListener(obs -> update());
        lower.addListener(obs -> update());
    }

    @Override
    public String getName() {
        return "range";
    }

    @Override
    public Object getBean() {
        return Main.this;
    }

    private void update() {
        super.set(upper.get() - lower.get());
    }

    @Override
    public void set(int newValue) {
        upper.set(lower.get() + newValue);
    }

};
我们的自定义属性基本上是一个可观察的复合数,具有可设置的特殊情况。因此,我们覆盖了一些方法并注册了必要的侦听器

以及一些示例代码来测试/验证这一点:

private void printStats() {
    System.out.println("lower : " + lower.get() + " - upper: "
            + upper.get() + " - range: " + range.get());
    System.out.println();
}

@Override
public void start(Stage primaryStage) {

    lower.addListener(obs -> {System.out.println("Lower changed"); printStats();});
    upper.addListener(obs -> {System.out.println("Upper changed"); printStats();});
    range.addListener(obs -> {System.out.println("Range changed"); printStats();});

    System.out.println(" ######### TEST #1 #############");
    lower.set(5);

    System.out.println(" ######### TEST #2 #############");
    upper.set(5);

    System.out.println(" ######### TEST #3 #############");
    range.set(10);
}

为了正确地理解这一点:您希望所有三个属性都是独立的/可设置的?是的,因此用户可以绑定到三个属性,但只有两个独立的属性。您回答了是和否;-)哪一个是独立的?你说两个?是的。我在原始帖子中添加了一些代码,希望能澄清它。谢谢!太好了。我还要补充一点,即使在使用WritableIntegerValue中定义的setValue(Number)方法时,以及在进一步绑定变量时,这也能很好地工作(我不清楚在没有进一步重写的情况下是否会这样做)这就是(ab)使用
IntegerPropertyBase
的优点,它是管理依赖项和侦听器的大多数样板文件的基本实现。