【问题标题】:Exposing properties for binding为绑定公开属性
【发布时间】:2016-09-06 13:09:42
【问题描述】:

属性应该如何暴露?

例如:

class A{
    private ObjectProperty<X> objx;
}

class B{
    private ObjectProperty<X> objy;
}

我们希望将objy 绑定到objx 或从B 添加一个侦听器到objx。只为objx 做一个吸气剂可以吗?或者有没有办法制作一个包装函数来绑定并只公开这个函数?

【问题讨论】:

    标签: java javafx properties


    【解决方案1】:

    standard pattern

    class A {
        private final ObjectProperty<X> objx = new SimpleObjectProperty<>();
    
        public ObjectProperty<X> objxProperty() {
            return objx ;
        }
    
        public final X getObjx() {
            return objxProperty().get();
        }
    
        public final void setObjx(X objx) {
            objxProperty().set(objx);
        }
    }
    

    这里的想法是您有一个属性本身的访问器方法(“属性访问器”:objxProperty()),可用于绑定和注册侦听器,但该属性也显示为常规 Java Bean 为好吧:即有标准的getset 方法。一般约定是您应该始终拥有x.getObjx() == x.objxProperty().get(),这是通过使 Java Bean 访问器方法(getObjx()setObjx)最终确定来强制执行的。

    如果您希望能够在内部修改属性,但只想公开只读属性(其他代码可以绑定到该属性),请使用ReadOnlyObjectWrapper

    class A {
    
        private final ReadOnlyObjectWrapper<X> objx = new ReadOnlyObjectWrapper<>();
    
        public ReadOnlyObjectProperty<X> objxProperty() {
            return objx.getReadOnlyProperty();
        }
    
        public final X getObjx() {
            return objxProperty().get();
        }
    
    }
    

    还可以查看this powerpoint presentation,虽然它很旧,但显示了许多有用的习惯用法,例如属性的延迟初始化和超级延迟初始化。

    【讨论】:

      【解决方案2】:

      JavaFX 中广泛使用以下结构:

      class A {
      
          // Private inner property
          private ObjectProperty<X> objx;
      
          // Public property accessor method
          public final ObjectProperty<X> objxProperty() {
              if (objx == null) 
                  objx = new SimpleObjectProperty<X>(DEFAULT_VALUE);
      
              return objx;
          }
      
          // Public setter method
          public final void setObjx(X val) {
              objxProperty().set(val);
          }
      
          // Public getter method
          public final X getObjx() {return objx == null ? DEFAULT_VALUE : objx.get();}
      
      }
      

      您在此处看到的内容称为lazy initialization。诀窍是私有内部属性在(真正)被请求之前不会被初始化。

      公共属性访问器objxProperty() 将初始化私有内部属性objx。此属性访问器方法用于公开内部属性以进行绑定和侦听。私有内部属性获取“Property”后缀,可以认为是JavaFX中的约定。

      公共的setter方法setObjx使用了这个属性访问器方法,所以如果请求设置这个属性的值,内部属性会被初始化。

      在public gettergetObjx()的情况下有点不同,好像内部属性还没有初始化(对属性没有直接访问请求,之前也没有set请求),不初始化直接返回默认值内部属性,进一步延迟初始化例程。

      您可以在 JavaFX 中的 alignmentPropertyTextField 的情况下看到这种技术。

      如果你不想把事情复杂化,James_D在他的回答中解释的“标准模式”真的是标准(方法命名和这里一样)。

      【讨论】:

      • 对不起,我看错了。我认为 objxProperty() 是一个构造函数。你的代码没问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-13
      • 1970-01-01
      相关资源
      最近更新 更多