]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/events/NodeEventHandler.java
SceneGraph NodeEventHandler should work in headless environments
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / events / NodeEventHandler.java
index 598dab9fefe266a62b12cfaf3946fcbc6907a8c7..1c1ac8a37a7b523ace66705188f148c1972ed763 100644 (file)
@@ -12,6 +12,7 @@
 package org.simantics.scenegraph.g2d.events;
 
 import java.awt.Component;
+import java.awt.GraphicsEnvironment;
 import java.awt.dnd.DnDConstants;
 import java.awt.dnd.DragGestureEvent;
 import java.awt.dnd.DragGestureListener;
@@ -35,6 +36,8 @@ import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
 import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
 import org.simantics.scenegraph.g2d.events.adapter.AWTMouseEventAdapter;
 import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Delivers events (mouse, key, focus, command, time) to scene graph nodes that
@@ -44,6 +47,8 @@ import org.simantics.scenegraph.g2d.events.command.CommandEvent;
  */
 public class NodeEventHandler implements IEventHandler {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(NodeEventHandler.class);
+
     private static final boolean DEBUG_EVENTS       = false;
     private static final boolean DEBUG_HANDLER_SORT = false;
 
@@ -75,8 +80,8 @@ public class NodeEventHandler implements IEventHandler {
 
         void getTreePath(INode node, ArrayList<INode> result) {
              result.clear();
-             for (INode parent = node.getParent(); parent != null; parent = parent.getParent())
-                 result.add(parent);
+             for (; node != null; node = node.getParent())
+                 result.add(node);
         }
 
         void notSameGraph(INode o1, INode o2) {
@@ -94,19 +99,15 @@ public class NodeEventHandler implements IEventHandler {
             ArrayList<INode> path1 = tmp.path1;
             ArrayList<INode> path2 = tmp.path2;
 
-            // Get path to root node for both nodes
-            INode o1 = (INode) e1;
-            INode o2 = (INode) e2;
-            getTreePath(o1, path1);
-            getTreePath(o2, path2);
+            try {
+               // Get path to root node for both nodes
+               getTreePath((INode) e1, path1);
+               getTreePath((INode) e2, path2);
 
-            // Sanity checks: nodes part of same scene graph
-            INode root1 = path1.isEmpty() ? o1 : path1.get(path1.size() - 1);
-            INode root2 = path2.isEmpty() ? o2 : path2.get(path2.size() - 1);
-            if (root1 != root2)
-                notSameGraph(o1, o2);
+               // Sanity checks: nodes part of same scene graph
+               if (path1.get(path1.size() - 1) != path2.get(path2.size() - 1))
+                       notSameGraph((INode)e1, (INode)e2);
 
-            try {
                 // Find first non-matching nodes in the paths starting from the root node
                 int i1 = path1.size() - 1;
                 int i2 = path2.size() - 1;
@@ -124,27 +125,31 @@ public class NodeEventHandler implements IEventHandler {
                 if (i2 < 0)
                     return Order.ASCENDING == order ? 1 : -1;
 
-                INode n1 = path1.get(i1);
-                INode n2 = path2.get(i2);
-                IG2DNode g1 = n1 instanceof IG2DNode ? (IG2DNode) n1 : null;
-                IG2DNode g2 = n2 instanceof IG2DNode ? (IG2DNode) n2 : null;
-                if (g1 != null && g2 != null) {
-                    int z1 = g1.getZIndex();
-                    int z2 = g2.getZIndex();
-                    int c = compare(z1, z2);
-                    return order == Order.ASCENDING ? c : -c;
-                }
-                // Can't sort non-IG2DNodes.
-                return 0;
+                return compare(path1.get(i1), path2.get(i2));
             } finally {
                 // Don't hold on to objects unnecessarily
                 path1.clear();
                 path2.clear();
             }
         }
-
-        private int compare(int v1, int v2) {
-            return v1 < v2 ? -1 : (v1 > v2 ? 1 : 0);
+        
+        private int compare(INode n1, INode n2) {
+               if(n1 instanceof IG2DNode) {
+                       if(n2 instanceof IG2DNode) {
+                       int z1 = ((IG2DNode)n1).getZIndex();
+                       int z2 = ((IG2DNode)n2).getZIndex();
+                       int c = Integer.compare(z1, z2);
+                       return order == Order.ASCENDING ? c : -c;
+                       }
+                       else
+                               return -1; // sort IG2DNodes before non-IG2DNodes
+            }
+               else {
+                       if(n2 instanceof IG2DNode)
+                               return 1;
+                       else
+                               return 0; // all non-IG2DNodes are equal in comparison
+               }
         }
     };
 
@@ -197,12 +202,6 @@ public class NodeEventHandler implements IEventHandler {
      */
     protected G2DSceneGraph               sg;
 
-    /**
-     * For proper initiation of native DnD operations within this AWT-based
-     * scenegraph system.
-     */
-    protected DragSource                  ds = new DragSource();
-
     public NodeEventHandler(G2DSceneGraph sg) {
         this.sg = sg;
     }
@@ -222,6 +221,11 @@ public class NodeEventHandler implements IEventHandler {
     }
 
     public void setRootPane(Component rootPane) {
+        if (GraphicsEnvironment.isHeadless()) {
+            LOGGER.info("Disabling DragSource in headless environments");
+            return;
+        }
+        final DragSource ds = new DragSource();
         final DragSourceListener dsl = new DragSourceListener() {
             @Override
             public void dropActionChanged(DragSourceDragEvent dsde) {