Skip to content

Commit 52a6e63

Browse files
committed
Allow node actions on multiple selected nodes (Delete, etc)
1 parent 0e0e4f2 commit 52a6e63

File tree

5 files changed

+200
-170
lines changed

5 files changed

+200
-170
lines changed

jme3-core/src/com/jme3/gde/core/sceneexplorer/SceneExplorerTopComponent.java

Lines changed: 37 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2010 jMonkeyEngine
2+
* Copyright (c) 2009-2024 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -77,11 +77,13 @@ public final class SceneExplorerTopComponent extends TopComponent implements Exp
7777
private static final Logger logger = Logger.getLogger(SceneExplorerTopComponent.class.getName());
7878
private static SceneExplorerTopComponent instance;
7979
private static final String PREFERRED_ID = "SceneExplorerTopComponent";
80-
// private final Result<AbstractSceneExplorerNode> nodeSelectionResult;
81-
private AbstractSceneExplorerNode selectedSpatial;
82-
private AbstractSceneExplorerNode lastSelected;
83-
private Map<String, MaterialChangeProvider> materialChangeProviders = new HashMap<String, MaterialChangeProvider>();
84-
private Map<String, List<MaterialChangeListener>> materialChangeListeners = new HashMap<String, List<MaterialChangeListener>>();
80+
81+
private AbstractSceneExplorerNode[] selectedSpatials;
82+
private AbstractSceneExplorerNode[] lastSelected;
83+
private final Map<String, MaterialChangeProvider> materialChangeProviders = new HashMap<>();
84+
private final Map<String, List<MaterialChangeListener>> materialChangeListeners = new HashMap<>();
85+
86+
private final transient ExplorerManager explorerManager = new ExplorerManager();
8587

