From 7d82eb6ee0ffb191fc5245316a325feb7f57c268 Mon Sep 17 00:00:00 2001 From: "nor..67" Date: Mon, 14 Jan 2013 02:07:52 +0000 Subject: [PATCH] SDK: - Add mother of all SDK features: Custom AppStates :O git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10068 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../AppStateExplorerTopComponent.form | 66 +++ .../AppStateExplorerTopComponent.java | 200 +++++++++ .../core/appstates/AppStateManagerNode.java | 109 +++++ .../jme3/gde/core/appstates/AppStateNode.java | 191 ++++++++ .../jme3/gde/core/appstates/Bundle.properties | 3 + .../gde/core/appstates/FakeApplication.java | 425 ++++++++++++++++++ .../appstates/NewAppStateVisualPanel1.form | 85 ++++ .../appstates/NewAppStateVisualPanel1.java | 209 +++++++++ .../appstates/NewAppStateWizardAction.java | 168 +++++++ .../appstates/NewAppStateWizardPanel1.java | 117 +++++ .../jme3/gde/core/scene/SceneApplication.java | 17 + .../com/jme3/gde/core/util/PropertyUtils.java | 39 +- 12 files changed, 1627 insertions(+), 2 deletions(-) create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.form create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateManagerNode.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateNode.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/Bundle.properties create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/FakeApplication.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.form create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardAction.java create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardPanel1.java diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.form b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.form new file mode 100644 index 000000000..6149cfda1 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.form @@ -0,0 +1,66 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java new file mode 100644 index 000000000..bc9f7cec6 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateExplorerTopComponent.java @@ -0,0 +1,200 @@ +/* + * 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.appstates; + +import com.jme3.asset.AssetManager; +import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.scene.PreviewRequest; +import com.jme3.gde.core.scene.SceneApplication; +import com.jme3.gde.core.scene.SceneListener; +import com.jme3.gde.core.scene.SceneRequest; +import com.jme3.renderer.Camera; +import com.jme3.scene.Spatial; +import javax.swing.ActionMap; +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; +import org.openide.windows.TopComponent; +import org.openide.util.NbBundle.Messages; + +/** + * TODO: preliminary implementation 'til new scene system + */ +@ConvertAsProperties( + dtd = "-//com.jme3.gde.core.appstates//AppStateExplorer//EN", +autostore = false) +@TopComponent.Description( + preferredID = "AppStateExplorerTopComponent", +//iconBase="SET/PATH/TO/ICON/HERE", +persistenceType = TopComponent.PERSISTENCE_NEVER) +@TopComponent.Registration(mode = "navigator", openAtStartup = true) +@ActionID(category = "Window", id = "com.jme3.gde.core.appstates.AppStateExplorerTopComponent") +@ActionReference(path = "Menu/Window" /*, position = 333 */) +@TopComponent.OpenActionRegistration( + displayName = "#CTL_AppStateExplorerAction", +preferredID = "AppStateExplorerTopComponent") +@Messages({ + "CTL_AppStateExplorerAction=AppStateExplorer", + "CTL_AppStateExplorerTopComponent=AppStateExplorer Window", + "HINT_AppStateExplorerTopComponent=This is a AppStateExplorer window" +}) +public final class AppStateExplorerTopComponent extends TopComponent implements ExplorerManager.Provider { + + private transient ExplorerManager explorerManager = new ExplorerManager(); + private FakeApplication fakeApp; + private ProjectAssetManager mgr; + private SceneListener listener = new SceneListener() { + public void sceneOpened(SceneRequest request) { + Spatial rootNode = request.getRootNode(); + if (!(rootNode instanceof com.jme3.scene.Node)) { + return; + } + mgr = request.getManager(); + AssetManager assetManager = request.getManager(); + Camera cam = SceneApplication.getApplication().getCamera(); + com.jme3.scene.Node guiNode = SceneApplication.getApplication().getGuiNode(); + fakeApp = new FakeApplication((com.jme3.scene.Node) rootNode, guiNode, assetManager, cam); + //TODO: ermagherd, hackish + SceneApplication.getApplication().setFakeApp(fakeApp); + final AppStateManagerNode nod = new AppStateManagerNode(fakeApp.getStateManager()); + jButton1.setEnabled(true); + explorerManager.setRootContext(nod); + setActivatedNodes(new Node[]{nod}); + } + + public void sceneClosed(SceneRequest request) { + SceneApplication.getApplication().setFakeApp(null); + mgr = null; + fakeApp = null; + jButton1.setEnabled(false); + explorerManager.setRootContext(Node.EMPTY); + setActivatedNodes(new Node[]{Node.EMPTY}); + } + + public void previewCreated(PreviewRequest request) { + } + }; + + public AppStateExplorerTopComponent() { + initComponents(); + setName(Bundle.CTL_AppStateExplorerTopComponent()); + setToolTipText(Bundle.HINT_AppStateExplorerTopComponent()); + ActionMap map = getActionMap(); + map.put("delete", ExplorerUtils.actionDelete(explorerManager, true)); +// map.put("moveup", new MoveUpAction()); +// map.put("movedown", new MoveDownAction()); + associateLookup(ExplorerUtils.createLookup(explorerManager, map)); + SceneApplication.getApplication().addSceneListener(listener); + } + + /** + * 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(); + jButton1 = new javax.swing.JButton(); + + jToolBar1.setFloatable(false); + jToolBar1.setRollover(true); + + org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AppStateExplorerTopComponent.class, "AppStateExplorerTopComponent.jButton1.text")); // NOI18N + jButton1.setEnabled(false); + jButton1.setFocusable(false); + jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); + jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM); + jButton1.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + jButton1ActionPerformed(evt); + } + }); + jToolBar1.add(jButton1); + + 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, 259, Short.MAX_VALUE) + .addComponent(jScrollPane1) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, 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, 193, Short.MAX_VALUE)) + ); + }// //GEN-END:initComponents + + private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed + ProjectAssetManager projectAssetManager = mgr; + FakeApplication fakeApp = this.fakeApp; + if (fakeApp != null && mgr != null) { + new NewAppStateWizardAction(projectAssetManager, fakeApp).showWizard(); + } + }//GEN-LAST:event_jButton1ActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton jButton1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JToolBar jToolBar1; + // End of variables declaration//GEN-END:variables + + @Override + public void componentOpened() { + } + + @Override + public void componentClosed() { + } + + 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"); + } + + void readProperties(java.util.Properties p) { + String version = p.getProperty("version"); + } + + public ExplorerManager getExplorerManager() { + return explorerManager; + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateManagerNode.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateManagerNode.java new file mode 100644 index 000000000..4738624a7 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateManagerNode.java @@ -0,0 +1,109 @@ +/* + * 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.appstates; + +import com.jme3.app.state.AppState; +import com.jme3.gde.core.appstates.FakeApplication.FakeAppStateManager; +import java.util.LinkedList; +import java.util.List; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node; + +/** + * + * @author normenhansen + */ +public class AppStateManagerNode extends AbstractNode { + +// private static Image smallImage = +// ImageUtilities.loadImage("com/jme3/gde/core/filters/icons/eye.gif"); + + public AppStateManagerNode(FakeAppStateManager manager) { + super(new AppStateChildren(manager)); + setName("Loaded App States"); + manager.setNode(this); + } + +// @Override +// public Image getIcon(int type) { +// return smallImage; +// } +// +// @Override +// public Image getOpenedIcon(int type) { +// return smallImage; +// } + + public void refresh() { + //TODO: external refresh + ((AppStateChildren) getChildren()).doRefresh(); + } + + public static class AppStateChildren extends Children.Keys { + + private final FakeAppStateManager manager; + + public AppStateChildren(FakeAppStateManager manager) { + this.manager = manager; + } + + @Override + protected void addNotify() { + super.addNotify(); + setKeys(createKeys()); + } + + protected void doRefresh() { + addNotify(); + refresh(); + } + + protected void reorderNotify() { + setKeys(createKeys()); + } + + protected List createKeys() { + List keys = new LinkedList(); + List states; + states = manager.getAddedStates(); + keys.addAll(states); + return keys; + } + + @Override + protected Node[] createNodes(Object t) { + AppStateNode node = new AppStateNode((AppState) t, manager); + return new Node[]{node}; + } + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateNode.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateNode.java new file mode 100644 index 000000000..ad5f4e985 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/AppStateNode.java @@ -0,0 +1,191 @@ +/* + * 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.appstates; + +import com.jme3.app.state.AppState; +import com.jme3.app.state.AppStateManager; +import com.jme3.gde.core.properties.SceneExplorerProperty; +import com.jme3.gde.core.properties.ScenePropertyChangeListener; +import com.jme3.gde.core.util.PropertyUtils; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; +import org.openide.nodes.Node.Property; +import org.openide.nodes.Sheet; +import org.openide.util.Exceptions; + +/** + * + * @author normenhansen + */ +public class AppStateNode extends AbstractNode implements ScenePropertyChangeListener { + + protected AppState appState; + protected AppStateManager parent; +// private static Image icon; +// private static final String ICON_ENABLED = "com/jme3/gde/core/filters/icons/eye.gif"; +// private static final String ICON_DISABLED = "com/jme3/gde/core/filters/icons/crossedEye.gif"; + + public AppStateNode(AppState appState, AppStateManager parent) { + super(Children.LEAF); + this.parent = parent; + this.appState = appState; + setName(appState.getClass().getName()); + setDisplayName(appState.getClass().getSimpleName()); +// icon = ImageUtilities.loadImage(ICON_ENABLED); +// setIconBaseWithExtension(ICON_ENABLED); + } + +// @Override +// public Image getIcon(int type) { +// return icon; +// +// } +// +// @Override +// public Image getOpenedIcon(int type) { +// return icon; +// } +// +// public void toggleIcon(boolean enabled) { +// if (enabled) { +// icon = ImageUtilities.loadImage(ICON_ENABLED); +// +// } else { +// icon = ImageUtilities.loadImage(ICON_DISABLED); +// +// } +// fireIconChange(); +// } +// @Override +// public Action[] getActions(boolean context) { +// return new Action[]{ +// //Actions.alwaysEnabled(new EnableFiterAction(this), "Toggle enabled", "", false), +// // SystemAction.get(MoveUpAction.class), +// // SystemAction.get(MoveDownAction.class), +// null, // SystemAction.get(DeleteAction.class), +// }; +// } +// +// @Override +// public Action getPreferredAction() { +//// return Actions.alwaysEnabled(new EnableFiterAction(this), "Toggle enabled", "", false); +// return null; +// } + @Override + public boolean canDestroy() { + return true; + } + + @Override + public void destroy() throws IOException { + super.destroy(); + parent.detach(appState); + //TODO:hack + ((AppStateManagerNode) getParentNode()).refresh(); + } + + @Override + protected Sheet createSheet() { + Sheet sheet = super.createSheet(); + Object obj = appState; + if (obj == null) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message( + "AppState unexpectedly null", + NotifyDescriptor.WARNING_MESSAGE)); + 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(); + set.setDisplayName("AppState"); + set.setName(appState.getClass().getName()); + createFields(appState.getClass(), set, obj); + sheet.put(set); + + return sheet; + } + + protected Property makeProperty(Object obj, Class returntype, String method, String name) { + Property prop = null; + try { + //getExplorerObjectClass().cast(obj) + prop = new SceneExplorerProperty(appState.getClass().cast(obj), returntype, method, null, this); + 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 { + prop = new SceneExplorerProperty(appState.getClass().cast(obj), returntype, method, setter, this); + prop.setName(name); + } catch (NoSuchMethodException ex) { + Exceptions.printStackTrace(ex); + } + return prop; + } + + protected void createMethods(Class c, Sheet.Set set, Object obj) throws SecurityException { + for (Method method : c.getDeclaredMethods()) { + PropertyDescriptor prop = PropertyUtils.getPropertyDescriptor(c, method); + if (prop != null) { + set.put(makeProperty(obj, prop.getPropertyType(), prop.getReadMethod().getName(), prop.getWriteMethod().getName(), prop.getDisplayName())); + } + } + } + + protected void createFields(Class c, Sheet.Set set, Object obj) throws SecurityException { + 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())); + } + } + } + + public void propertyChange(String property, Object oldValue, Object newValue) { + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/Bundle.properties b/sdk/jme3-core/src/com/jme3/gde/core/appstates/Bundle.properties new file mode 100644 index 000000000..2a7141b4a --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/Bundle.properties @@ -0,0 +1,3 @@ +AppStateExplorerTopComponent.jButton1.text=attach.. +NewAppStateVisualPanel1.jLabel1.text=Select or enter AppState classname +NewAppStateVisualPanel1.jTextField1.text=com.mycompany.MyAppState diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/FakeApplication.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/FakeApplication.java new file mode 100644 index 000000000..1354c48cd --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/FakeApplication.java @@ -0,0 +1,425 @@ +/* + * 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.appstates; + +import com.jme3.app.Application; +import com.jme3.app.SimpleApplication; +import com.jme3.app.state.AppState; +import com.jme3.app.state.AppStateManager; +import com.jme3.asset.AssetManager; +import com.jme3.audio.AudioRenderer; +import com.jme3.audio.Listener; +import com.jme3.input.FlyByCamera; +import com.jme3.input.InputManager; +import com.jme3.renderer.Camera; +import com.jme3.renderer.RenderManager; +import com.jme3.renderer.Renderer; +import com.jme3.renderer.ViewPort; +import com.jme3.scene.Node; +import com.jme3.system.AppSettings; +import com.jme3.system.JmeContext; +import com.jme3.system.JmeContext.Type; +import com.jme3.system.Timer; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.util.Exceptions; + +/** + * TODO: Temporary implementation before new scene system! + * + * @author normenhansen + */ +public class FakeApplication extends SimpleApplication { +// private Lookup lookup; + + private Node rootNode; + private Node guiNode; + private AssetManager assetManager; + private Camera cam; + private FakeAppStateManager appStateManager; + private FakeRenderManager renderManager; + + public FakeApplication(Node rootNode, Node guiNode, AssetManager assetManager, Camera cam) { + this.rootNode = rootNode; + this.guiNode = guiNode; + this.assetManager = assetManager; + this.cam = cam; + this.appStateManager = new FakeAppStateManager(this); + } + + @Override + public void createCanvas() { + defaultFakeError(true); + } + + @Override + public void destroy() { + defaultFakeError(true); + } + + @Override + protected void destroyInput() { + defaultFakeError(true); + } + + @Override + public Future enqueue(Callable callable) { + return super.enqueue(callable); + } + + @Override + public void gainFocus() { + defaultFakeError(true); + } + + @Override + public AssetManager getAssetManager() { + return assetManager; + } + + @Override + public AudioRenderer getAudioRenderer() { + defaultFakeError(); + return null; + } + + @Override + public Camera getCamera() { + return cam; + } + + @Override + public JmeContext getContext() { + defaultFakeError(); + return null; + } + + @Override + public ViewPort getGuiViewPort() { + //TODO + defaultFakeError(); + return null; + } + + @Override + public InputManager getInputManager() { + defaultFakeError(); + return null; + } + + @Override + public Listener getListener() { + defaultFakeError(); + return null; + } + + @Override + public RenderManager getRenderManager() { + defaultFakeError(); + return null; + } + + @Override + public Renderer getRenderer() { + defaultFakeError(); + return null; + } + + @Override + public FakeAppStateManager getStateManager() { + return appStateManager; + } + + @Override + public Timer getTimer() { + defaultFakeError(); + return null; + } + + @Override + public ViewPort getViewPort() { + //TODO + defaultFakeError(); + return null; + } + + @Override + public boolean isPauseOnLostFocus() { + return true; + } + + @Override + public void loseFocus() { + defaultFakeError(true); + } + + @Override + public void initialize() { + defaultFakeError(true); + } + + @Override + public void handleError(String errMsg, Throwable t) { + defaultFakeError(true); + } + + @Override + public void requestClose(boolean esc) { + defaultFakeError(); + } + + @Override + public void reshape(int w, int h) { + defaultFakeError(); + } + + @Override + public void restart() { + defaultFakeError(); + } + + @Override + public void setAssetManager(AssetManager assetManager) { + defaultFakeError(true); + } + + @Override + public void setSettings(AppSettings settings) { + defaultFakeError(); + } + + @Override + public void setPauseOnLostFocus(boolean pauseOnLostFocus) { + defaultFakeError(); + } + + @Override + public void start() { + defaultFakeError(); + } + + @Override + public void start(Type contextType) { + defaultFakeError(); + } + + @Override + public void startCanvas() { + defaultFakeError(); + } + + @Override + public void startCanvas(boolean waitFor) { + defaultFakeError(); + } + + @Override + public void stop() { + defaultFakeError(); + } + + @Override + public void stop(boolean waitFor) { + defaultFakeError(); + } + + @Override + public void update() { + defaultFakeError(true); + } + + /* + * SimpleApplication + */ + @Override + public void simpleInitApp() { + defaultFakeError(true); + } + + @Override + public FlyByCamera getFlyByCamera() { + defaultFakeError(); + return null; + } + + @Override + public Node getGuiNode() { + return guiNode; + } + + @Override + public Node getRootNode() { + return rootNode; + } + + @Override + public boolean isShowSettings() { + return true; + } + + @Override + public void setDisplayFps(boolean show) { + defaultFakeError(); + } + + @Override + public void setDisplayStatView(boolean show) { + defaultFakeError(); + } + + @Override + public void setTimer(Timer timer) { + defaultFakeError(); + } + + @Override + public void setShowSettings(boolean showSettings) { + defaultFakeError(); + } + + @Override + public void simpleRender(RenderManager rm) { + defaultFakeError(); + } + + @Override + public void simpleUpdate(float tpf) { + defaultFakeError(); + } + + private class FakeRenderManager extends RenderManager { + + public FakeRenderManager(Renderer renderer) { + super(null); + } + //TODO: also nice messages + } + + /* + * Internal + */ + private void defaultFakeError() { + defaultFakeError(false); + } + + private void defaultFakeError(boolean severe) { + ByteArrayOutputStream str = new ByteArrayOutputStream(); + new Throwable().printStackTrace(new PrintStream(new BufferedOutputStream(str))); + String trace = "No stack trace available."; + try { + trace = str.toString("UTF-8"); + } catch (UnsupportedEncodingException ex) { + Exceptions.printStackTrace(ex); + } + int idx = trace.indexOf("com.jme3.gde"); + while (idx != -1) { + if (idx < 50) { + continue; + } else { + trace = trace.substring(0, idx); + break; + } + } + showError("Fake app is fake!" + (severe ? "And WTF are you trying to do anyway?\n" : "\n") + trace); + } + + private void showError(String msg) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message( + msg, + NotifyDescriptor.WARNING_MESSAGE)); + } + + public void updateFake(float tpf) { +// System.out.println("UPDATE"); + appStateManager.update(tpf); + } + + public void renderFake() { + appStateManager.render(renderManager); + } + + public static class FakeAppStateManager extends AppStateManager { + + private AppStateManagerNode node; + ArrayList states = new ArrayList(); + + public FakeAppStateManager(Application app) { + super(app); + } + + public List getAddedStates() { + return states; + } + + @Override + public boolean attach(AppState state) { + boolean ret = super.attach(state); + try { + states.add(state); + } catch (Exception e) { + Exceptions.printStackTrace(e); + } +// DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message( +// "attach state", +// NotifyDescriptor.WARNING_MESSAGE)); + if (node != null) { +// DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message( +// "refresh node", +// NotifyDescriptor.WARNING_MESSAGE)); + node.refresh(); + } + return ret; + } + + @Override + public boolean detach(AppState state) { + try { + states.remove(state); + } catch (Exception e) { + Exceptions.printStackTrace(e); + } + return super.detach(state); + } + + public void setNode(AppStateManagerNode node) { + this.node = node; + } + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.form b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.form new file mode 100644 index 000000000..9ae30e44b --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.form @@ -0,0 +1,85 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java new file mode 100644 index 000000000..e2f3726e9 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateVisualPanel1.java @@ -0,0 +1,209 @@ +/* + * 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.appstates; + +import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.*; +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 javax.swing.JPanel; +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.util.Exceptions; + +public final class NewAppStateVisualPanel1 extends JPanel { + + private Project proj; + + /** + * Creates new form NewCustomControlVisualPanel1 + */ + public NewAppStateVisualPanel1() { + initComponents(); + } + + @Override + public String getName() { + return "Select AppState"; + } + + public String getClassName() { + return jTextField1.getText(); + } + + private void scanControls() { + List sources = getSources(); + jList1.setListData(sources.toArray()); + } + + private List getSources() { + Sources sources = proj.getLookup().lookup(Sources.class); + final List list = new LinkedList(); + 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 set = new HashSet(); + set.add(ClassIndex.SearchScope.SOURCE); + Set> types = cpInfo.getClassIndex().getDeclaredTypes("", NameKind.PREFIX, set); + for (Iterator> it = types.iterator(); it.hasNext();) { + final ElementHandle elementHandle = it.next(); + JavaSource js = JavaSource.create(cpInfo); + try { + js.runUserActionTask(new Task() { + 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); + if (elem != null) { + List interfaces = elem.getInterfaces(); + for (TypeMirror typeMirror : interfaces) { + String interfaceName = typeMirror.toString(); + if ("com.jme3.app.state.AppState".equals(interfaceName)) { + list.add(elem.getQualifiedName().toString()); + } + } + TypeMirror superClass = elem.getSuperclass(); + String superClassName = superClass.toString(); + if ("com.jme3.app.state.AbstractAppState".equals(superClassName)) { + list.add(elem.getQualifiedName().toString()); + } + } + } + }, false); + } catch (Exception ioe) { + Exceptions.printStackTrace(ioe); + } + } + + } + } + } + return list; + } + + public void load(Project proj) { + this.proj = proj; + scanControls(); + } + + /** + * 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 javax.swing.JScrollPane(); + jList1 = new javax.swing.JList(); + jLabel1 = new javax.swing.JLabel(); + jTextField1 = new javax.swing.JTextField(); + + jList1.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public Object getElementAt(int i) { return strings[i]; } + }); + jList1.addListSelectionListener(new javax.swing.event.ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + updateClassName(evt); + } + }); + jScrollPane1.setViewportView(jList1); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(NewAppStateVisualPanel1.class, "NewAppStateVisualPanel1.jLabel1.text")); // NOI18N + + jTextField1.setText(org.openide.util.NbBundle.getMessage(NewAppStateVisualPanel1.class, "NewAppStateVisualPanel1.jTextField1.text")); // NOI18N + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 351, Short.MAX_VALUE) + .addComponent(jTextField1) + .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addContainerGap() + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 172, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + }// //GEN-END:initComponents + + private void updateClassName(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_updateClassName + Object obj = jList1.getSelectedValue(); + if (obj != null) { + jTextField1.setText(obj + ""); + } + }//GEN-LAST:event_updateClassName + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JLabel jLabel1; + private javax.swing.JList jList1; + private javax.swing.JScrollPane jScrollPane1; + private javax.swing.JTextField jTextField1; + // End of variables declaration//GEN-END:variables +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardAction.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardAction.java new file mode 100644 index 000000000..bdb00abdf --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardAction.java @@ -0,0 +1,168 @@ +/* + * 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.appstates; + +import com.jme3.app.Application; +import com.jme3.app.state.AbstractAppState; +import com.jme3.app.state.AppState; +import com.jme3.gde.core.assets.ProjectAssetManager; +import java.awt.Component; +import java.awt.Dialog; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.MessageFormat; +import java.util.List; +import javax.swing.JComponent; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.WizardDescriptor; +import org.openide.util.Exceptions; + +// An example action demonstrating how the wizard could be called from within +// your code. You can move the code below wherever you need, or register an action: +// @ActionID(category="...", id="com.jme3.gde.core.sceneexplorer.nodes.actions.impl.NewCustomControlWizardAction") +// @ActionRegistration(displayName="Open NewCustomControl Wizard") +// @ActionReference(path="Menu/Tools", position=...) +public final class NewAppStateWizardAction implements ActionListener { + + private WizardDescriptor.Panel[] panels; + ProjectAssetManager mgr; + Application fakeApp; + + public NewAppStateWizardAction(ProjectAssetManager mgr, Application fakeApp) { + this.mgr = mgr; + this.fakeApp = fakeApp; + } + + public void actionPerformed(ActionEvent e) { + //TODO: actual action to open/close via keyboard etc? + } + + protected void showWizard() { + WizardDescriptor wizardDescriptor = new WizardDescriptor(getPanels()); + // {0} will be replaced by WizardDesriptor.Panel.getComponent().getName() + wizardDescriptor.setTitleFormat(new MessageFormat("{0}")); + wizardDescriptor.setTitle("Add New AppState"); + wizardDescriptor.putProperty("asset_manager", mgr); + wizardDescriptor.putProperty("fake_app", fakeApp); + wizardDescriptor.putProperty("project", mgr.getProject()); + Dialog dialog = DialogDisplayer.getDefault().createDialog(wizardDescriptor); + dialog.setVisible(true); + dialog.toFront(); + boolean cancelled = wizardDescriptor.getValue() != WizardDescriptor.FINISH_OPTION; + if (!cancelled) { + AppState state = doCreateAppState(wizardDescriptor); + if (state != null) { + fakeApp.getStateManager().attach(state); + } + } + } + + protected AppState doCreateAppState(WizardDescriptor configuration) { + if (configuration == null) { + return null; + } + WizardDescriptor wizardDescriptor = (WizardDescriptor) configuration; + ProjectAssetManager manager = (ProjectAssetManager) wizardDescriptor.getProperty("asset_manager"); + List loaders = manager.getClassLoaders(); + + String className = (String) wizardDescriptor.getProperty("class_name"); + Class clazz = null; + try { + clazz = getClass().getClassLoader().loadClass(className); + } catch (ClassNotFoundException ex) { + } + for (ClassLoader classLoader : loaders) { + if (clazz == null) { + try { + clazz = classLoader.loadClass(className); + } catch (ClassNotFoundException ex) { + } + } + } + if (clazz != null) { + try { + Object contr = clazz.newInstance(); + //TODO: remove sillyness-test + if (contr instanceof AppState || contr instanceof AbstractAppState) { + return (AppState) contr; + } else { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("This is no AppState class!")); + } + } catch (InstantiationException ex) { + Exceptions.printStackTrace(ex); + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error instatiating class!")); + } catch (IllegalAccessException ex) { + Exceptions.printStackTrace(ex); + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error instatiating class!")); + } + } else { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Cannot find class: " + className + "\nMake sure the name is correct and the project is compiled,\nbest enable 'Save on Compile' in the project preferences.")); + } + return null; + } + + /** + * Initialize panels representing individual wizard's steps and sets various + * properties for them influencing wizard appearance. + */ + private WizardDescriptor.Panel[] getPanels() { + if (panels == null) { + panels = new WizardDescriptor.Panel[]{ + new NewAppStateWizardPanel1() + }; + String[] steps = new String[panels.length]; + for (int i = 0; i < panels.length; i++) { + Component c = panels[i].getComponent(); + // Default step name to component name of panel. Mainly useful + // for getting the name of the target chooser to appear in the + // list of steps. + steps[i] = c.getName(); + if (c instanceof JComponent) { // assume Swing components + JComponent jc = (JComponent) c; + // Sets step number of a component + // TODO if using org.openide.dialogs >= 7.8, can use WizardDescriptor.PROP_*: + jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i)); + // Sets steps names for a panel + jc.putClientProperty("WizardPanel_contentData", steps); + // Turn on subtitle creation on each step + jc.putClientProperty("WizardPanel_autoWizardStyle", Boolean.TRUE); + // Show steps on the left side with the image on the background + jc.putClientProperty("WizardPanel_contentDisplayed", Boolean.TRUE); + // Turn on numbering of all steps + jc.putClientProperty("WizardPanel_contentNumbered", Boolean.TRUE); + } + } + } + return panels; + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardPanel1.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardPanel1.java new file mode 100644 index 000000000..d4798c83d --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewAppStateWizardPanel1.java @@ -0,0 +1,117 @@ +/* + * 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.appstates; + +import com.jme3.gde.core.sceneexplorer.nodes.actions.impl.*; +import java.awt.Component; +import javax.swing.event.ChangeListener; +import org.netbeans.api.project.Project; +import org.openide.WizardDescriptor; +import org.openide.util.HelpCtx; + +public class NewAppStateWizardPanel1 implements WizardDescriptor.Panel { + + /** + * The visual component that displays this panel. If you need to access the + * component from this class, just use getComponent(). + */ + private Component component; + + // Get the visual component for the panel. In this template, the component + // is kept separate. This can be more efficient: if the wizard is created + // but never displayed, or not all panels are displayed, it is better to + // create only those which really need to be visible. + public Component getComponent() { + if (component == null) { + component = new NewAppStateVisualPanel1(); + } + return component; + } + + public HelpCtx getHelp() { + // Show no Help button for this panel: + return HelpCtx.DEFAULT_HELP; + // If you have context help: + // return new HelpCtx(SampleWizardPanel1.class); + } + + public boolean isValid() { + // If it is always OK to press Next or Finish, then: + return true; + // If it depends on some condition (form filled out...), then: + // return someCondition(); + // and when this condition changes (last form field filled in...) then: + // fireChangeEvent(); + // and uncomment the complicated stuff below. + } + + public final void addChangeListener(ChangeListener l) { + } + + public final void removeChangeListener(ChangeListener l) { + } + /* + private final Set listeners = new HashSet(1); // or can use ChangeSupport in NB 6.0 + public final void addChangeListener(ChangeListener l) { + synchronized (listeners) { + listeners.add(l); + } + } + public final void removeChangeListener(ChangeListener l) { + synchronized (listeners) { + listeners.remove(l); + } + } + protected final void fireChangeEvent() { + Iterator it; + synchronized (listeners) { + it = new HashSet(listeners).iterator(); + } + ChangeEvent ev = new ChangeEvent(this); + while (it.hasNext()) { + it.next().stateChanged(ev); + } + } + */ + + // You can use a settings object to keep track of state. Normally the + // settings object will be the WizardDescriptor, so you can use + // WizardDescriptor.getProperty & putProperty to store information entered + // by the user. + public void readSettings(Object settings) { + ((NewAppStateVisualPanel1) component).load((Project)((WizardDescriptor) settings).getProperty("project")); + } + + public void storeSettings(Object settings) { + ((WizardDescriptor) settings).putProperty("class_name", ((NewAppStateVisualPanel1) component).getClassName()); + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java b/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java index 14734fd7e..015fa5228 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/scene/SceneApplication.java @@ -24,6 +24,7 @@ */ package com.jme3.gde.core.scene; +import com.jme3.gde.core.appstates.FakeApplication; import com.jme3.app.Application; import com.jme3.app.StatsView; import com.jme3.bullet.BulletAppState; @@ -116,6 +117,7 @@ public class SceneApplication extends Application implements LookupProvider { boolean useCanvas = false; private BulletAppState physicsState; private Thread thread; + private FakeApplication fakeApp; public SceneApplication() { progressHandle.start(7); @@ -265,6 +267,7 @@ public class SceneApplication extends Application implements LookupProvider { } try { super.update(); + FakeApplication fakap=fakeApp; float tpf = timer.getTimePerFrame(); camLight.setPosition(cam.getLocation()); secondCounter += tpf; @@ -274,12 +277,18 @@ public class SceneApplication extends Application implements LookupProvider { secondCounter = 0.0f; } getStateManager().update(tpf); + if(fakap!=null){ + fakap.updateFake(tpf); + } rootNode.updateLogicalState(tpf); guiNode.updateLogicalState(tpf); toolsNode.updateLogicalState(tpf); rootNode.updateGeometricState(); guiNode.updateGeometricState(); toolsNode.updateGeometricState(); + if(fakap!=null){ + fakap.renderFake(); + } getStateManager().render(renderManager); renderManager.render(tpf, context.isRenderable()); getStateManager().postRender(); @@ -619,4 +628,12 @@ public class SceneApplication extends Application implements LookupProvider { public boolean isAwt() { return java.awt.EventQueue.isDispatchThread(); } + + public FakeApplication getFakeApp() { + return fakeApp; + } + + public void setFakeApp(FakeApplication fakeApp) { + this.fakeApp = fakeApp; + } } diff --git a/sdk/jme3-core/src/com/jme3/gde/core/util/PropertyUtils.java b/sdk/jme3-core/src/com/jme3/gde/core/util/PropertyUtils.java index 24b3ba6b1..fa6a434b2 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/util/PropertyUtils.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/util/PropertyUtils.java @@ -34,6 +34,8 @@ package com.jme3.gde.core.util; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; +import java.lang.reflect.Method; +import org.openide.util.Exceptions; /** * @@ -43,8 +45,18 @@ public class PropertyUtils { public static PropertyDescriptor getPropertyDescriptor(Class c, Field field) { 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); prop.setDisplayName(splitCamelCase(field.getName())); @@ -56,6 +68,29 @@ public class PropertyUtils { } } + public static PropertyDescriptor getPropertyDescriptor(Class c, Method meth) { + try { + + String name = meth.getName(); + if (name.startsWith("get") || name.startsWith("set")) { + name = name.substring(3); + if (name.length() > 0) { + name = Character.toLowerCase(name.charAt(0)) + name.substring(1); + } + } else { + return null; + } + PropertyDescriptor prop = new PropertyDescriptor(name, c); + + prop.setDisplayName(splitCamelCase(meth.getName())); + + return prop; + } catch (IntrospectionException ex) { + //System.out.println(ex.getMessage()); + return null; + } + } + static String splitCamelCase(String s) { s = capitalizeString(s); return s.replaceAll(