SDK:
- MAJOR overhaul of the SceneExplorer node updates, updates are no longer blocking or reading from another thread - Some issues with enums still - simplified, improved and more versatile SceneExplorerProperty class git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10083 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
f77b953fff
commit
81a08d6c49
@ -113,10 +113,13 @@ public class AppStateNode extends AbstractNode implements ScenePropertyChangeLis
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws IOException {
|
public void destroy() throws IOException {
|
||||||
|
AppStateManagerNode parentNode = (AppStateManagerNode) getParentNode();
|
||||||
super.destroy();
|
super.destroy();
|
||||||
parent.detach(appState);
|
parent.detach(appState);
|
||||||
//TODO:hack
|
//TODO:hack
|
||||||
((AppStateManagerNode) getParentNode()).refresh();
|
if (parentNode != null) {
|
||||||
|
parentNode.refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -130,12 +133,6 @@ public class AppStateNode extends AbstractNode implements ScenePropertyChangeLis
|
|||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sheet.Set set2 = Sheet.createPropertiesSet();
|
|
||||||
// set2.setDisplayName("AppStateMethods");
|
|
||||||
// set2.setName(appState.getClass().getName() + ".hack");
|
|
||||||
// createMethods(appState.getClass(), set2, obj);
|
|
||||||
// sheet.put(set2);
|
|
||||||
|
|
||||||
Sheet.Set set = Sheet.createPropertiesSet();
|
Sheet.Set set = Sheet.createPropertiesSet();
|
||||||
set.setDisplayName("AppState");
|
set.setDisplayName("AppState");
|
||||||
set.setName(appState.getClass().getName());
|
set.setName(appState.getClass().getName());
|
||||||
@ -148,7 +145,6 @@ public class AppStateNode extends AbstractNode implements ScenePropertyChangeLis
|
|||||||
protected Property<?> makeProperty(Object obj, Class returntype, String method, String name) {
|
protected Property<?> makeProperty(Object obj, Class returntype, String method, String name) {
|
||||||
Property<?> prop = null;
|
Property<?> prop = null;
|
||||||
try {
|
try {
|
||||||
//getExplorerObjectClass().cast(obj)
|
|
||||||
prop = new SceneExplorerProperty(appState.getClass().cast(obj), returntype, method, null, this);
|
prop = new SceneExplorerProperty(appState.getClass().cast(obj), returntype, method, null, this);
|
||||||
prop.setName(name);
|
prop.setName(name);
|
||||||
} catch (NoSuchMethodException ex) {
|
} catch (NoSuchMethodException ex) {
|
||||||
@ -186,6 +182,13 @@ public class AppStateNode extends AbstractNode implements ScenePropertyChangeLis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void propertyChange(String property, Object oldValue, Object newValue) {
|
public void propertyChange(final String type, final String name, final Object before, final Object after) {
|
||||||
|
if (SceneExplorerProperty.PROP_USER_CHANGE.equals(type)) {
|
||||||
|
firePropertyChange(name, before, after);
|
||||||
|
} else if (SceneExplorerProperty.PROP_SCENE_CHANGE.equals(type)) {
|
||||||
|
firePropertyChange(name, before, after);
|
||||||
|
} else if (SceneExplorerProperty.PROP_INIT_CHANGE.equals(type)) {
|
||||||
|
firePropertyChange(name, before, after);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public class EnableFiterAction implements ActionListener {
|
|||||||
Filter filter=context.getFilter();
|
Filter filter=context.getFilter();
|
||||||
filter.setEnabled(!filter.isEnabled());
|
filter.setEnabled(!filter.isEnabled());
|
||||||
Logger.getLogger(EnableFiterAction.class.getName()).info( (filter.isEnabled()?"Enabled":"Disabled")+" "+filter.getName());
|
Logger.getLogger(EnableFiterAction.class.getName()).info( (filter.isEnabled()?"Enabled":"Disabled")+" "+filter.getName());
|
||||||
context.propertyChange("Enabled", !filter.isEnabled(), filter.isEnabled());
|
context.propertyChange("PROP_USER_CHANGE", "Enabled", !filter.isEnabled(), filter.isEnabled());
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package com.jme3.gde.core.navigator;
|
|
||||||
|
|
||||||
import com.jme3.app.state.AbstractAppState;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author normenhansen
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
public class DataScanner extends AbstractAppState{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(float tpf) {
|
|
||||||
super.update(tpf);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2010 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.jme3.gde.core.navigator;
|
|
||||||
|
|
||||||
import com.jme3.gde.core.properties.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author normenhansen
|
|
||||||
*/
|
|
||||||
public interface SceneChangeListener {
|
|
||||||
public void propertyChange(String property, Object oldValue, Object newValue);
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2010 jMonkeyEngine
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are
|
|
||||||
* met:
|
|
||||||
*
|
|
||||||
* * Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
*
|
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
||||||
* may be used to endorse or promote products derived from this software
|
|
||||||
* without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
||||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
package com.jme3.gde.core.navigator;
|
|
||||||
|
|
||||||
import org.openide.nodes.PropertySupport;
|
|
||||||
import org.openide.util.Lookup;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author normenhansen
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public class SceneProperty<T> extends PropertySupport.Reflection<T> {
|
|
||||||
|
|
||||||
Lookup lookup;
|
|
||||||
Object _originalValue;
|
|
||||||
|
|
||||||
public SceneProperty(Lookup lookup, Object instance, Class<T> valueType, String property) throws NoSuchMethodException {
|
|
||||||
super(instance, valueType, property);
|
|
||||||
DataScanner scanner = lookup.lookup(DataScanner.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -85,7 +85,7 @@ public class AudioTrackProperty extends PropertySupport.ReadWrite<AudioNode> {
|
|||||||
private void notifyListeners(Object before, Object after) {
|
private void notifyListeners(Object before, Object after) {
|
||||||
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(getName(), before, after);
|
propertyChangeListener.propertyChange("PROP_USER_CHANGE", getName(), before, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ public class EffectTrackEmitterProperty extends PropertySupport.ReadWrite<Partic
|
|||||||
private void notifyListeners(Object before, Object after) {
|
private void notifyListeners(Object before, Object after) {
|
||||||
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(getName(), before, after);
|
propertyChangeListener.propertyChange("PROP_USER_CHANGE", getName(), before, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public class ParticleInfluencerProperty extends PropertySupport.ReadWrite<Partic
|
|||||||
private void notifyListeners(Object before, Object after) {
|
private void notifyListeners(Object before, Object after) {
|
||||||
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(getName(), before, after);
|
propertyChangeListener.propertyChange("PROP_USER_CHANGE", getName(), before, after);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -41,16 +41,18 @@ import com.jme3.math.Matrix3f;
|
|||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.openide.nodes.PropertySupport;
|
import org.openide.nodes.PropertySupport;
|
||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
|
import org.openide.util.Mutex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -59,6 +61,16 @@ import org.openide.util.Lookup;
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
||||||
|
|
||||||
|
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_INIT_CHANGE = "PROP_INIT_CHANGE";
|
||||||
|
private T objectLocal;
|
||||||
|
private final boolean cloneable;
|
||||||
|
private final boolean instantiable;
|
||||||
|
private final boolean primitive;
|
||||||
|
private final Mutex mutex = new Mutex();
|
||||||
|
private boolean inited = false;
|
||||||
|
private final boolean editable;
|
||||||
protected LinkedList<ScenePropertyChangeListener> listeners = new LinkedList<ScenePropertyChangeListener>();
|
protected LinkedList<ScenePropertyChangeListener> listeners = new LinkedList<ScenePropertyChangeListener>();
|
||||||
|
|
||||||
public SceneExplorerProperty(T instance, Class valueType, String getter, String setter) throws NoSuchMethodException {
|
public SceneExplorerProperty(T instance, Class valueType, String getter, String setter) throws NoSuchMethodException {
|
||||||
@ -67,7 +79,14 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
|
|
||||||
public SceneExplorerProperty(T instance, Class valueType, String getter, String setter, ScenePropertyChangeListener listener) throws NoSuchMethodException {
|
public SceneExplorerProperty(T instance, Class valueType, String getter, String setter, ScenePropertyChangeListener listener) throws NoSuchMethodException {
|
||||||
super(instance, valueType, getter, setter);
|
super(instance, valueType, getter, setter);
|
||||||
addPropertyChangeListener(listener);
|
primitive = isPrimitive(instance, getter);
|
||||||
|
if (!primitive) {
|
||||||
|
cloneable = canClone(instance, getter);
|
||||||
|
instantiable = canRecreate(instance, getter);
|
||||||
|
} else {
|
||||||
|
cloneable = false;
|
||||||
|
instantiable = false;
|
||||||
|
}
|
||||||
if (valueType == Vector3f.class) {
|
if (valueType == Vector3f.class) {
|
||||||
setPropertyEditorClass(Vector3fPropertyEditor.class);
|
setPropertyEditorClass(Vector3fPropertyEditor.class);
|
||||||
} else if (valueType == Quaternion.class) {
|
} else if (valueType == Quaternion.class) {
|
||||||
@ -87,24 +106,152 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
for (SceneExplorerPropertyEditor di : Lookup.getDefault().lookupAll(SceneExplorerPropertyEditor.class)) {
|
for (SceneExplorerPropertyEditor di : Lookup.getDefault().lookupAll(SceneExplorerPropertyEditor.class)) {
|
||||||
di.setEditor(valueType, this);
|
di.setEditor(valueType, this);
|
||||||
}
|
}
|
||||||
|
//TODO: instantiates editor?
|
||||||
|
editable = getPropertyEditor() != null;
|
||||||
|
addPropertyChangeListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* synchronizes the local and scene value
|
||||||
|
*/
|
||||||
|
public void syncValue() {
|
||||||
|
if (!editable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mutex.postWriteRequest(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
T realValue = getSuperValue();
|
||||||
|
if (objectLocal == null && !inited) {
|
||||||
|
inited = true;
|
||||||
|
objectLocal = duplicateObject(realValue);
|
||||||
|
notifyListeners(PROP_INIT_CHANGE, null, objectLocal);
|
||||||
|
} else if (objectLocal != null && !objectLocal.equals(realValue)) {
|
||||||
|
T oldObject = objectLocal;
|
||||||
|
T newObject = duplicateObject(realValue);
|
||||||
|
notifyListeners(PROP_SCENE_CHANGE, oldObject, newObject);
|
||||||
|
objectLocal = newObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getValue() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
public T getValue() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
return super.getValue();
|
return objectLocal;
|
||||||
// try {
|
}
|
||||||
// return SceneApplication.getApplication().enqueue(new Callable<T>() {
|
|
||||||
//
|
@Override
|
||||||
// public T call() throws Exception {
|
public void setValue(final T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
// return getSuperValue();
|
mutex.postWriteRequest(new Runnable() {
|
||||||
// }
|
public void run() {
|
||||||
// }).get();
|
final T oldObject = (T) objectLocal;
|
||||||
// } catch (InterruptedException ex) {
|
objectLocal = val;
|
||||||
// Exceptions.printStackTrace(ex);
|
final T sceneObject = (T) duplicateObject(val);
|
||||||
// } catch (ExecutionException ex) {
|
notifyListeners(PROP_USER_CHANGE, oldObject, objectLocal);
|
||||||
// Exceptions.printStackTrace(ex);
|
SceneApplication.getApplication().enqueue(new Callable<Void>() {
|
||||||
// }
|
public Void call() throws Exception {
|
||||||
// return null;
|
setSuperValue(sceneObject);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPrimitive(Object obj, String getter) {
|
||||||
|
try {
|
||||||
|
Class objClass = obj.getClass().getMethod(getter).getReturnType();
|
||||||
|
if (objClass.isPrimitive()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canClone(Object obj, String getter) {
|
||||||
|
try {
|
||||||
|
Class objClass = obj.getClass().getMethod(getter).getReturnType();
|
||||||
|
if (Enum.class.isAssignableFrom(objClass)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Method meth = objClass.getMethod("clone");
|
||||||
|
if (meth != null) {
|
||||||
|
if (meth.getParameterTypes().length == 0
|
||||||
|
&& meth.getReturnType().equals(obj.getClass())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canRecreate(Object obj, String getter) {
|
||||||
|
try {
|
||||||
|
Class objClass = obj.getClass().getMethod(getter).getReturnType();
|
||||||
|
if (Enum.class.isAssignableFrom(objClass)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Constructor[] constructors = objClass.getConstructors();
|
||||||
|
for (Constructor constructor : constructors) {
|
||||||
|
Class[] types = constructor.getParameterTypes();
|
||||||
|
if (types.length == 1 && types[0].equals(obj.getClass())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private T duplicateObject(T a) {
|
||||||
|
T obj = a;
|
||||||
|
if (primitive) {
|
||||||
|
return obj;
|
||||||
|
} else if (cloneable) {
|
||||||
|
try {
|
||||||
|
obj = (T) a.getClass().getMethod("clone").invoke(a);
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
} else if (instantiable) {
|
||||||
|
try {
|
||||||
|
obj = (T) a.getClass().getConstructor(a.getClass()).newInstance(a);
|
||||||
|
} catch (InstantiationException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (IllegalAccessException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (InvocationTargetException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (NoSuchMethodException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
} catch (SecurityException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSuperValue(T val) {
|
||||||
|
setSuperValue(val, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private T getSuperValue() {
|
private T getSuperValue() {
|
||||||
@ -120,37 +267,10 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setValue(final T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
|
||||||
try {
|
|
||||||
notifyListeners(getSuperValue(), val);
|
|
||||||
SceneApplication.getApplication().enqueue(new Callable<Void>() {
|
|
||||||
|
|
||||||
public Void call() throws Exception {
|
|
||||||
setSuperValue(val);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}).get();
|
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
Exceptions.printStackTrace(ex);
|
|
||||||
} catch (ExecutionException ex) {
|
|
||||||
Exceptions.printStackTrace(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSuperValue(T val, boolean undo) {
|
private void setSuperValue(T val, boolean undo) {
|
||||||
try {
|
try {
|
||||||
if (undo) {
|
if (undo) {
|
||||||
try {
|
addUndo(duplicateObject(getSuperValue()), val);
|
||||||
Object oldValue = getSuperValue();
|
|
||||||
if (oldValue.getClass().getMethod("clone") != null) {
|
|
||||||
addUndo(oldValue.getClass().getMethod("clone").invoke(oldValue), val);
|
|
||||||
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.INFO, "Add cloned undo {0}", oldValue.getClass().getMethod("clone").invoke(oldValue));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
addUndo(getSuperValue(), val);
|
|
||||||
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.INFO, "Add undo {0}", getSuperValue());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.setValue(val);
|
super.setValue(val);
|
||||||
} catch (IllegalAccessException ex) {
|
} catch (IllegalAccessException ex) {
|
||||||
@ -162,10 +282,6 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSuperValue(T val) {
|
|
||||||
setSuperValue(val, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
||||||
@ -173,15 +289,17 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
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.INFO, "Do undo {0}", before);
|
Logger.getLogger(SceneExplorerProperty.class.getName()).log(Level.FINE, "Do undo {0}", 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);
|
||||||
|
notifyListeners(PROP_USER_CHANGE, before, after);
|
||||||
setSuperValue((T) after, false);
|
setSuperValue((T) after, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,17 +314,25 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addPropertyChangeListener(ScenePropertyChangeListener listener) {
|
public void addPropertyChangeListener(ScenePropertyChangeListener listener) {
|
||||||
|
if (listener != null) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void removePropertyChangeListener(ScenePropertyChangeListener listener) {
|
public void removePropertyChangeListener(ScenePropertyChangeListener listener) {
|
||||||
|
if (listener != null) {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void notifyListeners(Object before, Object after) {
|
private void notifyListeners(final String type, final Object before, final Object after) {
|
||||||
|
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
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(getName(), before, after);
|
propertyChangeListener.propertyChange(type, getName(), before, after);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,5 +37,5 @@ package com.jme3.gde.core.properties;
|
|||||||
* @author normenhansen
|
* @author normenhansen
|
||||||
*/
|
*/
|
||||||
public interface ScenePropertyChangeListener {
|
public interface ScenePropertyChangeListener {
|
||||||
public void propertyChange(String property, Object oldValue, Object newValue);
|
public void propertyChange(String type, String name, Object oldValue, Object newValue);
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ public class UserDataProperty extends PropertySupport.ReadWrite<String> {
|
|||||||
private void notifyListeners(Object before, Object after) {
|
private void notifyListeners(Object before, Object after) {
|
||||||
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(getName(), before, after);
|
propertyChangeListener.propertyChange("PROP_USER_CHANGE", getName(), before, after);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,6 +83,13 @@ public class FakeApplication extends SimpleApplication {
|
|||||||
private FakeAppStateManager appStateManager;
|
private FakeAppStateManager appStateManager;
|
||||||
private FakeRenderManager renderManager;
|
private FakeRenderManager renderManager;
|
||||||
|
|
||||||
|
public FakeApplication(Node guiNode, AssetManager assetManager, Camera cam) {
|
||||||
|
this.guiNode = guiNode;
|
||||||
|
this.assetManager = assetManager;
|
||||||
|
this.cam = cam;
|
||||||
|
this.appStateManager = new FakeAppStateManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
public FakeApplication(Node rootNode, Node guiNode, AssetManager assetManager, Camera cam) {
|
public FakeApplication(Node rootNode, Node guiNode, AssetManager assetManager, Camera cam) {
|
||||||
this.rootNode = rootNode;
|
this.rootNode = rootNode;
|
||||||
this.guiNode = guiNode;
|
this.guiNode = guiNode;
|
||||||
@ -385,6 +392,10 @@ public class FakeApplication extends SimpleApplication {
|
|||||||
*/
|
*/
|
||||||
private ScheduledThreadPoolExecutor fakeAppThread = new ScheduledThreadPoolExecutor(1);
|
private ScheduledThreadPoolExecutor fakeAppThread = new ScheduledThreadPoolExecutor(1);
|
||||||
|
|
||||||
|
public void setRootNode(Node rootNode) {
|
||||||
|
this.rootNode = rootNode;
|
||||||
|
}
|
||||||
|
|
||||||
public void stopFakeApp() {
|
public void stopFakeApp() {
|
||||||
fakeAppThread.shutdown();
|
fakeAppThread.shutdown();
|
||||||
}
|
}
|
||||||
|
125
sdk/jme3-core/src/com/jme3/gde/core/scene/NodeSyncAppState.java
Normal file
125
sdk/jme3-core/src/com/jme3/gde/core/scene/NodeSyncAppState.java
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2012 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.gde.core.scene;
|
||||||
|
|
||||||
|
import com.jme3.app.Application;
|
||||||
|
import com.jme3.app.state.AbstractAppState;
|
||||||
|
import com.jme3.app.state.AppStateManager;
|
||||||
|
import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.openide.util.Lookup.Result;
|
||||||
|
import org.openide.util.LookupEvent;
|
||||||
|
import org.openide.util.LookupListener;
|
||||||
|
import org.openide.util.Utilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author normenhansen
|
||||||
|
*/
|
||||||
|
public class NodeSyncAppState extends AbstractAppState implements LookupListener {
|
||||||
|
|
||||||
|
private final List<AbstractSceneExplorerNode> newNodes = Collections.synchronizedList(new LinkedList<AbstractSceneExplorerNode>());
|
||||||
|
private final List<AbstractSceneExplorerNode> oldNodes = Collections.synchronizedList(new LinkedList<AbstractSceneExplorerNode>());
|
||||||
|
private final Result<AbstractSceneExplorerNode> nodeSelectionResult;
|
||||||
|
private AbstractSceneExplorerNode node;
|
||||||
|
private float timeStep = 1;
|
||||||
|
private float timer = 0;
|
||||||
|
|
||||||
|
public NodeSyncAppState() {
|
||||||
|
nodeSelectionResult = Utilities.actionsGlobalContext().lookupResult(AbstractSceneExplorerNode.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(AppStateManager stateManager, Application app) {
|
||||||
|
super.initialize(stateManager, app);
|
||||||
|
nodeSelectionResult.addLookupListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float tpf) {
|
||||||
|
super.update(tpf);
|
||||||
|
synchronized (newNodes) {
|
||||||
|
for (Iterator<AbstractSceneExplorerNode> it = newNodes.iterator(); it.hasNext();) {
|
||||||
|
AbstractSceneExplorerNode abstractSceneExplorerNode = it.next();
|
||||||
|
abstractSceneExplorerNode.syncSceneData();
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timer += tpf;
|
||||||
|
if (timer > timeStep) {
|
||||||
|
timer = 0;
|
||||||
|
AbstractSceneExplorerNode node = this.node;
|
||||||
|
if (initialized && node != null) {
|
||||||
|
node.syncSceneData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (oldNodes) {
|
||||||
|
for (Iterator<AbstractSceneExplorerNode> it = oldNodes.iterator(); it.hasNext();) {
|
||||||
|
AbstractSceneExplorerNode abstractSceneExplorerNode = it.next();
|
||||||
|
abstractSceneExplorerNode.syncSceneData();
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resultChanged(LookupEvent ev) {
|
||||||
|
Collection collection = nodeSelectionResult.allInstances();
|
||||||
|
AbstractSceneExplorerNode newNode = null;
|
||||||
|
for (Iterator it = collection.iterator(); it.hasNext();) {
|
||||||
|
Object object = it.next();
|
||||||
|
if (object instanceof AbstractSceneExplorerNode) {
|
||||||
|
if (object != null) {
|
||||||
|
synchronized (newNodes) {
|
||||||
|
newNodes.add((AbstractSceneExplorerNode) object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newNode = (AbstractSceneExplorerNode) object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node != null) {
|
||||||
|
synchronized (oldNodes) {
|
||||||
|
oldNodes.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cleanup() {
|
||||||
|
nodeSelectionResult.removeLookupListener(this);
|
||||||
|
super.cleanup();
|
||||||
|
}
|
||||||
|
}
|
@ -116,6 +116,7 @@ public class SceneApplication extends Application implements LookupProvider {
|
|||||||
boolean useCanvas = false;
|
boolean useCanvas = false;
|
||||||
private BulletAppState physicsState;
|
private BulletAppState physicsState;
|
||||||
private Thread thread;
|
private Thread thread;
|
||||||
|
private NodeSyncAppState nodeSync;
|
||||||
private FakeApplication fakeApp;
|
private FakeApplication fakeApp;
|
||||||
|
|
||||||
public SceneApplication() {
|
public SceneApplication() {
|
||||||
@ -140,6 +141,8 @@ public class SceneApplication extends Application implements LookupProvider {
|
|||||||
createCanvas();
|
createCanvas();
|
||||||
startCanvas(true);
|
startCanvas(true);
|
||||||
}
|
}
|
||||||
|
nodeSync = new NodeSyncAppState();
|
||||||
|
stateManager.attach(nodeSync);
|
||||||
progressHandle.progress("initialize Base Application", 1);
|
progressHandle.progress("initialize Base Application", 1);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
getProgressHandle().finish();
|
getProgressHandle().finish();
|
||||||
@ -375,6 +378,7 @@ public class SceneApplication extends Application implements LookupProvider {
|
|||||||
} else {
|
} else {
|
||||||
camController.disable();
|
camController.disable();
|
||||||
}
|
}
|
||||||
|
//TODO: reuse fakeapp
|
||||||
fakeApp = new FakeApplication(rootNode, guiNode, request.getManager(), cam);
|
fakeApp = new FakeApplication(rootNode, guiNode, request.getManager(), cam);
|
||||||
request.setFakeApp(fakeApp);
|
request.setFakeApp(fakeApp);
|
||||||
enqueue(new Callable() {
|
enqueue(new Callable() {
|
||||||
@ -387,6 +391,13 @@ public class SceneApplication extends Application implements LookupProvider {
|
|||||||
StatusDisplayer.getDefault().setStatusText("could not load Spatial from request: " + getCurrentSceneRequest().getWindowTitle());
|
StatusDisplayer.getDefault().setStatusText("could not load Spatial from request: " + getCurrentSceneRequest().getWindowTitle());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
//TODO: bit dangerous, setting rootNode late
|
||||||
|
// still it should only be accessed from the
|
||||||
|
// update loop and be set until then.
|
||||||
|
|
||||||
|
if (model instanceof Node) {
|
||||||
|
fakeApp.setRootNode((Node) model);
|
||||||
|
}
|
||||||
rootNode.attachChild(model);
|
rootNode.attachChild(model);
|
||||||
if (request.getToolNode() != null) {
|
if (request.getToolNode() != null) {
|
||||||
toolsNode.attachChild(request.getToolNode());
|
toolsNode.attachChild(request.getToolNode());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.1" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
<Form version="1.4" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||||
<AuxValues>
|
<AuxValues>
|
||||||
@ -40,6 +40,7 @@
|
|||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JToolBar" name="jToolBar1">
|
<Container class="javax.swing.JToolBar" name="jToolBar1">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
<Property name="floatable" type="boolean" value="false"/>
|
||||||
<Property name="rollover" type="boolean" value="true"/>
|
<Property name="rollover" type="boolean" value="true"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
|
|
||||||
|
@ -118,6 +118,7 @@ public final class SceneExplorerTopComponent extends TopComponent implements Exp
|
|||||||
jToolBar1 = new javax.swing.JToolBar();
|
jToolBar1 = new javax.swing.JToolBar();
|
||||||
jButton1 = new javax.swing.JButton();
|
jButton1 = new javax.swing.JButton();
|
||||||
|
|
||||||
|
jToolBar1.setFloatable(false);
|
||||||
jToolBar1.setRollover(true);
|
jToolBar1.setRollover(true);
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(SceneExplorerTopComponent.class, "SceneExplorerTopComponent.jButton1.text")); // NOI18N
|
org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(SceneExplorerTopComponent.class, "SceneExplorerTopComponent.jButton1.text")); // NOI18N
|
||||||
|
@ -31,18 +31,19 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.gde.core.sceneexplorer.nodes;
|
package com.jme3.gde.core.sceneexplorer.nodes;
|
||||||
|
|
||||||
import com.jme3.gde.core.util.DynamicLookup;
|
|
||||||
import com.jme3.gde.core.properties.SceneExplorerProperty;
|
import com.jme3.gde.core.properties.SceneExplorerProperty;
|
||||||
import com.jme3.gde.core.properties.ScenePropertyChangeListener;
|
import com.jme3.gde.core.properties.ScenePropertyChangeListener;
|
||||||
|
import com.jme3.gde.core.util.DynamicLookup;
|
||||||
import com.jme3.gde.core.util.PropertyUtils;
|
import com.jme3.gde.core.util.PropertyUtils;
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import org.openide.loaders.DataObject;
|
import org.openide.loaders.DataObject;
|
||||||
import org.openide.nodes.AbstractNode;
|
import org.openide.nodes.AbstractNode;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.NodeAdapter;
|
|
||||||
import org.openide.nodes.NodeListener;
|
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.util.Lookup;
|
import org.openide.util.Lookup;
|
||||||
@ -60,6 +61,7 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
protected final InstanceContent lookupContents;
|
protected final InstanceContent lookupContents;
|
||||||
protected boolean readOnly = false;
|
protected boolean readOnly = false;
|
||||||
protected DataObject dataObject;
|
protected DataObject dataObject;
|
||||||
|
private final List<Property> sceneProperties = Collections.synchronizedList(new LinkedList<Property>());
|
||||||
|
|
||||||
public AbstractSceneExplorerNode() {
|
public AbstractSceneExplorerNode() {
|
||||||
super(Children.LEAF, new DynamicLookup(new InstanceContent()));
|
super(Children.LEAF, new DynamicLookup(new InstanceContent()));
|
||||||
@ -108,7 +110,7 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the PropertySet with the given name (mostly Class.name)
|
* returns the PropertySet with the given name
|
||||||
* @param name
|
* @param name
|
||||||
* @return The PropertySet or null if no PropertySet by that name exists
|
* @return The PropertySet or null if no PropertySet by that name exists
|
||||||
*/
|
*/
|
||||||
@ -168,7 +170,7 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Property makeEmbedProperty(Object obj,Class objectClass, Class returntype, String method, String setter, String name) {
|
protected Property makeEmbedProperty(Object obj, Class objectClass, Class returntype, String method, String setter, String name) {
|
||||||
Property prop = null;
|
Property prop = null;
|
||||||
try {
|
try {
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
@ -184,7 +186,6 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
return prop;
|
return prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void createFields(Class c, Sheet.Set set, Object obj) throws SecurityException {
|
protected void createFields(Class c, Sheet.Set set, Object obj) throws SecurityException {
|
||||||
for (Field field : c.getDeclaredFields()) {
|
for (Field field : c.getDeclaredFields()) {
|
||||||
PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(c, field);
|
PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(c, field);
|
||||||
@ -194,9 +195,32 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void propertyChange(final String name, final Object before, final Object after) {
|
@Override
|
||||||
|
protected Sheet createSheet() {
|
||||||
|
return Sheet.createDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void syncSceneData() {
|
||||||
|
//TODO: precache structure to avoid locks?
|
||||||
|
for (PropertySet propertySet : getPropertySets()) {
|
||||||
|
for (Property<?> property : propertySet.getProperties()) {
|
||||||
|
if(property instanceof SceneExplorerProperty){
|
||||||
|
SceneExplorerProperty prop = (SceneExplorerProperty)property;
|
||||||
|
prop.syncValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void propertyChange(final String type, final String name, final Object before, final Object after) {
|
||||||
|
if (SceneExplorerProperty.PROP_USER_CHANGE.equals(type)) {
|
||||||
fireSave(true);
|
fireSave(true);
|
||||||
firePropertyChange(name, before, after);
|
firePropertyChange(name, before, after);
|
||||||
|
} else if (SceneExplorerProperty.PROP_SCENE_CHANGE.equals(type)) {
|
||||||
|
firePropertyChange(name, before, after);
|
||||||
|
} else if (SceneExplorerProperty.PROP_INIT_CHANGE.equals(type)) {
|
||||||
|
firePropertyChange(name, before, after);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getExplorerNodeClass() {
|
public Class getExplorerNodeClass() {
|
||||||
@ -208,5 +232,4 @@ public abstract class AbstractSceneExplorerNode extends AbstractNode implements
|
|||||||
public Node[] createNodes(Object key, DataObject dataObject, boolean readOnly) {
|
public Node[] createNodes(Object key, DataObject dataObject, boolean readOnly) {
|
||||||
return new Node[]{Node.EMPTY};
|
return new Node[]{Node.EMPTY};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,6 @@ public class JmeGenericControl extends AbstractNode implements ScenePropertyChan
|
|||||||
final Spatial spat = getParentNode().getLookup().lookup(Spatial.class);
|
final Spatial spat = getParentNode().getLookup().lookup(Spatial.class);
|
||||||
try {
|
try {
|
||||||
SceneApplication.getApplication().enqueue(new Callable<Void>() {
|
SceneApplication.getApplication().enqueue(new Callable<Void>() {
|
||||||
|
|
||||||
public Void call() throws Exception {
|
public Void call() throws Exception {
|
||||||
spat.removeControl(control);
|
spat.removeControl(control);
|
||||||
return null;
|
return null;
|
||||||
@ -180,8 +179,10 @@ public class JmeGenericControl extends AbstractNode implements ScenePropertyChan
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void propertyChange(String property, Object oldValue, Object newValue) {
|
public void propertyChange(String type, String name, Object oldValue, Object newValue) {
|
||||||
|
if (type.equals("PROP_USER_CHANGE")) {
|
||||||
dobject.setModified(true);
|
dobject.setModified(true);
|
||||||
|
}
|
||||||
// throw new UnsupportedOperationException("Not supported yet.");
|
// throw new UnsupportedOperationException("Not supported yet.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ import java.awt.Image;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import org.openide.loaders.DataObject;
|
import org.openide.loaders.DataObject;
|
||||||
import org.openide.nodes.AbstractNode;
|
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
import org.openide.util.ImageUtilities;
|
import org.openide.util.ImageUtilities;
|
||||||
|
|
||||||
@ -144,8 +143,8 @@ public class JmeGeometry extends JmeSpatial implements MaterialChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(String name, final Object before, final Object after) {
|
public void propertyChange(String type, String name, final Object before, final Object after) {
|
||||||
super.propertyChange(name, before, after);
|
super.propertyChange(type, name, before, after);
|
||||||
if (name.equals("Material")) {
|
if (name.equals("Material")) {
|
||||||
java.awt.EventQueue.invokeLater(new Runnable() {
|
java.awt.EventQueue.invokeLater(new Runnable() {
|
||||||
|
|
||||||
|
@ -154,8 +154,8 @@ public class JmeParticleEmitter extends JmeGeometry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(String name, Object before, Object after) {
|
public void propertyChange(String type, String name, Object before, Object after) {
|
||||||
super.propertyChange(name, before, after);
|
super.propertyChange(type, name, before, after);
|
||||||
if (!name.equals("Emit all particles")) {
|
if (!name.equals("Emit all particles")) {
|
||||||
fireSave(true);
|
fireSave(true);
|
||||||
firePropertyChange(name, before, after);
|
firePropertyChange(name, before, after);
|
||||||
|
@ -294,7 +294,7 @@ public class JmeSpatial extends AbstractSceneExplorerNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Sheet createSheet() {
|
protected Sheet createSheet() {
|
||||||
Sheet sheet = Sheet.createDefault();
|
Sheet sheet = super.createSheet();
|
||||||
|
|
||||||
//TODO: multithreading.. but we only read
|
//TODO: multithreading.. but we only read
|
||||||
Collection<String> dataKeys = spatial.getUserDataKeys();
|
Collection<String> dataKeys = spatial.getUserDataKeys();
|
||||||
|
@ -253,8 +253,8 @@ public class JmeTrack extends AbstractSceneExplorerNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(String name, Object before, Object after) {
|
public void propertyChange(String type, String name, Object before, Object after) {
|
||||||
super.propertyChange(name, before, after);
|
super.propertyChange(type, name, before, after);
|
||||||
setName();
|
setName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.1" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||||
<NonVisualComponents>
|
<NonVisualComponents>
|
||||||
|
@ -37,11 +37,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.gde.core.sceneexplorer.nodes.actions;
|
package com.jme3.gde.core.sceneexplorer.nodes.actions;
|
||||||
|
|
||||||
import com.jme3.effect.influencers.ParticleInfluencer;
|
|
||||||
import com.jme3.export.Savable;
|
import com.jme3.export.Savable;
|
||||||
import com.jme3.gde.core.assets.ProjectAssetManager;
|
import com.jme3.gde.core.assets.ProjectAssetManager;
|
||||||
import com.jme3.gde.core.properties.SceneExplorerProperty;
|
import com.jme3.gde.core.properties.SceneExplorerProperty;
|
||||||
import com.jme3.gde.core.properties.ScenePropertyChangeListener;
|
|
||||||
import com.jme3.gde.core.scene.SceneApplication;
|
import com.jme3.gde.core.scene.SceneApplication;
|
||||||
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
|
import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial;
|
||||||
import com.jme3.gde.core.util.PropertyUtils;
|
import com.jme3.gde.core.util.PropertyUtils;
|
||||||
@ -65,7 +63,7 @@ import org.openide.util.Exceptions;
|
|||||||
*
|
*
|
||||||
* @author normenhansen
|
* @author normenhansen
|
||||||
*/
|
*/
|
||||||
public class UserDataDialog extends javax.swing.JDialog implements ScenePropertyChangeListener {
|
public class UserDataDialog extends javax.swing.JDialog {
|
||||||
|
|
||||||
JmeSpatial spat;
|
JmeSpatial spat;
|
||||||
boolean initialized = false;
|
boolean initialized = false;
|
||||||
@ -134,15 +132,11 @@ public class UserDataDialog extends javax.swing.JDialog implements SceneProperty
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void propertyChange(String property, Object oldValue, Object newValue) {
|
|
||||||
//System.out.println(property + " changed");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Property makeProperty(Object obj, Class returntype, String method, String setter, String name) {
|
protected Property makeProperty(Object obj, Class returntype, String method, String setter, String name) {
|
||||||
Property prop = null;
|
Property prop = null;
|
||||||
try {
|
try {
|
||||||
|
|
||||||
prop = new SceneExplorerProperty(obj.getClass().cast(obj), returntype, method, setter, this);
|
prop = new SceneExplorerProperty(obj.getClass().cast(obj), returntype, method, setter);
|
||||||
|
|
||||||
prop.setName(name);
|
prop.setName(name);
|
||||||
|
|
||||||
@ -408,4 +402,5 @@ private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI
|
|||||||
private javax.swing.JTextField jTextField1;
|
private javax.swing.JTextField jTextField1;
|
||||||
private javax.swing.JTextField jTextField2;
|
private javax.swing.JTextField jTextField2;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,6 @@ import java.beans.IntrospectionException;
|
|||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import org.openide.util.Exceptions;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -45,18 +44,6 @@ public class PropertyUtils {
|
|||||||
|
|
||||||
public static PropertyDescriptor getPropertyDescriptor(Class c, Field field) {
|
public static PropertyDescriptor getPropertyDescriptor(Class c, Field field) {
|
||||||
try {
|
try {
|
||||||
try {
|
|
||||||
try {
|
|
||||||
PropertyDescriptor p = (PropertyDescriptor)c.getClassLoader().loadClass("java.beans.PropertyDescriptor").newInstance();
|
|
||||||
|
|
||||||
} catch (InstantiationException ex) {
|
|
||||||
Exceptions.printStackTrace(ex);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
Exceptions.printStackTrace(ex);
|
|
||||||
}
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
Exceptions.printStackTrace(ex);
|
|
||||||
}
|
|
||||||
PropertyDescriptor prop = new PropertyDescriptor(field.getName(), c);
|
PropertyDescriptor prop = new PropertyDescriptor(field.getName(), c);
|
||||||
|
|
||||||
prop.setDisplayName(splitCamelCase(field.getName()));
|
prop.setDisplayName(splitCamelCase(field.getName()));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user