diff --git a/jme3-core/src/com/jme3/gde/core/sceneexplorer/SceneExplorerTopComponent.java b/jme3-core/src/com/jme3/gde/core/sceneexplorer/SceneExplorerTopComponent.java index ff08e043..7221deba 100644 --- a/jme3-core/src/com/jme3/gde/core/sceneexplorer/SceneExplorerTopComponent.java +++ b/jme3-core/src/com/jme3/gde/core/sceneexplorer/SceneExplorerTopComponent.java @@ -79,12 +79,13 @@ public final class SceneExplorerTopComponent extends TopComponent implements Exp private static final Logger logger = Logger.getLogger(SceneExplorerTopComponent.class.getName()); private static SceneExplorerTopComponent instance; private static final String PREFERRED_ID = "SceneExplorerTopComponent"; -// private final Result nodeSelectionResult; - private AbstractSceneExplorerNode selectedSpatial; - private AbstractSceneExplorerNode lastSelected; + + private AbstractSceneExplorerNode[] selectedSpatials; + private AbstractSceneExplorerNode[] lastSelected; private final Map materialChangeProviders = new HashMap<>(); private final Map> materialChangeListeners = new HashMap<>(); - private transient ExplorerManager explorerManager = new ExplorerManager(); + + private final transient ExplorerManager explorerManager = new ExplorerManager(); public SceneExplorerTopComponent() { initComponents(); @@ -149,18 +150,12 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }// //GEN-END:initComponents private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed - if (selectedSpatial == null) { + if (selectedSpatials == null) { return; } - SwingUtilities.invokeLater(() -> { - Node rootNode = SceneExplorerTopComponent.findInstance().getExplorerManager().getRootContext(); - if (rootNode instanceof JmeNode jmeNode) { - SceneApplication.getApplication().enqueue(new RefreshJmeSpatial(jmeNode, selectedSpatial.getName())); - } else { - selectedSpatial.refresh(false); - } - }); - + for (AbstractSceneExplorerNode node: selectedSpatials) { + node.refresh(false); + } }//GEN-LAST:event_jButton1ActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JScrollPane explorerScrollPane; @@ -188,13 +183,13 @@ public static synchronized SceneExplorerTopComponent getDefault() { * @return */ public static synchronized SceneExplorerTopComponent findInstance() { - TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); - if (win == null) { + TopComponent window = WindowManager.getDefault().findTopComponent(PREFERRED_ID); + if (window == null) { logger.warning( "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system."); return getDefault(); } - if (win instanceof SceneExplorerTopComponent sceneExplorerTopComponent) { + if (window instanceof SceneExplorerTopComponent sceneExplorerTopComponent) { return sceneExplorerTopComponent; } logger.warning( @@ -227,27 +222,20 @@ public void componentClosed() { SceneApplication.getApplication().removeSceneListener(this); // TODO add custom code on component closing } - + void writeProperties(java.util.Properties p) { - // better to version settings since initial version as advocated at - // http://wiki.apidesign.org/wiki/PropertyFiles + // Required. Do not remove. p.setProperty("version", "1.0"); - // TODO store your settings } - + Object readProperties(java.util.Properties p) { + // Required. Do not remove. if (instance == null) { instance = this; } - instance.readPropertiesImpl(p); return instance; } - private void readPropertiesImpl(java.util.Properties p) { - // TODO read your settings according to their version - - } - @Override protected String preferredID() { return PREFERRED_ID; @@ -263,18 +251,16 @@ public ExplorerManager getExplorerManager() { return explorerManager; } - public void setSelectedNode(AbstractSceneExplorerNode node) { - selectedSpatial = node; - if (node != null) { - lastSelected = node; + public void setSelectedNode(AbstractSceneExplorerNode[] nodes) { + selectedSpatials = nodes; + if (nodes != null) { + lastSelected = nodes; } try { - if (node != null) { - explorerManager.setSelectedNodes(new Node[]{node}); -// setActivatedNodes(new Node[]{node}); + if (nodes != null) { + explorerManager.setSelectedNodes(nodes); } else { explorerManager.setSelectedNodes(new Node[]{}); -// setActivatedNodes(new Node[]{}); } } catch (PropertyVetoException ex) { Exceptions.printStackTrace(ex); @@ -309,11 +295,11 @@ public void sceneClosed(SceneRequest request) { @Override public void previewCreated(PreviewRequest request) { } - + /** * @return the selectedSpatial */ - public AbstractSceneExplorerNode getLastSelected() { + public AbstractSceneExplorerNode[] getLastSelected() { return lastSelected; } diff --git a/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/MotionPathPopup.java b/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/MotionPathPopup.java index acf10508..3c8b60fb 100644 --- a/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/MotionPathPopup.java +++ b/jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/MotionPathPopup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2010 jMonkeyEngine + * Copyright (c) 2009-2024 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -107,14 +107,20 @@ public void actionPerformed(ActionEvent e) { Vector3f pos; SceneToolController controller = SceneApplication.getApplication().getStateManager().getState(SceneToolController.class); - if (controller != null && (!controller.getCursorLocation().equals(Vector3f.ZERO))) { // Vector3f.ZERO means not yet clicked + // Vector3f.ZERO means not yet clicked + if (controller != null && (!controller.getCursorLocation().equals(Vector3f.ZERO))) { pos = controller.getCursorLocation().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0); // Shifting up so a) Netbeans isn't merging Waypoints and b) it's visible } else { - AbstractSceneExplorerNode node = SceneExplorerTopComponent.findInstance().getLastSelected(); - if (node instanceof JmeVector3f) { // null instanceof JmeVector3f == false - pos = ((JmeVector3f)node).getVector3f().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0); + AbstractSceneExplorerNode[] nodes = SceneExplorerTopComponent.findInstance().getLastSelected(); + if(nodes == null || nodes.length == 0) { + return; + } + final AbstractSceneExplorerNode node = nodes[0]; + if (node instanceof JmeVector3f jmeVector3f) { + pos = jmeVector3f.getVector3f().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0); } else { - pos = new Vector3f(0f, 1.0f, 0f); // Default is a bit over the Center + // Default is a bit over the Center + pos = new Vector3f(0f, 1.0f, 0f); } } diff --git a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java index 1b827c89..2f9a021b 100644 --- a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java +++ b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/SceneComposerTopComponent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2023 jMonkeyEngine + * Copyright (c) 2009-2024 jMonkeyEngine * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1078,11 +1078,10 @@ private void jSlider1StateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRS // End of variables declaration//GEN-END:variables private void emit(Spatial root) { - if (root instanceof ParticleEmitter) { - ((ParticleEmitter) root).killAllParticles(); - ((ParticleEmitter) root).emitAllParticles(); - } else if (root instanceof Node) { - Node n = (Node) root; + if (root instanceof ParticleEmitter particleEmitter) { + particleEmitter.killAllParticles(); + particleEmitter.emitAllParticles(); + } else if (root instanceof Node n) { for (Spatial child : n.getChildren()) { emit(child); } @@ -1112,14 +1111,14 @@ public static synchronized SceneComposerTopComponent getDefault() { * @return */ public static synchronized SceneComposerTopComponent findInstance() { - TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID); - if (win == null) { + TopComponent window = WindowManager.getDefault().findTopComponent(PREFERRED_ID); + if (window == null) { Logger.getLogger(SceneComposerTopComponent.class.getName()).warning( "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system."); return getDefault(); } - if (win instanceof SceneComposerTopComponent) { - return (SceneComposerTopComponent) win; + if (window instanceof SceneComposerTopComponent sceneComposerTopComponent) { + return sceneComposerTopComponent; } Logger.getLogger(SceneComposerTopComponent.class.getName()).warning( "There seem to be multiple components with the '" + PREFERRED_ID @@ -1203,15 +1202,11 @@ protected String preferredID() { } private void setSelectedObjectText(final String text) { - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - if (text != null) { - ((TitledBorder) jPanel4.getBorder()).setTitle("Utilities - " + text); - } else { - ((TitledBorder) jPanel4.getBorder()).setTitle("Utilities - no spatial selected"); - } + java.awt.EventQueue.invokeLater(() -> { + if (text != null) { + ((TitledBorder) jPanel4.getBorder()).setTitle("Utilities - " + text); + } else { + ((TitledBorder) jPanel4.getBorder()).setTitle("Utilities - no spatial selected"); } }); } @@ -1255,15 +1250,15 @@ private void setSceneInfo(final JmeNode jmeNode, final FileObject file, final bo } } - public void openScene(Spatial spat, AssetDataObject file, ProjectAssetManager manager) { + public void openScene(Spatial spatial, AssetDataObject file, ProjectAssetManager manager) { cleanupControllers(); SceneApplication.getApplication().addSceneListener(this); Node node; - if (spat instanceof Node) { - node = (Node) spat; + if (spatial instanceof Node node1) { + node = node1; } else { node = new Node(); - node.attachChild(spat); + node.attachChild(spatial); } JmeNode jmeNode = NodeUtility.createNode(node, file, false); SceneRequest request = new SceneRequest(this, jmeNode, manager); @@ -1318,28 +1313,30 @@ public void resultChanged(LookupEvent ev) { return; } Collection items = (Collection) result.allInstances(); - for (AbstractSceneExplorerNode node : items) { - if (select(node)) { - return; - } - } + + AbstractSceneExplorerNode[] abstractNodes = new AbstractSceneExplorerNode[items.size()]; + SceneViewerTopComponent.findInstance().setActivatedNodes(items.toArray(org.openide.nodes.Node[]::new)); + items.toArray(abstractNodes); + select(abstractNodes); } - private boolean select(AbstractSceneExplorerNode node) { + private boolean select(AbstractSceneExplorerNode[] nodes) { + if( nodes.length == 0) { + return false; + } + AbstractSceneExplorerNode first = nodes[0]; if (editorController != null) { - editorController.setSelectedExplorerNode(node); + editorController.setSelectedExplorerNode(first); } - if (node instanceof JmeSpatial) { - selectSpatial(((JmeSpatial) node).getLookup().lookup(Spatial.class)); - SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{node}); - SceneExplorerTopComponent.findInstance().setSelectedNode(node); + if (first instanceof JmeSpatial jmeSpatial) { + selectSpatial(jmeSpatial.getLookup().lookup(Spatial.class)); + SceneExplorerTopComponent.findInstance().setSelectedNode(nodes); return true; } else if (toolController != null) { - Spatial selectedGizmo = toolController.getMarker(node); + Spatial selectedGizmo = toolController.getMarker(first); if (selectedGizmo != null) { selectSpatial(selectedGizmo); - SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{node}); - SceneExplorerTopComponent.findInstance().setSelectedNode(node); + SceneExplorerTopComponent.findInstance().setSelectedNode(nodes); return true; } } @@ -1356,8 +1353,8 @@ private void selectSpatial(Spatial selection) { } else if (toolController != null) { toolController.updateSelection(selection); } - if (selection instanceof Node) { - setSelectedObjectText(((Node) selection).getName()); + if (selection instanceof Node node) { + setSelectedObjectText(node.getName()); } else if (selection instanceof Spatial) { setSelectedObjectText(selection.getName()); } else { @@ -1423,57 +1420,53 @@ public void sceneOpened(SceneRequest request) { editorController.setTerrainLodCamera(); final SpatialAssetDataObject dobj = ((SpatialAssetDataObject) currentRequest.getDataObject()); - listener = new ProjectAssetManager.ClassPathChangeListener() { - - @Override - public void classPathChanged(final ProjectAssetManager manager) { - if (dobj.isModified()) { - Confirmation msg = new NotifyDescriptor.Confirmation( - "Classes have been changed, save and reload scene?", - NotifyDescriptor.OK_CANCEL_OPTION, - NotifyDescriptor.INFORMATION_MESSAGE); - Object result = DialogDisplayer.getDefault().notify(msg); - if (!NotifyDescriptor.OK_OPTION.equals(result)) { - return; - } - try { - dobj.saveAsset(); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - } + listener = (final ProjectAssetManager manager) -> { + if (dobj.isModified()) { + Confirmation msg = new NotifyDescriptor.Confirmation( + "Classes have been changed, save and reload scene?", + NotifyDescriptor.OK_CANCEL_OPTION, + NotifyDescriptor.INFORMATION_MESSAGE); + Object result1 = DialogDisplayer.getDefault().notify(msg); + if (!NotifyDescriptor.OK_OPTION.equals(result1)) { + return; } - Runnable call = new Runnable() { - - @Override - public void run() { - ProgressHandle progressHandle = ProgressHandle.createHandle("Reloading Scene.."); - progressHandle.start(); - try { - manager.clearCache(); - final Spatial asset = dobj.loadAsset(); - if (asset != null) { - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - SceneComposerTopComponent composer = SceneComposerTopComponent.findInstance(); - composer.openScene(asset, dobj, manager); - } - }); - } else { - Confirmation msg = new NotifyDescriptor.Confirmation( - "Error opening " + dobj.getPrimaryFile().getNameExt(), - NotifyDescriptor.OK_CANCEL_OPTION, - NotifyDescriptor.ERROR_MESSAGE); - DialogDisplayer.getDefault().notify(msg); - } - } finally { - progressHandle.finish(); + try { + dobj.saveAsset(); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + Runnable call = new Runnable() { + + @Override + public void run() { + ProgressHandle progressHandle = ProgressHandle.createHandle("Reloading Scene.."); + progressHandle.start(); + try { + manager.clearCache(); + final Spatial asset = dobj.loadAsset(); + if (asset != null) { + java.awt.EventQueue.invokeLater(new Runnable() { + + @Override + public void run() { + SceneComposerTopComponent composer = SceneComposerTopComponent.findInstance(); + composer.openScene(asset, dobj, manager); + } + }); + } else { + Confirmation msg = new NotifyDescriptor.Confirmation( + "Error opening " + dobj.getPrimaryFile().getNameExt(), + NotifyDescriptor.OK_CANCEL_OPTION, + NotifyDescriptor.ERROR_MESSAGE); + DialogDisplayer.getDefault().notify(msg); } + } finally { + progressHandle.finish(); } - }; - new Thread(call).start(); - } + } + }; + new Thread(call).start(); }; // currentRequest.getManager().addClassPathEventListener(listener); } diff --git a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java index 4f435f3b..64510788 100644 --- a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java +++ b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/SelectTool.java @@ -1,10 +1,38 @@ /* - * To change this template, choose Tools | Templates and open the template in - * the editor. + * Copyright (c) 2009-2024 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.scenecomposer.tools; import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeSpatial; import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; @@ -98,7 +126,7 @@ private void doSelect() { JmeSpatial n = rootNode.getChild(selec); if (n != null) { SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{n}); - SceneExplorerTopComponent.findInstance().setSelectedNode(n); + SceneExplorerTopComponent.findInstance().setSelectedNode(new AbstractSceneExplorerNode[]{n}); } } }); diff --git a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java index 2f910a0f..b0a6d359 100644 --- a/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java +++ b/jme3-scenecomposer/src/com/jme3/gde/scenecomposer/tools/shortcuts/DuplicateShortcut.java @@ -1,12 +1,39 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Copyright (c) 2009-2024 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.scenecomposer.tools.shortcuts; import com.jme3.asset.AssetManager; import com.jme3.gde.core.sceneexplorer.SceneExplorerTopComponent; +import com.jme3.gde.core.sceneexplorer.nodes.AbstractSceneExplorerNode; import com.jme3.gde.core.sceneexplorer.nodes.JmeNode; import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent; import com.jme3.gde.core.undoredo.AbstractUndoableSceneEdit; @@ -57,7 +84,11 @@ public void activate(AssetManager manager, Node toolNode, Node onTopToolNode, Sp private void duplicate() { Spatial selected = toolController.getSelectedSpatial(); - + + if(selected == null) { + return; + } + Spatial clone = selected.clone(); clone.move(1, 0, 1); @@ -67,28 +98,17 @@ private void duplicate() { final Spatial cloned = clone; final JmeNode rootNode = toolController.getRootNode(); refreshSelected(rootNode, selected.getParent()); - - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - if (cloned != null) { - SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); - SceneExplorerTopComponent.findInstance().setSelectedNode(rootNode.getChild(cloned)); - } - } + + java.awt.EventQueue.invokeLater(() -> { + SceneViewerTopComponent.findInstance().setActivatedNodes(new org.openide.nodes.Node[]{rootNode.getChild(cloned)}); + SceneExplorerTopComponent.findInstance().setSelectedNode(new AbstractSceneExplorerNode[]{rootNode.getChild(cloned)}); }); - toolController.updateSelection(selected); } private void refreshSelected(final JmeNode jmeRootNode, final Node parent) { - java.awt.EventQueue.invokeLater(new Runnable() { - - @Override - public void run() { - jmeRootNode.getChild(parent).refresh(false); - } + java.awt.EventQueue.invokeLater(() -> { + jmeRootNode.getChild(parent).refresh(false); }); } @@ -119,8 +139,8 @@ public void draggedSecondary(Vector2f screenCoord, boolean pressed, JmeNode root private class DuplicateUndo extends AbstractUndoableSceneEdit { - private Spatial spatial; - private Node parent; + private final Spatial spatial; + private final Node parent; DuplicateUndo(Spatial spatial, Node parent) { this.spatial = spatial;