8688
public SceneExplorerTopComponent() {
8789
initComponents();
@@ -90,8 +92,6 @@ public SceneExplorerTopComponent() {
9092
setToolTipText(NbBundle.getMessage(SceneExplorerTopComponent.class, "HINT_SceneExplorerTopComponent"));
9193
setIcon(IconList.jmeLogo.getImage());
9294
associateLookup(ExplorerUtils.createLookup(explorerManager, getActionMap()));
93-
// nodeSelectionResult = Utilities.actionsGlobalContext().lookupResult(AbstractSceneExplorerNode.class);
94-
// nodeSelectionResult.addLookupListener(this);
9595
}
9696

9797
private void initActions() {
@@ -148,10 +148,14 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
148148
}// </editor-fold>//GEN-END:initComponents
149149

150150
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
151-
if (selectedSpatial == null) {
151+
if (selectedSpatials == null) {
152152
return;
153153
}
154-
selectedSpatial.refresh(false);
154+
for (AbstractSceneExplorerNode node: selectedSpatials) {
155+
node.refresh(false);
156+
}
157+
158+
155159
}//GEN-LAST:event_jButton1ActionPerformed
156160
// Variables declaration - do not modify//GEN-BEGIN:variables
157161
private javax.swing.JScrollPane explorerScrollPane;
@@ -164,6 +168,7 @@ private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS
164168
* only, i.e. deserialization routines; otherwise you could get a
165169
* non-deserialized instance. To obtain the singleton instance, use
166170
* {@link #findInstance}.
171+
* @return
167172
*/
168173
public static synchronized SceneExplorerTopComponent getDefault() {
169174
if (instance == null) {
@@ -175,16 +180,17 @@ public static synchronized SceneExplorerTopComponent getDefault() {
175180
/**
176181
* Obtain the SceneExplorerTopComponent instance. Never call
177182
* {@link #getDefault} directly!
183+
* @return
178184
*/
179185
public static synchronized SceneExplorerTopComponent findInstance() {
180-
TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
181-
if (win == null) {
186+
TopComponent window = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
187+
if (window == null) {
182188
logger.warning(
183189
"Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
184190
return getDefault();
185191
}
186-
if (win instanceof SceneExplorerTopComponent) {
187-
return (SceneExplorerTopComponent) win;
192+
if (window instanceof SceneExplorerTopComponent sceneExplorerTopComponent) {
193+
return sceneExplorerTopComponent;
188194
}
189195
logger.warning(
190196
"There seem to be multiple components with the '" + PREFERRED_ID
@@ -216,27 +222,20 @@ public void componentClosed() {
216222
SceneApplication.getApplication().removeSceneListener(this);
217223
// TODO add custom code on component closing
218224
}
219-
225+
220226
void writeProperties(java.util.Properties p) {
221-
// better to version settings since initial version as advocated at
222-
// http://wiki.apidesign.org/wiki/PropertyFiles
227+
// Required. Do not remove.
223228
p.setProperty("version", "1.0");
224-
// TODO store your settings
225229
}
226-
230+
227231
Object readProperties(java.util.Properties p) {
232+
// Required. Do not remove.
228233
if (instance == null) {
229234
instance = this;
230235
}
231-
instance.readPropertiesImpl(p);
232236
return instance;
233237
}
234238

235-
private void readPropertiesImpl(java.util.Properties p) {
236-
String version = p.getProperty("version");
237-
// TODO read your settings according to their version
238-
}
239-
240239
@Override
241240
protected String preferredID() {
242241
return PREFERRED_ID;
@@ -246,46 +245,32 @@ protected String preferredID() {
246245
public UndoRedo getUndoRedo() {
247246
return Lookup.getDefault().lookup(UndoRedo.class);
248247
}
249-
private transient ExplorerManager explorerManager = new ExplorerManager();
250248

251249
@Override
252250
public ExplorerManager getExplorerManager() {
253251
return explorerManager;
254252
}
255253

256-
public void setSelectedNode(AbstractSceneExplorerNode node) {
257-
selectedSpatial = node;
258-
if (node != null) {
259-
lastSelected = node;
254+
public void setSelectedNode(AbstractSceneExplorerNode[] nodes) {
255+
selectedSpatials = nodes;
256+
if (nodes != null) {
257+
lastSelected = nodes;
260258
}
261259
try {
262-
if (node != null) {
263-
explorerManager.setSelectedNodes(new Node[]{node});
264-
// setActivatedNodes(new Node[]{node});
260+
if (nodes != null) {
261+
explorerManager.setSelectedNodes(nodes);
265262
} else {
266263
explorerManager.setSelectedNodes(new Node[]{});
267-
// setActivatedNodes(new Node[]{});
268264
}
269-
} catch (Exception ex) {
265+
} catch (PropertyVetoException ex) {
270266
Exceptions.printStackTrace(ex);
271267
}
272268
}
273269

274-
// public void resultChanged(LookupEvent ev) {
275-
// Collection collection = nodeSelectionResult.allInstances();
276-
// for (Iterator it = collection.iterator(); it.hasNext();) {
277-
// Object object = it.next();
278-
// if (object instanceof AbstractSceneExplorerNode) {
279-
// return;
280-
// }
281-
// }
282-
// selectedSpatial = null;
283-
// }
284270
@Override
285271
public void sceneOpened(SceneRequest request) {
286272
final JmeNode node = request.getJmeNode();
287-
for (Iterator it = materialChangeProviders.values().iterator(); it.hasNext();) {
288-
MaterialChangeProvider provider = (MaterialChangeProvider) it.next();
273+
for (MaterialChangeProvider provider : materialChangeProviders.values()) {
289274
provider.clearMaterialChangeListeners();
290275
}
291276
if (node != null) {
@@ -310,11 +295,11 @@ public void sceneClosed(SceneRequest request) {
310295
@Override
311296
public void previewCreated(PreviewRequest request) {
312297
}
313-
298+
314299
/**
315300
* @return the selectedSpatial
316301
*/
317-
public AbstractSceneExplorerNode getLastSelected() {
302+
public AbstractSceneExplorerNode[] getLastSelected() {
318303
return lastSelected;
319304
}
320305

@@ -339,7 +324,7 @@ public void addMaterialChangeListener(MaterialChangeListener listener) {
339324
logger.log(Level.FINE, "New material listener for : {0}", listener.getKey());
340325
List<MaterialChangeListener> listeners = materialChangeListeners.get(listener.getKey());
341326
if (listeners == null) {
342-
listeners = new ArrayList<MaterialChangeListener>();
327+
listeners = new ArrayList<>();
343328
materialChangeListeners.put(listener.getKey(), listeners);
344329
}
345330
listeners.add(listener);
@@ -383,7 +368,7 @@ public void swapMaterialChangeListener(MaterialChangeListener listener, String o
383368
// assert newKey.equals(listener.getKey());
384369
List<MaterialChangeListener> listeners = materialChangeListeners.get(newKey);
385370
if (listeners == null) {
386-
listeners = new ArrayList<MaterialChangeListener>();
371+
listeners = new ArrayList<>();
387372
materialChangeListeners.put(newKey, listeners);
388373
}
389374
listeners.add(listener);
@@ -397,6 +382,7 @@ public void swapMaterialChangeListener(MaterialChangeListener listener, String o
397382

398383
/**
399384
* Terrain has a LOD control that requires the camera to function.
385+
* @param jmeRootNode
400386
*/
401387
protected void setTerrainLodCamera(JmeNode jmeRootNode) {
402388
Camera camera = SceneApplication.getApplication().getCamera();

jme3-core/src/com/jme3/gde/core/sceneexplorer/nodes/actions/MotionPathPopup.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009-2010 jMonkeyEngine
2+
* Copyright (c) 2009-2024 jMonkeyEngine
33
* All rights reserved.
44
*
55
* Redistribution and use in source and binary forms, with or without
@@ -107,14 +107,20 @@ public void actionPerformed(ActionEvent e) {
107107
Vector3f pos;
108108

109109
SceneToolController controller = SceneApplication.getApplication().getStateManager().getState(SceneToolController.class);
110-
if (controller != null && (!controller.getCursorLocation().equals(Vector3f.ZERO))) { // Vector3f.ZERO means not yet clicked
110+
// Vector3f.ZERO means not yet clicked
111+
if (controller != null && (!controller.getCursorLocation().equals(Vector3f.ZERO))) {
111112
pos = controller.getCursorLocation().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0); // Shifting up so a) Netbeans isn't merging Waypoints and b) it's visible
112113
} else {
113-
AbstractSceneExplorerNode node = SceneExplorerTopComponent.findInstance().getLastSelected();
114-
if (node instanceof JmeVector3f) { // null instanceof JmeVector3f == false
115-
pos = ((JmeVector3f)node).getVector3f().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0);
114+
AbstractSceneExplorerNode[] nodes = SceneExplorerTopComponent.findInstance().getLastSelected();
115+
if(nodes == null || nodes.length == 0) {
116+
return;
117+
}
118+
final AbstractSceneExplorerNode node = nodes[0];
119+
if (node instanceof JmeVector3f jmeVector3f) {
120+
pos = jmeVector3f.getVector3f().clone().addLocal(0, jmeMotionPath.getDebugBoxExtents() * 3f, 0);
116121
} else {
117-
pos = new Vector3f(0f, 1.0f, 0f); // Default is a bit over the Center
122+
// Default is a bit over the Center
123+
pos = new Vector3f(0f, 1.0f, 0f);
118124
}
119125
}
120126

0 commit comments

Comments
 (0)