2017-10-05 60 views
1

我已经调查SOM类和它们的声明和我来arcross封装的一种新的方式,这使得达到一个实例变量的样子野蛮的一个普通的getter/setter方法...JavaFX:暴露ObjectProperty成员而不是getter/setter?

javafx.scene.Scene搜索摄像头,一个javafx.scene.Camera的对象,看看它的封装。

您还可以在这里看到它grepcode.com

这楼下距离的JavaFX Scene类:

private ObjectProperty<Camera> camera; 

public final void setCamera(Camera value) { 
    cameraProperty().set(value); 
} 

public final Camera getCamera() { 
    return camera == null ? null : camera.get(); 
} 

public final ObjectProperty<Camera> cameraProperty() { 
    if (camera == null) { 
     camera = new ObjectPropertyBase<Camera>() { 
      Camera oldCamera = null; 

      @Override 
      protected void invalidated() { 
       Camera _value = get(); 
       if (_value != null) { 
        if (_value instanceof PerspectiveCamera 
          && !Platform.isSupported(ConditionalFeature.SCENE3D)) { 
         String logname = Scene.class.getName(); 
         PlatformLogger.getLogger(logname).warning("System can't support " 
           + "ConditionalFeature.SCENE3D"); 
        } 
        // Illegal value if it belongs to other scene or any subscene 
        if ((_value.getScene() != null && _value.getScene() != Scene.this) 
          || _value.getSubScene() != null) { 
         throw new IllegalArgumentException(_value 
           + "is already part of other scene or subscene"); 
        } 
        // throws exception if the camera already has a different owner 
        _value.setOwnerScene(Scene.this); 
        _value.setViewWidth(getWidth()); 
        _value.setViewHeight(getHeight()); 
       } 
       if (oldCamera != null && oldCamera != _value) { 
        oldCamera.setOwnerScene(null); 
       } 
       oldCamera = _value; 
      } 

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

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

Camera getEffectiveCamera() { 
    final Camera cam = getCamera(); 
    if (cam == null 
      || (cam instanceof PerspectiveCamera 
      && !Platform.isSupported(ConditionalFeature.SCENE3D))) { 
     if (defaultCamera == null) { 
      defaultCamera = new ParallelCamera(); 
      defaultCamera.setOwnerScene(this); 
      defaultCamera.setViewWidth(getWidth()); 
      defaultCamera.setViewHeight(getHeight()); 
     } 
     return defaultCamera; 
    } 

    return cam; 
} 

什么时候应该使用把实例变量里面javafx.beans.property.ObjectProperty<T>和添加的这种方法额外的抽象层,如何或以什么方式有用?

注意:我知道添加监听器到属性的可能性 - 但是还有其他原因吗?

回答

1

你可以在这里看到的是一种延迟初始化的实现。

该属性camera不会被初始化,直到它没有真正被获取。

代码段中没有“额外抽象层”:cameraProperty()公开camera内部样本(并在第一次调用时初始化它)。访问器和增变器方法是cameraProperty().get()cameraProperty().set(...)的简单快捷方式。

同样在这个答案解释: Exposing properties for binding

+0

这岂不是也允许第一套方法调用(初始化)和以后使用一套方法之间的分离(改变实例变量) - 使他们能编码不同?它应该意味着你可以独立地初始化所有的实例变量(而不是具有通用的init方法)。并且谢谢,延迟初始化是有意义的,现在知道术语“延迟初始化”是很好的! – lelelo

+0

唯一的区别是(除了'camera'是一个“特殊”属性 - 这意味着它没有被初始化为'new SimpleObjectProperty()'),这个相机没有在costructor中初始化,但是 - 只有在财产被要求用于任何用途。 – DVarga

+0

如果我仍然会把'cameraProperty.set(value)'放在构造器中,并且我们有三种这样的方法(总共设置了camera1,camera2和camera3)。我正在同时初始化它们 - 但我可以对每个摄像机以不同的方式(内部)'cameraProperty'来完成。我认为这是围绕实例变量放置一个ObjectProperty的另一个好处。替代方案将有独立的初始化方法 - 它似乎没有吸引力,我认为 – lelelo