Jelajahi Sumber

Merge pull request #671 from jMonkeyEngine/copilot/fix-668

Fix drag and drop issues from file tree to scene composer by implementing AssetNameHolder and flavor detection
Rickard Edén 13 jam lalu
induk
melakukan
d7894fcab1

+ 1 - 6
jme3-assetbrowser/src/com/jme3/gde/assetbrowser/widgets/AssetPreviewWidget.java

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2009-2023 jMonkeyEngine
+ *  Copyright (c) 2009-2025 jMonkeyEngine
  *  All rights reserved.
  * 
  *  Redistribution and use in source and binary forms, with or without
@@ -154,11 +154,6 @@ public class AssetPreviewWidget extends javax.swing.JPanel implements SceneListe
         return assetNameLabel.getText();
     }
 
-    @Override
-    public void setAssetName(String name) {
-        assetNameLabel.setText(name);
-    }
-
     public void setEditable(boolean editable) {
         this.editable = editable;
     }

+ 14 - 3
jme3-core/src/com/jme3/gde/core/assets/AssetDataNode.java

@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2009-2010 jMonkeyEngine
+ *  Copyright (c) 2009-2025 jMonkeyEngine
  *  All rights reserved.
  * 
  *  Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
 package com.jme3.gde.core.assets;
 
 import com.jme3.asset.AssetKey;
+import com.jme3.gde.core.dnd.AssetNameHolder;
 import com.jme3.gde.core.util.PropertyUtils;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.Field;
@@ -48,7 +49,7 @@ import org.openide.util.Lookup;
  * @author normenhansen
  */
 @SuppressWarnings({"unchecked", "rawtypes"})
-public class AssetDataNode extends DataNode {
+public class AssetDataNode extends DataNode implements AssetNameHolder {
 
     public AssetDataNode(DataObject obj, Children ch) {
         super(obj, ch);
@@ -69,7 +70,7 @@ public class AssetDataNode extends DataNode {
         if (key == null) {
             return sheet;
         }
-        
+
         Sheet.Set set = Sheet.createPropertiesSet();
         set.setName("AssetKey");
         set.setDisplayName("Conversion Settings");
@@ -89,4 +90,14 @@ public class AssetDataNode extends DataNode {
         sheet.put(set);
         return sheet;
     }
+
+    @Override
+    public String getAssetName() {
+        AssetData data = getLookup().lookup(AssetData.class);
+        if (data != null && data.getAssetKey() != null) {
+            return data.getAssetKey().getName();
+        }
+        return null;
+    }
+
 }

+ 29 - 4
jme3-core/src/com/jme3/gde/core/dnd/AssetNameHolder.java

@@ -1,6 +1,33 @@
 /*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ *  Copyright (c) 2009-2025 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.dnd;
 
@@ -11,6 +38,4 @@ package com.jme3.gde.core.dnd;
 public interface AssetNameHolder {
 
     String getAssetName();
-
-    void setAssetName(String name);
 }

+ 65 - 12
jme3-core/src/com/jme3/gde/core/dnd/SceneViewerDropTargetListener.java

@@ -1,9 +1,37 @@
 /*
- * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
- * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ *  Copyright (c) 2009-2025 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.dnd;
 
+import com.jme3.gde.core.assets.AssetDataNode;
 import com.jme3.gde.core.sceneviewer.SceneViewerTopComponent;
 import com.jme3.math.Vector2f;
 import java.awt.Cursor;
@@ -19,8 +47,9 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 /**
- * Handles dropping Materials or Spatial from the AssetBrowser to the
- * SceneViewer
+ * Handles dropping Materials or Spatial from the AssetBrowser and Projects tab
+ * to the SceneViewer
+ *
  * @author rickard
  */
 public class SceneViewerDropTargetListener implements DropTargetListener {
@@ -57,8 +86,7 @@ public class SceneViewerDropTargetListener implements DropTargetListener {
     @Override
     public void drop(final DropTargetDropEvent dtde) {
         this.rootPanel.setCursor(Cursor.getDefaultCursor());
-
-        AssetNameHolder transferableObj = null;
+        String assetKey = null;
         Transferable transferable = null;
         DataFlavor flavor = null;
 
@@ -69,26 +97,51 @@ public class SceneViewerDropTargetListener implements DropTargetListener {
             flavor = flavors[0];
             // What does the Transferable support
             if (transferable.isDataFlavorSupported(flavor)) {
-                transferableObj = (AssetNameHolder) dtde.getTransferable().getTransferData(flavor);
+                Object o = dtde.getTransferable().getTransferData(flavor);
+                if (o instanceof AssetNameHolder assetNameHolder) {
+                    assetKey = assetNameHolder.getAssetName();
+                } else if (o instanceof AssetDataNode assetDataNode) {
+                    assetKey = assetDataNode.getAssetName();
+                }
             }
 
         } catch (UnsupportedFlavorException | IOException ex) {
             Logger.getLogger(SceneViewerDropTargetListener.class.getName()).log(Level.WARNING, "Non-supported flavor {0}", transferable);
         }
 
-        if (transferable == null || transferableObj == null) {
+        if (transferable == null || assetKey == null) {
             return;
         }
 
         final int dropYLoc = dtde.getLocation().y;
         final int dropXLoc = dtde.getLocation().x;
 
-        if (flavor instanceof SpatialDataFlavor) {
-            rootPanel.addModel(transferableObj.getAssetName(), new Vector2f(dropXLoc, dropYLoc));
-        } else if (flavor instanceof MaterialDataFlavor) {
-            rootPanel.applyMaterial(transferableObj.getAssetName(), new Vector2f(dropXLoc, dropYLoc));
+        if (flavor instanceof SpatialDataFlavor || isModelExtension(assetKey)) {
+            rootPanel.addModel(assetKey, new Vector2f(dropXLoc, dropYLoc));
+        } else if (flavor instanceof MaterialDataFlavor || isMaterialExtension(assetKey)) {
+            rootPanel.applyMaterial(assetKey, new Vector2f(dropXLoc, dropYLoc));
         }
 
     }
 
+    /**
+     * Determines if the asset key represents a model/spatial asset by checking its file extension.
+     *
+     * @param assetKey The asset key (typically a filename or path); this method checks if it ends with the model file extension.
+     * @return true if the asset key is for model files
+     */
+    private boolean isModelExtension(String assetKey) {
+        return assetKey.endsWith("j3o");
+    }
+
+    /**
+     * Determines if the asset key represents a material asset by checking its file extension.
+     *
+     * @param assetKey The asset key (typically a filename or path); this method checks if it ends with the material file extension.
+     * @return true if the asset key is for material files
+     */
+    private boolean isMaterialExtension(String assetKey) {
+        return assetKey.endsWith("j3m");
+    }
+
 }