📄 binding.java
字号:
* on the source property and target property as they will be notified
* by calls to {@link #sourceChangedImpl} and {@link #targetChangedImpl}
* when the source and target properties change respectively.
*
* @see #unbindImpl
*/
protected abstract void bindImpl();
/**
* Unbinds this binding. Removes the {@code PropertyStateListeners}
* added by {@code bind}, calls {@link #unbindImpl} to allow subclasses
* to uninitiate binding, notifies all registered {@code BindingListeners}
* that the binding has become unbound, and fires a property change
* notification to indicate a change to the {@code "bound"} property.
*
* @throws UnsupportedOperationException if the {@code Binding} is managed
* @throws IllegalStateException if the {@code Binding} is not bound
* @see #isBound()
* @see #isManaged()
* @see #bind
*/
public final void unbind() {
throwIfManaged();
unbindUnmanaged();
}
/**
* A protected version of {@link #unbind} that allows managed
* subclasses to unbind without throwing an exception
* for being managed.
*
* @throws IllegalStateException if the {@code Binding} is not bound
* @see #isManaged()
* @see #isBound()
*/
protected final void unbindUnmanaged() {
throwIfUnbound();
sourceProperty.removePropertyStateListener(sourceObject, psl);
targetProperty.removePropertyStateListener(targetObject, psl);
psl = null;
unbindImpl();
isBound = false;
if (listeners != null) {
for (BindingListener listener : listeners) {
listener.bindingBecameUnbound(this);
}
}
firePropertyChange("bound", true, false);
}
/**
* Called by {@link #unbind} to allow subclasses to uninitiate binding.
*
* @see #bindImpl
*/
protected abstract void unbindImpl();
/**
* Returns whether or not this {@code Binding} is bound.
* <p>
* {@code Binding} fires a property change notification with
* property name {@code "bound"} when the value of
* this property changes.
*
* @return whether or not the {@code Binding} is bound
* @see #bind
* @see #unbind
*/
public final boolean isBound() {
return isBound;
}
/**
* Sets whether or not this {@code Binding} is managed. Some
* {@code Bindings} are managed, often by another {@code Binding}.
* A managed {@code Binding} does not allow certain methods to be called by
* the user. These methods are identified in their documentation.
* Subclasses should call {@code setManaged(true)} to make themselves managed.
* {@code Binding} provides protected versions of the managed methods, with the
* suffix {@code "Unmanaged"}, for subclasses to use internally without
* checking whether or not they are managed.
*/
protected final void setManaged(boolean isManaged) {
this.isManaged = isManaged;
}
/**
* Returns whether or not this {@code Binding} is managed. Some
* {@code Bindings} are managed, often by another {@code Binding}.
* A managed {@code Binding} does not allow certain methods to be called by
* the user. These methods are identified in their documentation.
* Subclasses should call {@code setManaged(true)} to make themselves managed.
* {@code Binding} provides protected versions of the managed methods, with the
* suffix {@code "Unmanaged"}, for subclasses to use internally without
* checking whether or not they are managed.
*
* @return whether or not the {@code Binding} is managed
* @see #setManaged
*/
public final boolean isManaged() {
return isManaged;
}
/**
* Notifies all registered {@code BindingListeners} of a successful
* sync ({@code refresh} or {@code save}), by calling {@code synced}
* on each one.
*/
protected final void notifySynced() {
if (listeners == null) {
return;
}
for (BindingListener listener : listeners) {
listener.synced(this);
}
}
/**
* Notifies all registered {@code BindingListeners} of a failure to
* sync ({@code refresh} or {@code save}), by calling
* {@code syncFailed} on each one.
*
* @param failure the reason that the sync failed
*/
protected final void notifySyncFailed(SyncFailure failure) {
if (listeners == null) {
return;
}
for (BindingListener listener : listeners) {
listener.syncFailed(this, failure);
}
}
private final SyncFailure notifyAndReturn(SyncFailure failure) {
if (failure == null) {
notifySynced();
} else {
notifySyncFailed(failure);
}
return failure;
}
/**
* The same as {@link #refresh} with the additional
* behavior of notifying all registered {@code BindingListeners}
* with {@code synced} if {@code refresh} returns {@code null}
* or {@code syncFailed} if {@code refresh} returns a
* {@code SyncFailure}.
*
* @return the return value from the call to {@code refresh}
* @throws UnsupportedOperationException if the {@code Binding} is managed
* @throws RuntimeException as specified by {@link #refresh}
* @throws ClassCastException as specified by {@link #refresh}
* @see #isManaged()
*/
public final SyncFailure refreshAndNotify() {
return notifyAndReturn(refresh());
}
/**
* A protected version of {@link #refreshAndNotify} that allows managed
* subclasses to refresh and notify without throwing an exception
* for being managed.
*
* @return the return value from the call to {@code refresh}
* @throws RuntimeException as specified by {@link #refresh}
* @throws ClassCastException as specified by {@link #refresh}
* @see #isManaged()
*/
protected final SyncFailure refreshAndNotifyUnmanaged() {
return notifyAndReturn(refreshUnmanaged());
}
/**
* The same as {@link #save} with the additional
* behavior of notifying all registered {@code BindingListeners}
* with {@code synced} if {@code save} returns {@code null}
* or {@code syncFailed} if {@code save} returns a
* {@code SyncFailure}.
*
* @return the return value from the call to {@code save}
* @throws UnsupportedOperationException if the {@code Binding} is managed
* @throws ClassCastException as specified by {@link #refresh}
* @see #isManaged()
*/
public final SyncFailure saveAndNotify() {
return notifyAndReturn(save());
}
/**
* A protected version of {@link #saveAndNotify} that allows managed
* subclasses to save and notify without throwing an exception
* for being managed.
*
* @return the return value from the call to {@code save}
* @throws ClassCastException as specified by {@link #save}
* @see #isManaged()
*/
protected final SyncFailure saveAndNotifyUnmanaged() {
return notifyAndReturn(saveUnmanaged());
}
/**
* Fetches the value of the source property for the source object and sets
* it as the value of the target property for the target object.
* First calls {@link #getSourceValueForTarget}. If the return value
* from that method represents a failure, this method returns the failure.
* Otherwise, it calls {@code setValue} on the target property for the
* target object with the value obtained from the source.
*
* @return the reason for failure if the binding could not be refreshed,
* or {@code null} for success
* @throws UnsupportedOperationException if the {@code Binding} is managed
* @throws RuntimeException if thrown by {@link #getSourceValueForTarget}
* @throws ClassCastException if thrown by {@link #getSourceValueForTarget}
* @see #isManaged()
* @see #save
*/
public final SyncFailure refresh() {
throwIfManaged();
return refreshUnmanaged();
}
/**
* A protected version of {@link #refresh} that allows managed
* subclasses to refresh without throwing an exception
* for being managed.
*
* @return the reason for failure if the binding could not be refreshed,
* or {@code null} for success
* @throws RuntimeException if thrown by {@link #getSourceValueForTarget}
* @throws ClassCastException if thrown by {@link #getSourceValueForTarget}
* @see #isManaged()
*/
protected final SyncFailure refreshUnmanaged() {
ValueResult<TV> vr = getSourceValueForTarget();
if (vr.failed()) {
return vr.getFailure();
}
try {
ignoreChange = true;
targetProperty.setValue(targetObject, vr.getValue());
} finally {
ignoreChange = false;
}
return null;
}
/**
* Fetches the value of the target property for the target object and sets
* it as the value of the source property for the source object.
* First calls {@link #getTargetValueForSource}. If the return value
* from that method represents a failure, this method returns the failure.
* Otherwise, it calls {@code setValue} on the source property for the
* source object with the value obtained from the target.
*
* @return the reason for failure if the binding could not be saved,
* or {@code null} for success
* @throws UnsupportedOperationException if the {@code Binding} is managed
* @throws ClassCastException if thrown by {@link #getTargetValueForSource}
* @see #isManaged()
* @see #refresh
*/
public final SyncFailure save() {
throwIfManaged();
return saveUnmanaged();
}
/**
* A protected version of {@link #save} that allows managed
* subclasses to save without throwing an exception
* for being managed.
*
* @return the reason for failure if the binding could not be saved,
* or {@code null} for success
* @throws ClassCastException if thrown by {@link #getTargetValueForSource}
* @see #isManaged()
*/
protected final SyncFailure saveUnmanaged() {
ValueResult<SV> vr = getTargetValueForSource();
if (vr.failed()) {
return vr.getFailure();
}
try {
ignoreChange = true;
sourceProperty.setValue(sourceObject, vr.getValue());
} finally {
ignoreChange = false;
}
return null;
}
private final Class<?> noPrimitiveType(Class<?> klass) {
if (!klass.isPrimitive()) {
return klass;
}
if (klass == Byte.TYPE) {
return Byte.class;
} else if (klass == Short.TYPE) {
return Short.class;
} else if (klass == Integer.TYPE) {
return Integer.class;
} else if (klass == Long.TYPE) {
return Long.class;
} else if (klass == Boolean.TYPE) {
return Boolean.class;
} else if (klass == Character.TYPE) {
return Character.class;
} else if (klass == Float.TYPE) {
return Float.class;
} else if (klass == Double.TYPE) {
return Double.class;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -