Преглед изворни кода

Allow Filters to be edited again (bugfix) and prepare to fix #133. Only a PropertyEditor for Light and Spatial is required then.

MeFisto94 пре 7 година
родитељ
комит
33b141de88

+ 73 - 2
jme3-core/src/com/jme3/gde/core/filters/AbstractFilterNode.java

@@ -42,6 +42,10 @@ import java.awt.Image;
 import java.beans.PropertyDescriptor;
 import java.io.IOException;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 import javax.swing.Action;
 import org.openide.actions.DeleteAction;
 import org.openide.actions.MoveDownAction;
@@ -219,11 +223,78 @@ public abstract class AbstractFilterNode extends AbstractNode implements FilterN
         return prop;
     }
 
-    protected void createFields(Class c, Sheet.Set set, Object obj) throws SecurityException {
+    /**
+     * Scans the passed object for all it's fields and adds them to the Property
+     * Sheet Set.
+     * 
+     * @param c The Class of obj
+     * @param set The Property Sheet Set to add values to
+     * @param obj The Object to inspect
+     * @return The Methods which have been added/discovered. See
+     * {@link #createMethods(java.lang.Class, org.openide.nodes.Sheet.Set,
+     * java.lang.Object, java.lang.reflect.Method[]) }
+     * @throws SecurityException When Inspecting using Reflection failed
+     */
+    protected Method[] createFields(Class c, Sheet.Set set, Object obj) throws SecurityException {
+        ArrayList<Method> methodList = new ArrayList<Method>(c.getDeclaredFields().length);
         for (Field field : c.getDeclaredFields()) {
             PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(c, field);
             if (prop != null) {
-                set.put(makeProperty(obj, prop.getPropertyType(), prop.getReadMethod().getName(), prop.getWriteMethod().getName(), prop.getDisplayName()));
+                methodList.add(prop.getReadMethod());
+                methodList.add(prop.getWriteMethod());
+                set.put(
+                    makeProperty(
+                            obj, prop.getPropertyType(),
+                            prop.getReadMethod().getName(),
+                            prop.getWriteMethod().getName(),
+                            prop.getDisplayName()
+                    )
+                );
+            }
+        }
+        
+        return methodList.toArray(new Method[methodList.size()]);
+    }
+    
+    /**
+     * Scans the passed object for all it's methods and adds them to the
+     * PropertySheet Set. Excludes the methods passed in, which are typically
+     * already found by {@link #createFields(java.lang.Class,
+     * org.openide.nodes.Sheet.Set, java.lang.Object) } and should not
+     * be added twice to the Properties.
+     * 
+     * @param c The Class of obj
+     * @param set The Property Sheet Set to add values to
+     * @param obj The Object to inspect
+     * @param ignoreMethods The Methods to ignore
+     * @throws SecurityException When Inspecting using Reflection failed
+     */
+    protected void createMethods(Class c, Sheet.Set set, Object obj, Method[] ignoreMethods) throws SecurityException {
+        List<Method> ignoreMethodList = new ArrayList<Method>(Arrays.asList(ignoreMethods));
+        
+        for (Method m : c.getDeclaredMethods()) {
+            // Ignore Methods which were already discovered by the fields.
+            if (!ignoreMethodList.contains(m)) {
+                PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(c, m);
+                if (prop != null) {
+                    /* add the setter/getter to the ignoreMethodsList, to
+                     * prevent double discovery of the same internal field
+                     */
+                    ignoreMethodList.add(prop.getReadMethod());
+                    ignoreMethodList.add(prop.getWriteMethod());
+                    
+                    set.put(
+                        makeProperty(
+                            obj, prop.getPropertyType(),
+                            prop.getReadMethod().getName(),
+                            prop.getWriteMethod().getName(),
+                            prop.getDisplayName().substring(
+                                // Remove "Is " "Set "
+                                prop.getDisplayName().indexOf(" ") + 1
+                            )
+                        )
+                    );
+                }
             }
         }
     }

+ 7 - 9
jme3-core/src/com/jme3/gde/core/filters/impl/JmeFilter.java

@@ -34,6 +34,8 @@ package com.jme3.gde.core.filters.impl;
 import com.jme3.gde.core.filters.AbstractFilterNode;
 import com.jme3.gde.core.filters.FilterNode;
 import com.jme3.post.Filter;
+import com.jme3.shadow.AbstractShadowFilter;
+import java.lang.reflect.Method;
 import org.openide.loaders.DataObject;
 import org.openide.nodes.Node;
 import org.openide.nodes.Sheet;
@@ -69,22 +71,18 @@ public class JmeFilter extends AbstractFilterNode {
         
         do {
             // The Filter class is already processed in AbstractFilterNode#createSheet
-            if (c.equals(Filter.class)) {
+            if (c.equals(Filter.class) || c.equals(Object.class)) {
                 c = c.getSuperclass();
                 continue;
             }
             
             Sheet.Set set = Sheet.createPropertiesSet();
+            set.setName(c.getName()); // A set's name is it's unique identifier
+            set.setDisplayName(c.getName());
             
-            if (filter.getClass().equals(c)) { // is level of current filter.
-                set.setDisplayName(filter.getName());
-                set.setName(Node.class.getName());
-            } else {
-                set.setName(Node.class.getName());
-                set.setDisplayName(c.getName());
-            }
+            Method[] methods = createFields(c, set, filter);
+            createMethods(c, set, filter, methods);
             
-            createFields(c, set, filter);
             sheet.put(set);
             
             c = c.getSuperclass();

+ 17 - 6
jme3-core/src/com/jme3/gde/core/properties/SceneExplorerProperty.java

@@ -44,7 +44,6 @@ import com.jme3.math.Vector3f;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.concurrent.Callable;
 import java.util.logging.Level;
@@ -57,7 +56,7 @@ import org.openide.util.Mutex;
 /**
  * This class allows editing jME scene values in property sheets in a threadsafe
  * manner. The getter and setter are called via reflection and changes in the
- * properties can be listed for.
+ * properties can be listened for.
  *
  * @author normenhansen
  */
@@ -136,12 +135,14 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
     public void syncValue() {
         final T realValue = getSuperValue();
         mutex.readAccess(new Runnable() {
+            @Override
             public void run() {
                 if (changing) {
                     return;
                 }
                 if ((objectLocal == null) && !inited) {
                     mutex.postWriteRequest(new Runnable() {
+                        @Override
                         public void run() {
                             inited = true;
                             objectLocal = duplicateObject(realValue);
@@ -151,6 +152,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
                     });
                 } else if ((objectLocal != null) && !objectLocal.equals(realValue)) {
                     mutex.postWriteRequest(new Runnable() {
+                        @Override
                         public void run() {
                             T oldObject = objectLocal;
                             T newObject = duplicateObject(realValue);
@@ -161,6 +163,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
                     });
                 } else if ((objectLocal == null) && (realValue != null)) {
                     mutex.postWriteRequest(new Runnable() {
+                        @Override
                         public void run() {
                             objectLocal = duplicateObject(realValue);
                             notifyListeners(PROP_SCENE_CHANGE, null, objectLocal);
@@ -186,6 +189,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
     @Override
     public T getValue() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         return mutex.readAccess(new Mutex.Action<T>() {
+            @Override
             public T run() {
                 logger.log(Level.FINE, "Return local value of {0}", objectLocal);
                 return objectLocal;
@@ -205,6 +209,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
     @Override
     public void setValue(final T val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         mutex.postWriteRequest(new Runnable() {
+            @Override
             public void run() {
                 logger.log(Level.FINE, "Set local value to {0}", val);
                 final T oldObject = objectLocal;
@@ -212,8 +217,10 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
                 objectLocal = val;
                 final T sceneObject = duplicateObject(val);
                 SceneApplication.getApplication().enqueue(new Callable<Void>() {
+                    @Override
                     public Void call() throws Exception {
                         mutex.postWriteRequest(new Runnable() {
+                            @Override
                             public void run() {
                                 setSuperValue(sceneObject);
                                 changing = false;
@@ -426,7 +433,9 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
     protected void addUndo(final Object before, final Object after) {
         SceneUndoRedoManager undoRedo = Lookup.getDefault().lookup(SceneUndoRedoManager.class);
         if (undoRedo == null) {
-            logger.log(Level.WARNING, "Cannot access SceneUndoRedoManager");
+            logger.log(Level.WARNING, "Cannot access SceneUndoRedoManager. "
+                + "If you are editing properties without having a j3o file open,"
+                + "you wont have undo/redo support!");
             return;
         }
         undoRedo.addEdit(this, new AbstractUndoableSceneEdit() {
@@ -458,7 +467,7 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
      * Add a ScenePropertyChangeListener to listen for changes of this propety.
      * See the "PROP_XXX" properties for a list of change callback types.
      *
-     * @param listener
+     * @param listener The Listener
      */
     public void addPropertyChangeListener(ScenePropertyChangeListener listener) {
         if (listener != null) {
@@ -470,6 +479,8 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
     /**
      * Removes a ScenePropertyChangeListener that was listening for changes of
      * this propety.
+     * 
+     * @param listener The Listener
      */
     public void removePropertyChangeListener(ScenePropertyChangeListener listener) {
         if (listener != null) {
@@ -486,10 +497,10 @@ public class SceneExplorerProperty<T> extends PropertySupport.Reflection<T> {
      */
     protected void notifyListeners(final String type, final Object before, final Object after) {
         java.awt.EventQueue.invokeLater(new Runnable() {
+            @Override
             public void run() {
                 logger.log(Level.FINE, "Notify SceneExplorer listeners");
-                for (Iterator<ScenePropertyChangeListener> it = listeners.iterator(); it.hasNext();) {
-                    ScenePropertyChangeListener propertyChangeListener = it.next();
+                for (ScenePropertyChangeListener propertyChangeListener : listeners) {
                     propertyChangeListener.propertyChange(type, getName(), before, after);
                 }
             }