From 8fc897f3b7f9b5af20c6ba3bec08876d5c12e2bd Mon Sep 17 00:00:00 2001 From: "nor..67" Date: Sat, 29 Jun 2013 18:51:56 +0000 Subject: [PATCH] SDK: - commit disabled code to save scene from scratch git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10685 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../gde/core/appstates/NewSceneSaveNode.java | 129 ++++++++++++++++++ .../gde/core/appstates/RunAppStateAction.java | 123 ++++++++++++----- 2 files changed, 217 insertions(+), 35 deletions(-) create mode 100644 sdk/jme3-core/src/com/jme3/gde/core/appstates/NewSceneSaveNode.java diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewSceneSaveNode.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewSceneSaveNode.java new file mode 100644 index 000000000..da82e2b09 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/NewSceneSaveNode.java @@ -0,0 +1,129 @@ +/* + * 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.export.binary.BinaryExporter; +import com.jme3.gde.core.scene.SceneApplication; +import com.jme3.gde.core.scene.SceneRequest; +import com.jme3.scene.Spatial; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.Callable; +import javax.swing.filechooser.FileFilter; +import org.netbeans.api.progress.ProgressHandle; +import org.netbeans.api.progress.ProgressHandleFactory; +import org.openide.DialogDisplayer; +import org.openide.NotifyDescriptor; +import org.openide.awt.StatusDisplayer; +import org.openide.cookies.SaveCookie; +import org.openide.filesystems.FileChooserBuilder; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.nodes.AbstractNode; +import org.openide.nodes.Children; + +/** + * Node for a not yet existing scene, can be saved as j3o + * @author normenhansen + */ +public class NewSceneSaveNode extends AbstractNode implements SaveCookie { + + private final SceneRequest request; + + public NewSceneSaveNode(SceneRequest nodeToSave) { + super(Children.LEAF); + request = nodeToSave; + getCookieSet().assign(SaveCookie.class, this); + + } + + @Override + public String toString() { + return "NewSceneSaveNode(" + getDisplayName() + ")"; + } + + public void save() throws IOException { + FileChooserBuilder builder = new FileChooserBuilder(NewSceneSaveNode.class); + builder.addFileFilter(new FileFilter() { + @Override + public boolean accept(File f) { + if (f.getName().toLowerCase().trim().endsWith(".j3o")) { + return true; + } + return false; + } + + @Override + public String getDescription() { + return "j3o Files"; + } + }); + + final File file = builder.showSaveDialog(); + if (file == null) { + return; + } + SceneApplication.getApplication().enqueue(new Callable() { + public Void call() throws Exception { + Spatial node = request.getRootNode(); + if (node == null) { + return null; + } + if (file.exists()) { + NotifyDescriptor.Confirmation mesg = new NotifyDescriptor.Confirmation("File exists, overwrite?", + "Not Saved", + NotifyDescriptor.YES_NO_OPTION, NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(mesg); + if (mesg.getValue() != NotifyDescriptor.Confirmation.YES_OPTION) { + return null; + } + } + ProgressHandle progressHandle = ProgressHandleFactory.createHandle("Saving File.."); + progressHandle.start(); + try { + BinaryExporter exp = BinaryExporter.getInstance(); + exp.save(node, file); + } catch (Exception e) { + } finally { + FileObject fo = FileUtil.toFileObject(file); + if (fo != null) { + StatusDisplayer.getDefault().setStatusText(fo + " saved."); + fo.getParent().refresh(); + } + } + progressHandle.finish(); + return null; + } + }); + + } +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java b/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java index e3c24cf65..2d2fe665b 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/appstates/RunAppStateAction.java @@ -32,8 +32,11 @@ package com.jme3.gde.core.appstates; import com.jme3.app.state.AppState; +import com.jme3.gde.core.assets.ProjectAssetManager; import com.jme3.gde.core.scene.FakeApplication; +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.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; @@ -50,6 +53,8 @@ import org.netbeans.api.java.source.CancellableTask; import org.netbeans.api.java.source.CompilationController; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.SourceUtils; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.awt.ActionID; @@ -69,7 +74,6 @@ id = "com.jme3.gde.core.appstates.RunAppStateAction") @ActionRegistration( displayName = "#CTL_RunAppState") @ActionReferences({ - @ActionReference(path = "Toolbars/Build", position = 325), @ActionReference(path = "Loaders/text/x-java/Actions", position = 1050), @ActionReference(path = "Editors/text/x-java/Popup", position = 1740) }) @@ -77,22 +81,19 @@ displayName = "#CTL_RunAppState") public class RunAppStateAction implements ContextAwareAction { private static final Logger logger = Logger.getLogger(RunAppStateAction.class.getName()); - private String className; - private JavaSource source; + private final ActionConfig config; public RunAppStateAction() { - className = null; - source = null; + config = null; } - public RunAppStateAction(String className, JavaSource src) { - this.className = className; - this.source = src; + private RunAppStateAction(ActionConfig config) { + this.config = config; } public Action createContextAwareInstance(Lookup actionContext) { - checkData(actionContext, "com.jme3.app.state.AppState"); - return new RunAppStateAction(className, source); + ActionConfig config = checkData(actionContext, "com.jme3.app.state.AppState"); + return new RunAppStateAction(config); } public Object getValue(String key) { @@ -109,7 +110,7 @@ public class RunAppStateAction implements ContextAwareAction { } public boolean isEnabled() { - return className != null; + return config != null ? config.className != null : false; } public void addPropertyChangeListener(PropertyChangeListener listener) { @@ -120,47 +121,72 @@ public class RunAppStateAction implements ContextAwareAction { public void actionPerformed(ActionEvent e) { //TODO: better way to access scene request + if (config == null) { + logger.log(Level.SEVERE, "Performing unconfigured RunAppState action"); + return; + } SceneRequest req = SceneApplication.getApplication().getCurrentSceneRequest(); if (req != null) { FakeApplication app = req.getFakeApp(); - try { - AppState state = (AppState) app.getClassByName(className).newInstance(); - app.getStateManager().attach(state); - AppStateExplorerTopComponent.openExplorer(); - } catch (InstantiationException ex) { - DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, make sure it has an empty constructor!\n" + ex.getMessage())); - Exceptions.printStackTrace(ex); - } catch (IllegalAccessException ex) { - DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, make sure it has an empty constructor!\n" + ex.getMessage())); - Exceptions.printStackTrace(ex); - } catch (Exception ex) { - DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, exception when creating!\n" + ex.getMessage())); - Exceptions.printStackTrace(ex); - } + assert (app != null); + attachState(app); } else { DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("No Scene opened to attach to,\nopen a j3o scene.")); - logger.log(Level.INFO, "No Scene Request available"); + if(5==5) + return; + if (config.manager != null) { + logger.log(Level.INFO, "Try request scene.."); + //TODO: rootNode is assigned in SceneApplication.. more elegant system (with scene lookup) + final SceneRequest sceneRequest = new SceneRequest(this, config.manager); + sceneRequest.setWindowTitle("New Scene"); + sceneRequest.setDataNode(new NewSceneSaveNode(sceneRequest)); + SceneApplication.getApplication().addSceneListener(new SceneListener() { + public void sceneOpened(SceneRequest request) { + if (request == sceneRequest) { + FakeApplication app = request.getFakeApp(); + attachState(app); + } + } + + public void sceneClosed(SceneRequest request) { + if (request == sceneRequest) { + SceneApplication.getApplication().removeSceneListener(this); + } + } + + public void previewCreated(PreviewRequest request) { + } + }); + SceneApplication.getApplication().openScene(sceneRequest); + } else { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Not a jME project!")); + } } } - - private void checkData(Lookup actionContext, final String name) { - source = null; - className = null; + + private ActionConfig checkData(Lookup actionContext, final String name) { + final ActionConfig ret = new ActionConfig(); try { DataObject dObj = actionContext.lookup(DataObject.class); if (dObj == null) { logger.log(Level.FINE, "No DataObject"); - return; + return null; + } + Project proj = FileOwnerQuery.getOwner(dObj.getPrimaryFile());; + if (proj != null) { + ret.manager = proj.getLookup().lookup(ProjectAssetManager.class); + } else { + logger.log(Level.INFO, "Project null"); } FileObject fObj = dObj.getPrimaryFile(); if (fObj == null) { logger.log(Level.FINE, "No FileObject"); - return; + return null; } final JavaSource src = JavaSource.forFileObject(fObj); if (src == null) { logger.log(Level.FINE, "No JavaSource"); - return; + return null; } CancellableTask task = new CancellableTask() { public void run(CompilationController controller) throws IOException { @@ -185,8 +211,8 @@ public class RunAppStateAction implements ContextAwareAction { TypeMirror elementType = myElement.asType(); logger.log(Level.FINE, "Check {0} against {1}", new Object[]{elementType, appState}); if (elementType != null && SourceUtils.checkTypesAssignable(controller, elementType, appState)) { - source = src; - className = elementName; + ret.source = src; + ret.className = elementName; } } } @@ -197,8 +223,35 @@ public class RunAppStateAction implements ContextAwareAction { } }; src.runUserActionTask(task, true); + return ret; } catch (IOException ex) { Exceptions.printStackTrace(ex); } + return null; + } + + private void attachState(FakeApplication app) { + try { + assert (config.className != null); + AppState state = (AppState) app.getClassByName(config.className).newInstance(); + app.getStateManager().attach(state); + AppStateExplorerTopComponent.openExplorer(); + } catch (InstantiationException ex) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, is the project compiled?\nAlso make sure it has an empty constructor!\n" + ex.getMessage())); + Exceptions.printStackTrace(ex); + } catch (IllegalAccessException ex) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, is the project compiled?\nAlso make sure it has an empty constructor!\n" + ex.getMessage())); + Exceptions.printStackTrace(ex); + } catch (Exception ex) { + DialogDisplayer.getDefault().notifyLater(new NotifyDescriptor.Message("Error creating AppState, exception when creating!\n" + ex.getMessage())); + Exceptions.printStackTrace(ex); + } + } + + private static class ActionConfig { + + public String className; + public JavaSource source; + public ProjectAssetManager manager; } } \ No newline at end of file