Sfoglia il codice sorgente

SDK : ParticleEmitter editor, enhanced particleInfluencer editor to avoid slow downs due to classpath scanning.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9844 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rem..om 13 anni fa
parent
commit
c677ad236c

+ 5 - 2
jme3-core/src/com/jme3/gde/core/properties/ParticleInfluencerProperty.java

@@ -33,6 +33,7 @@ package com.jme3.gde.core.properties;
 
 import com.jme3.effect.ParticleEmitter;
 import com.jme3.effect.influencers.ParticleInfluencer;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeParticleEmitter;
 import java.beans.PropertyEditor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.Iterator;
@@ -48,12 +49,14 @@ public class ParticleInfluencerProperty extends PropertySupport.ReadWrite<Partic
 
     private LinkedList<ScenePropertyChangeListener> listeners = new LinkedList<ScenePropertyChangeListener>();
     private ParticleEmitter emitter;
+    private JmeParticleEmitter jmePE;
     private Project project;
 
-    public ParticleInfluencerProperty(ParticleEmitter emitter, Project project) {
+    public ParticleInfluencerProperty(ParticleEmitter emitter,JmeParticleEmitter jmePE, Project project) {
         super("ParticleInfluencer", ParticleInfluencer.class, "Particle Influencer", " ");
         this.project = project;
         this.emitter = emitter;
+        this.jmePE = jmePE;
 
     }
 
@@ -71,7 +74,7 @@ public class ParticleInfluencerProperty extends PropertySupport.ReadWrite<Partic
 
     @Override
     public PropertyEditor getPropertyEditor() {
-        return new ParticleInfluencerPropertyEditor(emitter.getParticleInfluencer(), project);
+        return new ParticleInfluencerPropertyEditor(jmePE, project);
     }
 
     public void addPropertyChangeListener(ScenePropertyChangeListener listener) {

+ 77 - 87
jme3-core/src/com/jme3/gde/core/properties/ParticleInfluencerPropertyEditor.java

@@ -31,35 +31,21 @@
  */
 package com.jme3.gde.core.properties;
 
+import com.jme3.effect.ParticleEmitter;
 import com.jme3.effect.influencers.ParticleInfluencer;
 import com.jme3.gde.core.assets.ProjectAssetManager;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeParticleEmitter;
+import com.jme3.gde.core.sceneexplorer.nodes.actions.ParticleInfluencerPicker;
 import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Rectangle;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyEditor;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Set;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeMirror;
-import org.netbeans.api.java.classpath.ClassPath;
-import org.netbeans.api.java.project.JavaProjectConstants;
-import org.netbeans.api.java.source.ClassIndex;
-import org.netbeans.api.java.source.ClassIndex.NameKind;
-import org.netbeans.api.java.source.ClassIndex.SearchScope;
-import org.netbeans.api.java.source.ClasspathInfo;
-import org.netbeans.api.java.source.CompilationController;
-import org.netbeans.api.java.source.ElementHandle;
-import org.netbeans.api.java.source.JavaSource;
-import org.netbeans.api.java.source.JavaSource.Phase;
-import org.netbeans.api.java.source.Task;
 import org.netbeans.api.project.Project;
-import org.netbeans.api.project.SourceGroup;
-import org.netbeans.api.project.Sources;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.util.Exceptions;
@@ -71,14 +57,16 @@ import org.openide.util.Exceptions;
 public class ParticleInfluencerPropertyEditor implements PropertyEditor {
 
     private LinkedList<PropertyChangeListener> listeners = new LinkedList<PropertyChangeListener>();
+    private JmeParticleEmitter jmePe;
     private ParticleInfluencer pi;
     private Project proj;
 
     public ParticleInfluencerPropertyEditor() {
     }
 
-    public ParticleInfluencerPropertyEditor(ParticleInfluencer pi, Project project) {
-        this.pi = pi;
+    public ParticleInfluencerPropertyEditor(JmeParticleEmitter jmePe, Project project) {
+        this.jmePe = jmePe;
+        this.pi = jmePe.getLookup().lookup(ParticleEmitter.class).getParticleInfluencer();
         this.proj = project;
     }
 
@@ -105,10 +93,13 @@ public class ParticleInfluencerPropertyEditor implements PropertyEditor {
     }
 
     public String getAsText() {
-        return pi.getClass().getName();
+        return pi.getClass().getSimpleName();
     }
 
     public void setAsText(String text) throws IllegalArgumentException {
+        if(pi.getClass().getName().equals(text)){
+            return;
+        }
         ParticleInfluencer old = pi;
         ProjectAssetManager manager = (ProjectAssetManager) proj.getLookup().lookup(ProjectAssetManager.class);
         List<ClassLoader> loaders = manager.getClassLoaders();
@@ -151,77 +142,76 @@ public class ParticleInfluencerPropertyEditor implements PropertyEditor {
     }
 
     public String[] getTags() {
-
-        List<String> s = getSources();
-        s.add("com.jme3.effect.influencers.DefaultParticleInfluencer");
-        s.add("com.jme3.effect.influencers.NewtonianParticleInfluencer");
-        s.add("com.jme3.effect.influencers.RadialParticleInfluencer");
-        s.add("com.jme3.effect.influencers.EmptyParticleInfluencer");
-        String[] t = new String[s.size()];
-        return s.toArray(t);
-
-    }
-
-    private List<String> getSources() {
-        Sources sources = proj.getLookup().lookup(Sources.class);
-        final List<String> list = new LinkedList<String>();
-        if (sources != null) {
-            SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
-            if (groups != null) {
-                for (SourceGroup sourceGroup : groups) {
-                    ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT),
-                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.COMPILE),
-                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE));
-
-                    HashSet<SearchScope> set = new HashSet<SearchScope>();
-                    set.add(ClassIndex.SearchScope.SOURCE);
-                    //   set.add(ClassIndex.SearchScope.DEPENDENCIES);
-
-                    Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
-                    for (Iterator<ElementHandle<TypeElement>> it = types.iterator(); it.hasNext();) {
-                        final ElementHandle<TypeElement> elementHandle = it.next();
-                        JavaSource js = JavaSource.create(cpInfo);
-                        try {
-                            js.runUserActionTask(new Task<CompilationController>() {
-
-                                public void run(CompilationController control)
-                                        throws Exception {
-                                    control.toPhase(Phase.RESOLVED);
-                                    //TODO: check with proper casting check.. gotta get TypeMirror of Control interface..
-//                                    TypeUtilities util = control.getTypeUtilities();//.isCastable(Types., null)
-//                                    util.isCastable(null, null);
-                                    TypeElement elem = elementHandle.resolve(control);
-                                    List<? extends TypeMirror> interfaces = elem.getInterfaces();
-                                    for (TypeMirror typeMirror : interfaces) {
-                                        String interfaceName = typeMirror.toString();
-                                        if ("com.jme3.effect.influencers.ParticleInfluencer".equals(interfaceName)) {
-                                            list.add(elem.getQualifiedName().toString());
-                                        }
-                                    }
-                                    TypeMirror superClass = elem.getSuperclass();
-                                    String superClassName = superClass.toString();
-                                    if ("com.jme3.effect.influencers.DefaultParticleInfluencer".equals(superClassName)) {
-                                        list.add(elem.getQualifiedName().toString());
-                                    }
-                                }
-                            }, false);
-                        } catch (Exception ioe) {
-                            Exceptions.printStackTrace(ioe);
-                        }
-                    }
-
-                }
-            }
-        }
-        return list;
-    }
-
+        return null;
+//        List<String> s = getSources();
+//        s.add("com.jme3.effect.influencers.DefaultParticleInfluencer");
+//        s.add("com.jme3.effect.influencers.NewtonianParticleInfluencer");
+//        s.add("com.jme3.effect.influencers.RadialParticleInfluencer");
+//        s.add("com.jme3.effect.influencers.EmptyParticleInfluencer");
+//        String[] t = new String[s.size()];
+//        return s.toArray(t);
+
+    }
+
+//    private List<String> getSources() {
+//        Sources sources = proj.getLookup().lookup(Sources.class);
+//        final List<String> list = new LinkedList<String>();
+//        if (sources != null) {
+//            SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
+//            if (groups != null) {
+//                for (SourceGroup sourceGroup : groups) {
+//                    ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT),
+//                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.COMPILE),
+//                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE));
+//
+//                    HashSet<SearchScope> set = new HashSet<SearchScope>();
+//                    set.add(ClassIndex.SearchScope.SOURCE);
+//                    //   set.add(ClassIndex.SearchScope.DEPENDENCIES);
+//
+//                    Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
+//                    for (Iterator<ElementHandle<TypeElement>> it = types.iterator(); it.hasNext();) {
+//                        final ElementHandle<TypeElement> elementHandle = it.next();
+//                        JavaSource js = JavaSource.create(cpInfo);
+//                        try {
+//                            js.runUserActionTask(new Task<CompilationController>() {
+//
+//                                public void run(CompilationController control)
+//                                        throws Exception {
+//                                    control.toPhase(Phase.RESOLVED);
+//                                    //TODO: check with proper casting check.. gotta get TypeMirror of Control interface..
+////                                    TypeUtilities util = control.getTypeUtilities();//.isCastable(Types., null)
+////                                    util.isCastable(null, null);
+//                                    TypeElement elem = elementHandle.resolve(control);
+//                                    List<? extends TypeMirror> interfaces = elem.getInterfaces();
+//                                    for (TypeMirror typeMirror : interfaces) {
+//                                        String interfaceName = typeMirror.toString();
+//                                        if ("com.jme3.effect.influencers.ParticleInfluencer".equals(interfaceName)) {
+//                                            list.add(elem.getQualifiedName().toString());
+//                                        }
+//                                    }
+//                                    TypeMirror superClass = elem.getSuperclass();
+//                                    String superClassName = superClass.toString();
+//                                    if ("com.jme3.effect.influencers.DefaultParticleInfluencer".equals(superClassName)) {
+//                                        list.add(elem.getQualifiedName().toString());
+//                                    }
+//                                }
+//                            }, false);
+//                        } catch (Exception ioe) {
+//                            Exceptions.printStackTrace(ioe);
+//                        }
+//                    }
+//
+//                }
+//            }
+//        }
+//        return list;
+//    }
     public Component getCustomEditor() {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return new ParticleInfluencerPicker(null, true, this, jmePe);
     }
 
     public boolean supportsCustomEditor() {
-        return false;
+        return true;
     }
 
     public void addPropertyChangeListener(PropertyChangeListener listener) {

+ 1 - 1
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/JmeParticleEmitter.java

@@ -132,7 +132,7 @@ public class JmeParticleEmitter extends JmeGeometry {
 
         set2.setDisplayName("Particle Influencer" + " - " + obj.getParticleInfluencer().getClass().getSimpleName());
         set2.setName(obj.getParticleInfluencer().getClass().getName());
-        ParticleInfluencerProperty prop = new ParticleInfluencerProperty(obj, this.getLookup().lookup(ProjectAssetManager.class).getProject());
+        ParticleInfluencerProperty prop = new ParticleInfluencerProperty(obj,this, this.getLookup().lookup(ProjectAssetManager.class).getProject());
         prop.addPropertyChangeListener(this);
         set2.put(prop);
 

+ 4 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties

@@ -10,3 +10,7 @@ UserDataPicker.jPanel1.border.title=Chose a UserData type
 UserDataPicker.jTextField1.text=
 UserDataPicker.jButton1.text=Ok
 UserDataPicker.jButton2.text=Cancel
+ParticleInfluencerPicker.jPanel1.border.title=Chose a UserData type
+ParticleInfluencerPicker.jButton2.text=Cancel
+ParticleInfluencerPicker.jButton1.text=Ok
+ParticleInfluencerPicker.jTextField1.text=

+ 138 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ParticleInfluencerPicker.form

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.7" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="jPanel1" alignment="0" max="32767" attributes="0"/>
+          <Group type="102" alignment="1" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jButton2" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="225" max="32767" attributes="0"/>
+              <Component id="jButton1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="jButton1" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="jButton2" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
+            <TitledBorder title="Chose a UserData type">
+              <ResourceString PropertyName="titleX" bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ParticleInfluencerPicker.jPanel1.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </TitledBorder>
+          </Border>
+        </Property>
+      </Properties>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="1" attributes="0">
+                      <Component id="jTextField1" alignment="0" pref="323" max="32767" attributes="0"/>
+                      <Component id="jScrollPane1" alignment="0" pref="323" max="32767" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <Component id="jScrollPane1" min="-2" pref="204" max="-2" attributes="0"/>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Component id="jTextField1" min="-2" max="-2" attributes="0"/>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JList" name="jList1">
+              <Properties>
+                <Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
+                  <StringArray count="1">
+                    <StringItem index="0" value="Loading Savable types..."/>
+                  </StringArray>
+                </Property>
+              </Properties>
+              <Events>
+                <EventHandler event="mouseClicked" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="jList1MouseClicked"/>
+                <EventHandler event="valueChanged" listener="javax.swing.event.ListSelectionListener" parameters="javax.swing.event.ListSelectionEvent" handler="jList1ValueChanged"/>
+              </Events>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JTextField" name="jTextField1">
+          <Properties>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ParticleInfluencerPicker.jTextField1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+            </Property>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JButton" name="jButton1">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ParticleInfluencerPicker.jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton1ActionPerformed"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="jButton2">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="com/jme3/gde/core/sceneexplorer/nodes/actions/Bundle.properties" key="ParticleInfluencerPicker.jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="jButton2ActionPerformed"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>

+ 291 - 0
jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/ParticleInfluencerPicker.java

@@ -0,0 +1,291 @@
+ /*
+ *  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.
+ */
+/*
+ * UserDataPicker.java
+ *
+ * Created on 20 août 2012, 22:09:04
+ */
+package com.jme3.gde.core.sceneexplorer.nodes.actions;
+
+import com.jme3.gde.core.assets.ProjectAssetManager;
+import com.jme3.gde.core.properties.ParticleInfluencerPropertyEditor;
+import com.jme3.gde.core.sceneexplorer.nodes.JmeParticleEmitter;
+import java.awt.EventQueue;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.swing.DefaultListModel;
+import org.netbeans.api.java.classpath.ClassPath;
+import org.netbeans.api.java.project.JavaProjectConstants;
+import org.netbeans.api.java.source.ClassIndex;
+import org.netbeans.api.java.source.ClassIndex.NameKind;
+import org.netbeans.api.java.source.ClassIndex.SearchScope;
+import org.netbeans.api.java.source.ClasspathInfo;
+import org.netbeans.api.java.source.CompilationController;
+import org.netbeans.api.java.source.ElementHandle;
+import org.netbeans.api.java.source.JavaSource;
+import org.netbeans.api.java.source.JavaSource.Phase;
+import org.netbeans.api.java.source.Task;
+import org.netbeans.api.project.SourceGroup;
+import org.netbeans.api.project.Sources;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Nehon
+ */
+public class ParticleInfluencerPicker extends javax.swing.JDialog {
+
+    JmeParticleEmitter jmePE;
+    ParticleInfluencerPropertyEditor editor;
+
+    /**
+     * Creates new form UserDataPicker
+     */
+    public ParticleInfluencerPicker(java.awt.Frame parent, boolean modal, ParticleInfluencerPropertyEditor editor, JmeParticleEmitter spat) {
+        super(parent, modal);
+        this.jmePE = spat;
+        initComponents();
+        this.editor = editor;
+
+        setLocationRelativeTo(null);
+        ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
+
+        jList1.setEnabled(false);
+        //loading savable list in a new Thread
+        exec.execute(new Runnable() {
+            public void run() {
+                final DefaultListModel model = getSources();
+
+                EventQueue.invokeLater(new Runnable() {
+                    public void run() {
+                        jList1.setModel(model);
+                        jList1.setEnabled(true);
+                    }
+                });
+
+            }
+        });
+
+
+    }
+
+    private DefaultListModel getSources() {
+        final DefaultListModel model = new DefaultListModel();
+        model.addElement("com.jme3.effect.influencers.DefaultParticleInfluencer");
+        model.addElement("com.jme3.effect.influencers.NewtonianParticleInfluencer");
+        model.addElement("com.jme3.effect.influencers.RadialParticleInfluencer");
+        model.addElement("com.jme3.effect.influencers.EmptyParticleInfluencer");
+        Sources sources = jmePE.getLookup().lookup(ProjectAssetManager.class).getProject().getLookup().lookup(Sources.class);
+        if (sources != null) {
+            SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA);
+            if (groups != null) {
+                for (SourceGroup sourceGroup : groups) {
+                    ClasspathInfo cpInfo = ClasspathInfo.create(ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.BOOT),
+                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.COMPILE),
+                            ClassPath.getClassPath(sourceGroup.getRootFolder(), ClassPath.SOURCE));
+
+                    HashSet<SearchScope> set = new HashSet<SearchScope>();
+                    set.add(ClassIndex.SearchScope.SOURCE);
+
+                    Set<ElementHandle<TypeElement>> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set);
+                    for (Iterator<ElementHandle<TypeElement>> it = types.iterator(); it.hasNext();) {
+                        final ElementHandle<TypeElement> elementHandle = it.next();
+                        JavaSource js = JavaSource.create(cpInfo);
+                        try {
+                            js.runUserActionTask(new Task<CompilationController>() {
+                                public void run(CompilationController control)
+                                        throws Exception {
+                                    control.toPhase(Phase.RESOLVED);
+                                    //TODO: check with proper casting check.. gotta get TypeMirror of Control interface..
+//                                    TypeUtilities util = control.getTypeUtilities();//.isCastable(Types., null)
+//                                    util.isCastable(null, null);
+                                    TypeElement elem = elementHandle.resolve(control);
+                                    List<? extends TypeMirror> interfaces = elem.getInterfaces();
+                                    for (TypeMirror typeMirror : interfaces) {
+                                        String interfaceName = typeMirror.toString();
+                                        if ("com.jme3.effect.influencers.ParticleInfluencer".equals(interfaceName)) {
+                                            model.addElement(elem.getQualifiedName().toString());
+                                        }
+                                    }
+                                    TypeMirror superClass = elem.getSuperclass();
+                                    String superClassName = superClass.toString();
+                                    if ("com.jme3.effect.influencers.DefaultParticleInfluencer".equals(superClassName)) {
+                                        model.addElement(elem.getQualifiedName().toString());
+                                    }
+
+                                }
+                            }, false);
+                        } catch (Exception ioe) {
+                            Exceptions.printStackTrace(ioe);
+                        }
+                    }
+
+                }
+            }
+        }
+        return model;
+    }
+
+    /**
+     * This method is called from within the constructor to initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is always
+     * regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        jList1 = new javax.swing.JList();
+        jTextField1 = new javax.swing.JTextField();
+        jButton1 = new javax.swing.JButton();
+        jButton2 = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+
+        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(ParticleInfluencerPicker.class, "ParticleInfluencerPicker.jPanel1.border.title"))); // NOI18N
+
+        jList1.setModel(new javax.swing.AbstractListModel() {
+            String[] strings = { "Loading Savable types..." };
+            public int getSize() { return strings.length; }
+            public Object getElementAt(int i) { return strings[i]; }
+        });
+        jList1.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mouseClicked(java.awt.event.MouseEvent evt) {
+                jList1MouseClicked(evt);
+            }
+        });
+        jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
+            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
+                jList1ValueChanged(evt);
+            }
+        });
+        jScrollPane1.setViewportView(jList1);
+
+        jTextField1.setText(org.openide.util.NbBundle.getMessage(ParticleInfluencerPicker.class, "ParticleInfluencerPicker.jTextField1.text")); // NOI18N
+
+        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+                    .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE)
+                    .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 323, Short.MAX_VALUE))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(jPanel1Layout.createSequentialGroup()
+                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 204, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        jButton1.setText(org.openide.util.NbBundle.getMessage(ParticleInfluencerPicker.class, "ParticleInfluencerPicker.jButton1.text")); // NOI18N
+        jButton1.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                jButton1ActionPerformed(evt);
+            }
+        });
+
+        jButton2.setText(org.openide.util.NbBundle.getMessage(ParticleInfluencerPicker.class, "ParticleInfluencerPicker.jButton2.text")); // NOI18N
+        jButton2.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                jButton2ActionPerformed(evt);
+            }
+        });
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+                .addContainerGap()
+                .addComponent(jButton2)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 225, Short.MAX_VALUE)
+                .addComponent(jButton1)
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(layout.createSequentialGroup()
+                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                    .addComponent(jButton1)
+                    .addComponent(jButton2))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
+    setVisible(false);
+}//GEN-LAST:event_jButton2ActionPerformed
+
+private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
+
+
+    editor.setAsText(jTextField1.getText());
+    setVisible(false);
+
+}//GEN-LAST:event_jButton1ActionPerformed
+
+private void jList1ValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_jList1ValueChanged
+    jTextField1.setText(jList1.getSelectedValue().toString());
+}//GEN-LAST:event_jList1ValueChanged
+
+private void jList1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jList1MouseClicked
+    if (evt.getClickCount() == 2) {
+        jButton1ActionPerformed(null);
+    }
+}//GEN-LAST:event_jList1MouseClicked
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton jButton1;
+    private javax.swing.JButton jButton2;
+    private javax.swing.JList jList1;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextField jTextField1;
+    // End of variables declaration//GEN-END:variables
+}