Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX8双向绑定_Java_Data Binding_Javafx_Javafx 8 - Fatal编程技术网

JavaFX8双向绑定

JavaFX8双向绑定,java,data-binding,javafx,javafx-8,Java,Data Binding,Javafx,Javafx 8,以下代码激发java.lang.RuntimeException:无法设置绑定值: public class Test { public static void main( String[] args ) { final DoubleProperty amount = new SimpleDoubleProperty( 100_000.00 ); final DoubleProperty rate = new SimpleDoubleProperty();

以下代码激发
java.lang.RuntimeException:无法设置绑定值

public class Test {

   public static void main( String[] args ) {
      final DoubleProperty amount = new SimpleDoubleProperty( 100_000.00 );
      final DoubleProperty rate   = new SimpleDoubleProperty();
      final DoubleProperty part   = new SimpleDoubleProperty();
      rate.bind( part.divide  ( amount.getValue()));
      part.bind( rate.multiply( amount.getValue()));
      rate.set( 0.025 );//<<----------------------------------- Here is the cause
      System.out.println( "Part: " + part.get());
      part.set( 1200 );
      System.out.println( "Rate: " + rate.get());
   }
}
公共类测试{
公共静态void main(字符串[]args){
最终双重财产金额=新的简化双重财产(100_000.00);
最终DoubleProperty比率=新SimpleDoubleProperty();
最终DoubleProperty部分=新的SimpleDoubleProperty();
rate.bind(part.divide(amount.getValue());
part.bind(rate.multiply(amount.getValue());

rate.set(0.025);//一个简单的静态方法,一个自制的
NumberBiBinding
做这个工作:

public final class NumberBiBinding {

   public static void bind(
      Property<Number> operand1,
      NumberBinding    operator1,
      Property<Number> operand2,
      NumberBinding    operator2  )
   {
      assert operand1 != operand2;
      operand1.addListener( o -> operand2.setValue( operator1.getValue()));
      operand2.addListener( o -> operand1.setValue( operator2.getValue()));
   }
}

public final class Test {

   public static void main( String[] args ) {
      final DoubleProperty amount = new SimpleDoubleProperty( 100_000.00 );
      final DoubleProperty rate   = new SimpleDoubleProperty();
      final DoubleProperty part   = new SimpleDoubleProperty();

      NumberBiBinding.bind(
         rate, rate.multiply( amount ),
         part, part.divide  ( amount ));

      System.out.println( "Amount: " + amount.get());
      rate.set( 0.025 );
      System.out.println(
        "Part is " + part.get() + " when rate is set to " + rate.get());
      part.set( 1200 );
      System.out.println(
         "Rate is " + rate.get() + " when part is set to " + part.get());
   }
}

一个可能的解决方案是创建InvalizationListeners,而不是使用绑定

工作原理:

  • 设置速率会导致速率无效。这是设置部分的时间,因此也是无效的
  • 依次设置速率不要再次启动InvalizationListener。这只是它的定义方式

上述代码的输出为:

setting rate
rate is invalid
part is invalid
Part: 2500.0
setting part
part is invalid
rate is invalid
Rate: 0.012

如何避免无限通知循环?这不会发生。触发InvalizationListener的定义是:如果变量已经无效,则不要触发。我了解了这一点。查找“但是如果绑定已经无效,则无效侦听器将不会再次触发”是的!此解决方案看起来不错,我将它转换为我自己的道具奥萨尔
public static void main(String[] args) {
    final DoubleProperty amount = new SimpleDoubleProperty(100_000.00);
    final DoubleProperty part = new SimpleDoubleProperty();
    final DoubleProperty rate = new SimpleDoubleProperty();

    part.addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            System.out.println("part is invalid");
            rate.set(part.get() / amount.get());
        }
    });

    rate.addListener(new InvalidationListener() {
        @Override
        public void invalidated(Observable observable) {
            System.out.println("rate is invalid");
            part.set(rate.get() * amount.get());
        }
    });

    System.out.println("setting rate");
    rate.set(0.025);
    System.out.println("Part: " + part.get()); //2500

    System.out.println("setting part");
    part.set(1200);
    System.out.println("Rate: " + rate.get()); //0.012
}
setting rate
rate is invalid
part is invalid
Part: 2500.0
setting part
part is invalid
rate is invalid
Rate: 0.012