- fix SceneExplorer property issues

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10102 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
nor..67 12 years ago
parent f1ee873706
commit 6307a254a4
  1. 43
      sdk/jme3-core/src/com/jme3/gde/core/properties/SceneExplorerProperty.java

@ -61,6 +61,7 @@ import org.openide.util.Mutex;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> { public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
private static final Logger logger = Logger.getLogger(SceneExplorerProperty.class.getName());
public static final String PROP_SCENE_CHANGE = "PROP_SCENE_CHANGE"; public static final String PROP_SCENE_CHANGE = "PROP_SCENE_CHANGE";
public static final String PROP_USER_CHANGE = "PROP_USER_CHANGE"; public static final String PROP_USER_CHANGE = "PROP_USER_CHANGE";
public static final String PROP_INIT_CHANGE = "PROP_INIT_CHANGE"; public static final String PROP_INIT_CHANGE = "PROP_INIT_CHANGE";
@ -108,6 +109,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
} }
//TODO: instantiates editor? //TODO: instantiates editor?
editable = getPropertyEditor() != null; editable = getPropertyEditor() != null;
logger.log(Level.FINE, "Created SceneExplorerProperty for {0}, cloneable = {1}, instantiatable = {2}, primitive = {3}, editable = {4}", new Object[]{valueType, cloneable, instantiable, primitive, editable});
addPropertyChangeListener(listener); addPropertyChangeListener(listener);
} }
@ -123,9 +125,9 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
mutex.postWriteRequest(new Runnable() { mutex.postWriteRequest(new Runnable() {
public void run() { public void run() {
inited = true; inited = true;
T newObject = duplicateObject(realValue);
notifyListeners(PROP_INIT_CHANGE, null, newObject);
objectLocal = duplicateObject(realValue); objectLocal = duplicateObject(realValue);
notifyListeners(PROP_INIT_CHANGE, null, objectLocal);
logger.log(Level.FINE, "Get first sync duplicate for {0}", this);
} }
}); });
} else if ((objectLocal != null) && !objectLocal.equals(realValue)) { } else if ((objectLocal != null) && !objectLocal.equals(realValue)) {
@ -133,16 +135,17 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
public void run() { public void run() {
T oldObject = objectLocal; T oldObject = objectLocal;
T newObject = duplicateObject(realValue); T newObject = duplicateObject(realValue);
notifyListeners(PROP_SCENE_CHANGE, oldObject, newObject);
objectLocal = newObject; objectLocal = newObject;
notifyListeners(PROP_SCENE_CHANGE, oldObject, objectLocal);
logger.log(Level.FINE, "Get update for {0} due to equals check", this);
} }
}); });
} else if ((objectLocal == null) && (realValue != null)) { } else if ((objectLocal == null) && (realValue != null)) {
mutex.postWriteRequest(new Runnable() { mutex.postWriteRequest(new Runnable() {
public void run() { public void run() {
T newObject = duplicateObject(realValue);
notifyListeners(PROP_SCENE_CHANGE, null, newObject);
objectLocal = duplicateObject(realValue); objectLocal = duplicateObject(realValue);
notifyListeners(PROP_SCENE_CHANGE, null, objectLocal);
logger.log(Level.FINE, "Get update for {0} due to change from null", this);
} }
}); });
} }
@ -152,6 +155,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
public T getValue() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { public T getValue() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
return mutex.readAccess(new Mutex.Action<T>() { return mutex.readAccess(new Mutex.Action<T>() {
public T run() { public T run() {
logger.log(Level.FINE, "Return local value of {0}", this);
return objectLocal; return objectLocal;
} }
}); });
@ -161,6 +165,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
public void setValue(final T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void setValue(final T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
mutex.postWriteRequest(new Runnable() { mutex.postWriteRequest(new Runnable() {
public void run() { public void run() {
logger.log(Level.FINE, "Set local value of {0}", this);
final T oldObject = objectLocal; final T oldObject = objectLocal;
objectLocal = val; objectLocal = val;
final T sceneObject = duplicateObject(val); final T sceneObject = duplicateObject(val);
@ -192,13 +197,17 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
try { try {
Class objClass = obj.getClass().getMethod(getter).getReturnType(); Class objClass = obj.getClass().getMethod(getter).getReturnType();
if (Enum.class.isAssignableFrom(objClass)) { if (Enum.class.isAssignableFrom(objClass)) {
logger.log(Level.FINE, "Found enum, not cloneable");
return false; return false;
} }
Method meth = objClass.getMethod("clone"); Method meth = objClass.getMethod("clone");
if (meth != null) { if (meth != null) {
logger.log(Level.FINE, "Found clone method");
if (meth.getParameterTypes().length == 0 if (meth.getParameterTypes().length == 0
&& meth.getReturnType().equals(obj.getClass())) { && meth.getReturnType().isAssignableFrom(objClass)) {
return true; return true;
} else {
logger.log(Level.FINE, "Wrong kind of clone method, parameter size {0}, returnType {1}", new Object[]{meth.getParameterTypes().length, meth.getReturnType()});
} }
} }
} catch (NoSuchMethodException ex) { } catch (NoSuchMethodException ex) {
@ -212,12 +221,13 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
try { try {
Class objClass = obj.getClass().getMethod(getter).getReturnType(); Class objClass = obj.getClass().getMethod(getter).getReturnType();
if (Enum.class.isAssignableFrom(objClass)) { if (Enum.class.isAssignableFrom(objClass)) {
logger.log(Level.FINE, "Found enum, not recreatable");
return false; return false;
} }
Constructor[] constructors = objClass.getConstructors(); Constructor[] constructors = objClass.getConstructors();
for (Constructor constructor : constructors) { for (Constructor constructor : constructors) {
Class[] types = constructor.getParameterTypes(); Class[] types = constructor.getParameterTypes();
if (types.length == 1 && types[0].equals(obj.getClass())) { if (types.length == 1 && types[0].isAssignableFrom(objClass)) {
return true; return true;
} }
} }
@ -230,13 +240,18 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
} }
private T duplicateObject(T a) { private T duplicateObject(T a) {
if (a == null) {
return null;
}
if (primitive) { if (primitive) {
logger.log(Level.FINE, "Returning primitive as duplicate");
return a; return a;
} }
T obj = null; T obj = null;
if (cloneable) { if (cloneable) {
try { try {
obj = (T) a.getClass().getMethod("clone").invoke(a); obj = (T) a.getClass().getMethod("clone").invoke(a);
logger.log(Level.FINE, "Cloned object {0} to {1}", new Object[]{a, obj});
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex); Exceptions.printStackTrace(ex);
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
@ -251,6 +266,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
} else if (instantiable) { } else if (instantiable) {
try { try {
obj = (T) a.getClass().getConstructor(a.getClass()).newInstance(a); obj = (T) a.getClass().getConstructor(a.getClass()).newInstance(a);
logger.log(Level.FINE, "Instantiated new object from {0} to {1}", new Object[]{a, obj});
} catch (InstantiationException ex) { } catch (InstantiationException ex) {
Exceptions.printStackTrace(ex); Exceptions.printStackTrace(ex);
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
@ -266,6 +282,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
} }
} }
if (obj == null) { if (obj == null) {
logger.log(Level.FINE, "Simply returning non-primitive {0} as duplicate", new Object[]{a});
return a; return a;
} }
return obj; return obj;
@ -277,6 +294,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
private T getSuperValue() { private T getSuperValue() {
try { try {
logger.log(Level.FINE, "Get super value of {0} on thread {1}", new Object[]{this, Thread.currentThread().getName()});
return super.getValue(); return super.getValue();
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex); Exceptions.printStackTrace(ex);
@ -291,8 +309,10 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
private void setSuperValue(T val, boolean undo) { private void setSuperValue(T val, boolean undo) {
try { try {
if (undo) { if (undo) {
logger.log(Level.FINE, "Add undo for {0} on thread {1}");
addUndo(duplicateObject(getSuperValue()), val); addUndo(duplicateObject(getSuperValue()), val);
} }
logger.log(Level.FINE, "Set super value of {0} on thread {1}", new Object[]{this, Thread.currentThread().getName()});
super.setValue(val); super.setValue(val);
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
Exceptions.printStackTrace(ex); Exceptions.printStackTrace(ex);
@ -306,20 +326,20 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
protected void addUndo(final Object before, final Object after) { protected void addUndo(final Object before, final Object after) {
SceneUndoRedoManager undoRedo = Lookup.getDefault().lookup(SceneUndoRedoManager.class); SceneUndoRedoManager undoRedo = Lookup.getDefault().lookup(SceneUndoRedoManager.class);
if (undoRedo == null) { if (undoRedo == null) {
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.WARNING, "Cannot access SceneUndoRedoManager"); logger.log(Level.WARNING, "Cannot access SceneUndoRedoManager");
return; return;
} }
undoRedo.addEdit(this, new AbstractUndoableSceneEdit() { undoRedo.addEdit(this, new AbstractUndoableSceneEdit() {
@Override @Override
public void sceneUndo() { public void sceneUndo() {
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.FINE, "Do undo {0}", before); logger.log(Level.FINE, "Do undo {0}", before);
notifyListeners(PROP_USER_CHANGE, after, before); notifyListeners(PROP_USER_CHANGE, after, before);
setSuperValue((T) before, false); setSuperValue((T) before, false);
} }
@Override @Override
public void sceneRedo() { public void sceneRedo() {
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.FINE, "Do redo {0}", before); logger.log(Level.FINE, "Do redo {0}", before);
notifyListeners(PROP_USER_CHANGE, before, after); notifyListeners(PROP_USER_CHANGE, before, after);
setSuperValue((T) after, false); setSuperValue((T) after, false);
} }
@ -336,12 +356,14 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
public void addPropertyChangeListener(ScenePropertyChangeListener listener) { public void addPropertyChangeListener(ScenePropertyChangeListener listener) {
if (listener != null) { if (listener != null) {
logger.log(Level.FINE, "Add property listener {0}", listener);
listeners.add(listener); listeners.add(listener);
} }
} }
public void removePropertyChangeListener(ScenePropertyChangeListener listener) { public void removePropertyChangeListener(ScenePropertyChangeListener listener) {
if (listener != null) { if (listener != null) {
logger.log(Level.FINE, "Remove property listener {0}", listener);
listeners.remove(listener); listeners.remove(listener);
} }
} }
@ -349,6 +371,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
private void notifyListeners(final String type, final Object before, final Object after) { private void notifyListeners(final String type, final Object before, final Object after) {
java.awt.EventQueue.invokeLater(new Runnable() { java.awt.EventQueue.invokeLater(new Runnable() {
public void run() { public void run() {
logger.log(Level.FINE, "Notify SceneExplorer listeners of {0}", this);
for (Iterator<ScenePropertyChangeListener> it = listeners.iterator(); it.hasNext();) { for (Iterator<ScenePropertyChangeListener> it = listeners.iterator(); it.hasNext();) {
ScenePropertyChangeListener propertyChangeListener = it.next(); ScenePropertyChangeListener propertyChangeListener = it.next();
propertyChangeListener.propertyChange(type, getName(), before, after); propertyChangeListener.propertyChange(type, getName(), before, after);

Loading…
Cancel
Save