diff --git a/sdk/jme3-core/manifest.mf b/sdk/jme3-core/manifest.mf
index 91daa7f95..d1a2d12e2 100644
--- a/sdk/jme3-core/manifest.mf
+++ b/sdk/jme3-core/manifest.mf
@@ -4,5 +4,5 @@ OpenIDE-Module-Implementation-Version: 0
OpenIDE-Module-Install: com/jme3/gde/core/Installer.class
OpenIDE-Module-Layer: com/jme3/gde/core/layer.xml
OpenIDE-Module-Localizing-Bundle: com/jme3/gde/core/Bundle.properties
-OpenIDE-Module-Requires: org.netbeans.api.javahelp.Help
+OpenIDE-Module-Requires: org.netbeans.api.javahelp.Help, org.openide.windows.WindowManager
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/Bundle.properties b/sdk/jme3-core/src/com/jme3/gde/core/Bundle.properties
index 4187126a0..a8a0d9a7a 100644
--- a/sdk/jme3-core/src/com/jme3/gde/core/Bundle.properties
+++ b/sdk/jme3-core/src/com/jme3/gde/core/Bundle.properties
@@ -3,6 +3,8 @@ OpenIDE-Module-Long-Description=\
This plugin provides the core functions of jMonkeyPlatform.
OpenIDE-Module-Name=jMonkeyPlatform Core
OpenIDE-Module-Short-Description=The jMonkeyPlatform Core Plugin
+Services/MIMEResolver/FilterPostProcessorResolver.xml=FilterPostProcessor Files
Services/MIMEResolver/JMEBinaryModelResolver.xml=JMEBinaryModel Files
Menu/Help/jmewiki.url=Browse Help online
Menu/Help/help-main.xml=Browse Help locally
+Templates/Other/filter.j3f=Empty FilterPostProcessor file
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/FilterPostProcessorResolver.xml b/sdk/jme3-core/src/com/jme3/gde/core/FilterPostProcessorResolver.xml
new file mode 100644
index 000000000..4c2b931cb
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/FilterPostProcessorResolver.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/assets/FilterDataObject.java b/sdk/jme3-core/src/com/jme3/gde/core/assets/FilterDataObject.java
new file mode 100644
index 000000000..931e4e7a5
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/assets/FilterDataObject.java
@@ -0,0 +1,58 @@
+/*
+ * 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.assets;
+
+import com.jme3.gde.core.filters.FilterPostProcessorNode;
+import com.jme3.post.FilterPostProcessor;
+import java.io.IOException;
+import org.openide.filesystems.FileObject;
+import org.openide.loaders.DataObjectExistsException;
+import org.openide.loaders.MultiFileLoader;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class FilterDataObject extends AssetDataObject {
+
+ public FilterDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException, IOException {
+ super(pf, loader);
+ getLookupContents().add(new FilterPostProcessorNode(this));
+ saveExtension = "j3f";
+ getLookup().lookup(AssetData.class).setExtension("j3f");
+ }
+
+ @Override
+ public FilterPostProcessor loadAsset() {
+ return (FilterPostProcessor) super.loadAsset();
+ }
+}
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filter.j3f b/sdk/jme3-core/src/com/jme3/gde/core/filter.j3f
new file mode 100644
index 000000000..a086ea025
Binary files /dev/null and b/sdk/jme3-core/src/com/jme3/gde/core/filter.j3f differ
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/AbstractFilterNode.java b/sdk/jme3-core/src/com/jme3/gde/core/filters/AbstractFilterNode.java
new file mode 100644
index 000000000..2fc16587d
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/AbstractFilterNode.java
@@ -0,0 +1,159 @@
+/*
+ * 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.filters;
+
+import com.jme3.gde.core.sceneexplorer.nodes.properties.SceneExplorerProperty;
+import com.jme3.gde.core.sceneexplorer.nodes.properties.ScenePropertyChangeListener;
+import com.jme3.post.Filter;
+import java.io.IOException;
+import javax.swing.Action;
+import org.openide.actions.CopyAction;
+import org.openide.actions.CutAction;
+import org.openide.actions.DeleteAction;
+import org.openide.actions.PasteAction;
+import org.openide.actions.RenameAction;
+import org.openide.loaders.DataObject;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
+import org.openide.util.actions.SystemAction;
+
+/**
+ *
+ * @author normenhansen
+ */
+public abstract class AbstractFilterNode extends AbstractNode implements FilterNode, ScenePropertyChangeListener {
+
+ protected boolean readOnly = false;
+ protected DataObject dataObject;
+ protected Filter filter;
+
+ public AbstractFilterNode() {
+ super(Children.LEAF);
+ }
+
+ public AbstractFilterNode(Filter filter) {
+ super(Children.LEAF);
+ this.filter = filter;
+ setName(filter.getName());
+ }
+
+ @Override
+ public Action[] getActions(boolean context) {
+// return super.getActions(context);
+ return new Action[]{
+ SystemAction.get(DeleteAction.class)
+ };
+ }
+
+ @Override
+ public boolean canDestroy() {
+ return !readOnly;
+ }
+
+ @Override
+ public void destroy() throws IOException {
+ super.destroy();
+ FilterPostProcessorNode nod = (FilterPostProcessorNode) getParentNode();
+ nod.removeFilter(filter);
+ }
+
+ protected void fireSave(boolean modified) {
+ if (dataObject != null) {
+ dataObject.setModified(true);
+ }
+ }
+
+ /**
+ * returns the PropertySet with the given name (mostly Class.name)
+ * @param name
+ * @return The PropertySet or null if no PropertySet by that name exists
+ */
+ public PropertySet getPropertySet(String name) {
+ for (int i = 0; i < getPropertySets().length; i++) {
+ PropertySet propertySet = getPropertySets()[i];
+ if (propertySet.getName().equals(name)) {
+ return propertySet;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param saveCookie the saveCookie to set
+ */
+ public AbstractFilterNode setReadOnly(boolean readOnly) {
+ this.readOnly = readOnly;
+ return this;
+ }
+
+ public void refreshProperties() {
+ setSheet(createSheet());
+ }
+
+ protected Property> makeProperty(Object obj, Class returntype, String method, String name) {
+ Property> prop = null;
+ try {
+ prop = new SceneExplorerProperty(getExplorerObjectClass().cast(obj), returntype, method, null);
+ prop.setName(name);
+ } catch (NoSuchMethodException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ return prop;
+ }
+
+ protected Property> makeProperty(Object obj, Class returntype, String method, String setter, String name) {
+ Property> prop = null;
+ try {
+ if (readOnly) {
+ prop = new SceneExplorerProperty(getExplorerObjectClass().cast(obj), returntype, method, null);
+ } else {
+ prop = new SceneExplorerProperty(getExplorerObjectClass().cast(obj), returntype, method, setter, this);
+ }
+ prop.setName(name);
+
+ } catch (NoSuchMethodException ex) {
+ Exceptions.printStackTrace(ex);
+ }
+ return prop;
+ }
+
+ public void propertyChange(final String name, final Object before, final Object after) {
+ fireSave(true);
+ firePropertyChange(name, before, after);
+ }
+
+ public abstract Class> getExplorerObjectClass();
+
+ public abstract Node[] createNodes(Object key, DataObject dataObject, boolean readOnly);
+}
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/AddFilterAction.java b/sdk/jme3-core/src/com/jme3/gde/core/filters/AddFilterAction.java
new file mode 100644
index 000000000..bc214ac15
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/AddFilterAction.java
@@ -0,0 +1,107 @@
+/*
+ * 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.filters;
+
+import com.jme3.gde.core.filters.actions.NewFilterAction;
+import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit;
+import com.jme3.gde.core.undoredo.SceneUndoRedoManager;
+import com.jme3.post.Filter;
+import com.jme3.post.FilterPostProcessor;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
+import org.openide.util.Lookup;
+import org.openide.util.actions.Presenter;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class AddFilterAction extends AbstractAction implements Presenter.Popup {
+
+ protected FilterPostProcessorNode filterNode;
+
+ public AddFilterAction(FilterPostProcessorNode node) {
+ this.filterNode = node;
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ }
+
+ public JMenuItem getPopupPresenter() {
+ JMenu result = new JMenu("Add Filter..");
+ for (NewFilterAction di : Lookup.getDefault().lookupAll(NewFilterAction.class)) {
+ result.add(new JMenuItem(di.getAction(filterNode)));
+ }
+ return result;
+ }
+
+ private void addFilterUndo(final FilterPostProcessor fpp, final Filter filter) {
+ //add undo
+ if (fpp != null && filter != null) {
+ Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {
+
+ @Override
+ public void sceneUndo() throws CannotUndoException {
+ fpp.removeFilter(filter);
+ }
+
+ @Override
+ public void sceneRedo() throws CannotRedoException {
+ fpp.addFilter(filter);
+ }
+
+ @Override
+ public void awtRedo() {
+ filterNode.refresh();
+ }
+
+ @Override
+ public void awtUndo() {
+ filterNode.refresh();
+ }
+ });
+ }
+ }
+
+ private void setModified() {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+
+ public void run() {
+ filterNode.refresh();
+ }
+ });
+ }
+}
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/Bundle.properties b/sdk/jme3-core/src/com/jme3/gde/core/filters/Bundle.properties
new file mode 100644
index 000000000..651fa1a1e
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/Bundle.properties
@@ -0,0 +1,3 @@
+CTL_FilterExplorerAction=FilterExplorer
+CTL_FilterExplorerTopComponent=FilterExplorer Window
+HINT_FilterExplorerTopComponent=This is a FilterExplorer window
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.form b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.form
new file mode 100644
index 000000000..701702b5b
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.form
@@ -0,0 +1,67 @@
+
+
+
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.java b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.java
new file mode 100644
index 000000000..505784dbe
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterExplorerTopComponent.java
@@ -0,0 +1,222 @@
+/*
+ * 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.filters;
+
+import com.jme3.gde.core.assets.FilterDataObject;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.post.FilterPostProcessor;
+import java.util.concurrent.Callable;
+import java.util.logging.Logger;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+import org.netbeans.api.settings.ConvertAsProperties;
+import org.openide.awt.ActionID;
+import org.openide.awt.ActionReference;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+import org.openide.explorer.view.BeanTreeView;
+import org.openide.nodes.Node;
+
+/**
+ * Top component which displays something.
+ */
+@ConvertAsProperties(dtd = "-//com.jme3.gde.core.filters//FilterExplorer//EN",
+autostore = false)
+@TopComponent.Description(preferredID = "FilterExplorerTopComponent",
+iconBase="com/jme3/gde/core/objects_082.gif",
+persistenceType = TopComponent.PERSISTENCE_ALWAYS)
+@TopComponent.Registration(mode = "navigator", openAtStartup = true)
+@ActionID(category = "Window", id = "com.jme3.gde.core.filters.FilterExplorerTopComponent")
+@ActionReference(path = "Menu/Window" /*, position = 333 */)
+@TopComponent.OpenActionRegistration(displayName = "#CTL_FilterExplorerAction",
+preferredID = "FilterExplorerTopComponent")
+public final class FilterExplorerTopComponent extends TopComponent implements ExplorerManager.Provider {
+
+ private static FilterExplorerTopComponent instance;
+ private static final String PREFERRED_ID = "FilterExplorerTopComponent";
+ private transient ExplorerManager explorerManager = new ExplorerManager();
+ private FilterDataObject currentFile;
+ private FilterPostProcessorNode node;
+ private boolean added = false;
+
+ public FilterExplorerTopComponent() {
+ initComponents();
+ setName(NbBundle.getMessage(FilterExplorerTopComponent.class, "CTL_FilterExplorerTopComponent"));
+ setToolTipText(NbBundle.getMessage(FilterExplorerTopComponent.class, "HINT_FilterExplorerTopComponent"));
+ associateLookup(ExplorerUtils.createLookup(explorerManager, getActionMap()));
+ }
+
+ /** 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.
+ */
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jScrollPane1 = new BeanTreeView();
+ jToolBar1 = new javax.swing.JToolBar();
+ jPanel1 = new javax.swing.JPanel();
+
+ jToolBar1.setFloatable(false);
+ jToolBar1.setRollover(true);
+
+ javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
+ jPanel1.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 392, Short.MAX_VALUE)
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 21, Short.MAX_VALUE)
+ );
+
+ jToolBar1.add(jPanel1);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(jToolBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE))
+ );
+ }// //GEN-END:initComponents
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JToolBar jToolBar1;
+ // End of variables declaration//GEN-END:variables
+
+ @Override
+ public void componentOpened() {
+ // TODO add custom code on component opening
+ }
+
+ @Override
+ public void componentClosed() {
+ // TODO add custom code on component closing
+ //explorerManager.setRootContext(Node.EMPTY);
+ setActivatedNodes(new Node[]{});
+ }
+
+ void writeProperties(java.util.Properties p) {
+ // better to version settings since initial version as advocated at
+ // http://wiki.apidesign.org/wiki/PropertyFiles
+ p.setProperty("version", "1.0");
+ // TODO store your settings
+ }
+
+ void readProperties(java.util.Properties p) {
+ String version = p.getProperty("version");
+ // TODO read your settings according to their version
+ }
+
+ public void loadFile(FilterDataObject object) {
+ explorerManager.setRootContext(object.getLookup().lookup(FilterPostProcessorNode.class));
+ node = object.getLookup().lookup(FilterPostProcessorNode.class);
+ setActivatedNodes(new Node[]{object.getNodeDelegate()});
+ open();
+ if (currentFile != null && added) {
+ setFilterEnabled(false);
+ }
+ currentFile = object;
+ if (added) {
+ setFilterEnabled(true);
+ }
+ }
+
+ public synchronized void setFilterEnabled(final boolean enabled) {
+ if (added == enabled) {
+ return;
+ }
+ added = enabled;
+ if (currentFile != null) {
+ final FilterPostProcessor fpp = this.node.getFilterPostProcessor();
+ SceneApplication.getApplication().enqueue(new Callable() {
+
+ public Object call() throws Exception {
+ if (enabled) {
+ SceneApplication.getApplication().getViewPort().removeProcessor(fpp);
+ } else {
+ SceneApplication.getApplication().getViewPort().addProcessor(fpp);
+ }
+ return null;
+ }
+ });
+
+ }
+ }
+
+ /**
+ * Gets default instance. Do not use directly: reserved for *.settings files only,
+ * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+ * To obtain the singleton instance, use {@link #findInstance}.
+ */
+ public static synchronized FilterExplorerTopComponent getDefault() {
+ if (instance == null) {
+ instance = new FilterExplorerTopComponent();
+ }
+ return instance;
+ }
+
+ /**
+ * Obtain the SceneExplorerTopComponent instance. Never call {@link #getDefault} directly!
+ */
+ public static synchronized FilterExplorerTopComponent findInstance() {
+ TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+ if (win == null) {
+ Logger.getLogger(FilterExplorerTopComponent.class.getName()).warning(
+ "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+ return getDefault();
+ }
+ if (win instanceof FilterExplorerTopComponent) {
+ return (FilterExplorerTopComponent) win;
+ }
+ Logger.getLogger(FilterExplorerTopComponent.class.getName()).warning(
+ "There seem to be multiple components with the '" + PREFERRED_ID
+ + "' ID. That is a potential source of errors and unexpected behavior.");
+ return getDefault();
+ }
+
+ public ExplorerManager getExplorerManager() {
+ return explorerManager;
+ }
+}
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterNode.java b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterNode.java
new file mode 100644
index 000000000..fa401c39f
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterNode.java
@@ -0,0 +1,47 @@
+/*
+ * 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.filters;
+
+import org.openide.loaders.DataObject;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author normenhansen
+ */
+public interface FilterNode{
+
+ public Class> getExplorerObjectClass();
+
+ public Node[] createNodes(Object key, DataObject dataObject, boolean readOnly);
+
+}
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterPostProcessorNode.java b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterPostProcessorNode.java
new file mode 100644
index 000000000..16b597193
--- /dev/null
+++ b/sdk/jme3-core/src/com/jme3/gde/core/filters/FilterPostProcessorNode.java
@@ -0,0 +1,203 @@
+/*
+ * 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.filters;
+
+import com.jme3.gde.core.assets.FilterDataObject;
+import com.jme3.gde.core.scene.SceneApplication;
+import com.jme3.post.Filter;
+import com.jme3.post.FilterPostProcessor;
+import java.awt.Image;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import javax.swing.Action;
+import org.openide.actions.CopyAction;
+import org.openide.actions.CutAction;
+import org.openide.actions.DeleteAction;
+import org.openide.actions.PasteAction;
+import org.openide.actions.RenameAction;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Exceptions;
+import org.openide.util.ImageUtilities;
+import org.openide.util.Lookup;
+import org.openide.util.actions.SystemAction;
+
+/**
+ *
+ * @author normenhansen
+ */
+public class FilterPostProcessorNode extends AbstractNode {
+
+ private FilterDataObject dataObject;
+ private static Image smallImage =
+ ImageUtilities.loadImage("com/jme3/gde/core/objects_082.gif");
+ private FilterPostProcessor fpp;
+
+ public FilterPostProcessorNode(FilterDataObject dataObject) {
+ super(new FilterChildren(dataObject));
+ this.dataObject = dataObject;
+ setName(dataObject.getName());
+ ((FilterChildren) getChildren()).setFilterPostProcessorNode(this);
+ }
+
+ @Override
+ public Image getIcon(int type) {
+ return smallImage;
+ }
+
+ @Override
+ public Image getOpenedIcon(int type) {
+ return smallImage;
+ }
+
+ public FilterPostProcessor getFilterPostProcessor() {
+ if (fpp == null) {
+ this.fpp = dataObject.loadAsset();
+ }
+ return fpp;
+ }
+
+ public void refresh() {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+
+ public void run() {
+ ((FilterChildren) getChildren()).addNotify();
+ ((FilterChildren) getChildren()).doRefresh();
+ }
+ });
+ }
+
+ public void addFilter(final Filter filter) {
+ SceneApplication.getApplication().enqueue(new Callable