com.sun.javafx.property.adapter.PropertyDescriptor Maven / Gradle / Ivy
/*
* Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.javafx.property.adapter;
import com.sun.javafx.property.MethodHelper;
import javafx.beans.property.Property;
import javafx.beans.property.adapter.ReadOnlyJavaBeanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
*/
public class PropertyDescriptor extends ReadOnlyPropertyDescriptor {
private static final String ADD_VETOABLE_LISTENER_METHOD_NAME = "addVetoableChangeListener";
private static final String REMOVE_VETOABLE_LISTENER_METHOD_NAME = "removeVetoableChangeListener";
private static final String ADD_PREFIX = "add";
private static final String REMOVE_PREFIX = "remove";
private static final String SUFFIX = "Listener";
private static final int ADD_VETOABLE_LISTENER_TAKES_NAME = 1;
private static final int REMOVE_VETOABLE_LISTENER_TAKES_NAME = 2;
private final Method setter;
private final Method addVetoListener;
private final Method removeVetoListener;
private final int flags;
public Method getSetter() {return setter;}
public PropertyDescriptor(String propertyName, Class> beanClass, Method getter, Method setter) {
super(propertyName, beanClass, getter);
this.setter = setter;
Method tmpAddVetoListener = null;
Method tmpRemoveVetoListener = null;
int tmpFlags = 0;
// reflect addVetoListenerMethod
final String addMethodName = ADD_PREFIX + capitalizedName(name) + SUFFIX;
try {
tmpAddVetoListener = beanClass.getMethod(addMethodName, VetoableChangeListener.class);
} catch (NoSuchMethodException e) {
try {
tmpAddVetoListener = beanClass.getMethod(ADD_VETOABLE_LISTENER_METHOD_NAME, String.class, VetoableChangeListener.class);
tmpFlags |= ADD_VETOABLE_LISTENER_TAKES_NAME;
} catch (NoSuchMethodException e1) {
try {
tmpAddVetoListener = beanClass.getMethod(ADD_VETOABLE_LISTENER_METHOD_NAME, VetoableChangeListener.class);
} catch (NoSuchMethodException e2) {
// ignore
}
}
}
// reflect removeVetoListenerMethod
final String removeMethodName = REMOVE_PREFIX + capitalizedName(name) + SUFFIX;
try {
tmpRemoveVetoListener = beanClass.getMethod(removeMethodName, VetoableChangeListener.class);
} catch (NoSuchMethodException e) {
try {
tmpRemoveVetoListener = beanClass.getMethod(REMOVE_VETOABLE_LISTENER_METHOD_NAME, String.class, VetoableChangeListener.class);
tmpFlags |= REMOVE_VETOABLE_LISTENER_TAKES_NAME;
} catch (NoSuchMethodException e1) {
try {
tmpRemoveVetoListener = beanClass.getMethod(REMOVE_VETOABLE_LISTENER_METHOD_NAME, VetoableChangeListener.class);
} catch (NoSuchMethodException e2) {
// ignore
}
}
}
addVetoListener = tmpAddVetoListener;
removeVetoListener = tmpRemoveVetoListener;
flags = tmpFlags;
}
@Override
public void addListener(ReadOnlyListener listener) {
super.addListener(listener);
if (addVetoListener != null) {
try {
if ((flags & ADD_VETOABLE_LISTENER_TAKES_NAME) > 0) {
addVetoListener.invoke(listener.getBean(), name, listener);
} else {
addVetoListener.invoke(listener.getBean(), listener);
}
} catch (IllegalAccessException e) {
// ignore
} catch (InvocationTargetException e) {
// ignore
}
}
}
@Override
public void removeListener(ReadOnlyListener listener) {
super.removeListener(listener);
if (removeVetoListener != null) {
try {
if ((flags & REMOVE_VETOABLE_LISTENER_TAKES_NAME) > 0) {
removeVetoListener.invoke(listener.getBean(), name, listener);
} else {
removeVetoListener.invoke(listener.getBean(), listener);
}
} catch (IllegalAccessException e) {
// ignore
} catch (InvocationTargetException e) {
// ignore
}
}
}
public class Listener extends ReadOnlyListener implements ChangeListener, VetoableChangeListener {
private boolean updating;
public Listener(Object bean, ReadOnlyJavaBeanProperty property) {
super(bean, property);
}
@Override
public void changed(ObservableValue extends T> observable, T oldValue, T newValue) {
final ReadOnlyJavaBeanProperty property = checkRef();
if (property == null) {
observable.removeListener(this);
} else if (!updating) {
updating = true;
try {
MethodHelper.invoke(setter, bean, new Object[] {newValue});
property.fireValueChangedEvent();
} catch (IllegalAccessException e) {
// ignore
} catch (InvocationTargetException e) {
// ignore
} finally {
updating = false;
}
}
}
@Override
public void vetoableChange(PropertyChangeEvent propertyChangeEvent) throws PropertyVetoException {
if (bean.equals(propertyChangeEvent.getSource()) && name.equals(propertyChangeEvent.getPropertyName())) {
final ReadOnlyJavaBeanProperty property = checkRef();
if ((property instanceof Property) && (((Property)property).isBound()) && !updating) {
throw new PropertyVetoException("A bound value cannot be set.", propertyChangeEvent);
}
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy