]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/G2DNode.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / g2d / G2DNode.java
index a558aa308d68dec22bba2c63942293ffc90d789d..477b95517cfb26d6aaa95347ccc6bed4285dd394 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.scenegraph.g2d;\r
-\r
-import java.awt.Component;\r
-import java.awt.Cursor;\r
-import java.awt.Shape;\r
-import java.awt.geom.AffineTransform;\r
-import java.awt.geom.NoninvertibleTransformException;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-\r
-import org.simantics.scenegraph.INode;\r
-import org.simantics.scenegraph.Node;\r
-import org.simantics.scenegraph.ParentNode;\r
-import org.simantics.scenegraph.g2d.events.Event;\r
-import org.simantics.scenegraph.g2d.events.EventTypes;\r
-import org.simantics.scenegraph.g2d.events.FocusEvent;\r
-import org.simantics.scenegraph.g2d.events.IEventHandler;\r
-import org.simantics.scenegraph.g2d.events.KeyEvent;\r
-import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;\r
-import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;\r
-import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;\r
-import org.simantics.scenegraph.g2d.events.NodeEventHandler;\r
-import org.simantics.scenegraph.g2d.events.TimeEvent;\r
-import org.simantics.scenegraph.g2d.events.command.CommandEvent;\r
-import org.simantics.scenegraph.utils.GeometryUtils;\r
-import org.simantics.scenegraph.utils.NodeUtil;\r
-\r
-public abstract class G2DNode extends Node implements IG2DNode {\r
-\r
-    private static final long serialVersionUID = 8283264115992894707L;\r
-\r
-    protected int z = 0;\r
-    protected AffineTransform transform = IdentityAffineTransform.INSTANCE;\r
-\r
-    @SyncField("z")\r
-    public void setZIndex(int z) {\r
-        if (z != this.z) {\r
-            G2DParentNode parent = (G2DParentNode) getParent();\r
-            if (parent != null)\r
-                parent.invalidateChildOrder();\r
-            this.z = z;\r
-        }\r
-    }\r
-\r
-    public int getZIndex() {\r
-        return z;\r
-    }\r
-    \r
-    public boolean validate() {\r
-       return true;\r
-    }\r
-    \r
-    @Override\r
-    public void cleanup() {\r
-        retractMapping();\r
-        repaint();\r
-    }\r
-\r
-    public void repaint() {\r
-       INode parent = getParent();\r
-        while(parent != null && !(parent instanceof G2DSceneGraph))\r
-            parent = parent.getParent();\r
-        if(parent == null || ((G2DSceneGraph)parent).getRootPane() == null) return;\r
-        ((G2DSceneGraph)parent).getRootPane().repaint();\r
-    }\r
-\r
-\r
-    // Bounds and transformation\r
-\r
-    public AffineTransform getTransform() {\r
-        return transform;\r
-    }\r
-\r
-    @PropertySetter("Transform")\r
-    @SyncField("transform")\r
-    public void setTransform(AffineTransform transform) {\r
-        assert(transform != null);\r
-        if (transform.isIdentity())\r
-            this.transform = IdentityAffineTransform.INSTANCE;\r
-        else\r
-            this.transform = transform;\r
-    }\r
-\r
-    /**\r
-     * Return bounds transformed with local transformation\r
-     * \r
-     * @return transformed bounds\r
-     */\r
-    public Rectangle2D getBounds() {\r
-        Rectangle2D local = getBoundsInLocal();\r
-        if (local == null)\r
-            return null;\r
-        // TODO: potential spot for CPU/memory allocation optimization\r
-        // by using more specialized implementations\r
-        return transform.createTransformedShape(local).getBounds2D();\r
-    }\r
-\r
-    /**\r
-     * Return bounds in local coordinates\r
-     * \r
-     * @return bounds\r
-     */\r
-    abstract public Rectangle2D getBoundsInLocal();\r
-    \r
-    public Rectangle2D getBoundsInLocal(boolean ignoreNulls) {\r
-       return getBoundsInLocal();\r
-    }\r
-\r
-    // Helper methods for bounds checking\r
-\r
-    public boolean contains(Point2D point) {\r
-        Rectangle2D bounds = getBounds();\r
-        if(bounds == null) return false;\r
-        return bounds.contains(point);\r
-    }\r
-\r
-    public boolean containsLocal(Point2D localPoint) {\r
-        Rectangle2D bounds = getBoundsInLocal();\r
-        if(bounds == null) return false;\r
-        return bounds.contains(localPoint);\r
-    }\r
-\r
-    public boolean intersects(Rectangle2D b) {\r
-        if (b == null)\r
-            return true;\r
-        Rectangle2D a = getBounds();\r
-        if (a == null)\r
-            return true;\r
-        /*\r
-         * Compared to Rectangle2D.intersects, this\r
-         * intersects closed (not open) shapes.\r
-         */\r
-        double ax = a.getX();\r
-        double ay = a.getY();\r
-        double aw = a.getWidth();\r
-        double ah = a.getHeight();\r
-        double bx = b.getX();\r
-        double by = b.getY();\r
-        double bw = b.getWidth();\r
-        double bh = b.getHeight();\r
-        return (ax + aw >= bx &&\r
-                ay + ah >= by &&\r
-                ax <= bx + bw &&\r
-                ay <= by + bh);\r
-    }\r
-\r
-    public Point2D localToParent(Point2D point) {\r
-        return transform.transform(point, null);\r
-    }\r
-\r
-    public Rectangle2D localToParent(Rectangle2D rect) {\r
-        return transform.createTransformedShape(rect).getBounds2D();\r
-    }\r
-\r
-    public Point2D parentToLocal(Point2D point) {\r
-        AffineTransform inverse = null;\r
-        try {\r
-            inverse = transform.createInverse();\r
-            return inverse.transform(point, null);\r
-        } catch (NoninvertibleTransformException e) {\r
-            e.printStackTrace(); // FIXME\r
-        }\r
-        return point;\r
-    }\r
-\r
-    public Point2D parentToLocal(Point2D src, Point2D dst) {\r
-        AffineTransform inverse = null;\r
-        try {\r
-            inverse = transform.createInverse();\r
-            return inverse.transform(src, dst);\r
-        } catch (NoninvertibleTransformException e) {\r
-            e.printStackTrace(); // FIXME\r
-        }\r
-        return src;\r
-    }\r
-\r
-    public Rectangle2D parentToLocal(Rectangle2D rect) {\r
-        AffineTransform inverse = null;\r
-        try {\r
-            inverse = transform.createInverse();\r
-            return inverse.createTransformedShape(rect).getBounds2D();\r
-        } catch (NoninvertibleTransformException e) {\r
-            e.printStackTrace(); // FIXME\r
-        }\r
-        return rect;\r
-    }\r
-\r
-    public Point2D localToControl(Point2D point) {\r
-        IG2DNode node = this;\r
-        while(node != null) {\r
-            point = node.getTransform().transform(point, null);\r
-            node = (G2DParentNode)node.getParent(); // FIXME: it should be G2DParentNode but you can never be sure\r
-        }\r
-        return point;\r
-    }\r
-\r
-    public Rectangle2D localToControl(Rectangle2D rect) {\r
-        Shape shape = rect;\r
-        IG2DNode node = this;\r
-        while(node != null) {\r
-            shape = node.getTransform().createTransformedShape(shape);\r
-            node = (G2DParentNode)node.getParent(); // FIXME: it should be G2DParentNode but you can never be sure\r
-        }\r
-\r
-        return shape.getBounds2D();\r
-    }\r
-\r
-    public Point2D controlToLocal(Point2D point) {\r
-        AffineTransform at = NodeUtil.getGlobalToLocalTransform(this, null);\r
-        if (at == null)\r
-            return point;\r
-        return at.transform(point, null);\r
-    }\r
-\r
-    public Rectangle2D controlToLocal(Rectangle2D rect) {\r
-        AffineTransform at = NodeUtil.getGlobalToLocalTransform(this, null);\r
-        if (at == null)\r
-            return rect;\r
-        return GeometryUtils.transformRectangle(at, rect);\r
-    }\r
-\r
-    @Override\r
-    public String toString() {\r
-        return super.toString() + " [z=" + z + ",transform=" + transform + "]";\r
-    }\r
-\r
-    /**\r
-     * @see org.simantics.scenegraph.g2d.IG2DNode#getRootNode()\r
-     */\r
-    public G2DSceneGraph getRootNode2D() {\r
-        ParentNode<?> root = getRootNode();\r
-        return (G2DSceneGraph) root;\r
-    }\r
-\r
-    @Override\r
-    public boolean hasFocus() {\r
-        return getFocusNode() == this;\r
-    }\r
-\r
-    @Override\r
-    public IG2DNode getFocusNode() {\r
-        return getRootNode2D().getFocusNode();\r
-    }\r
-\r
-    @Override\r
-    public void setFocusNode(IG2DNode node) {\r
-        getRootNode2D().setFocusNode(node);\r
-    }\r
-\r
-    protected NodeEventHandler getEventHandler() {\r
-        return NodeUtil.getNodeEventHandler(this);\r
-    }\r
-\r
-    protected void addEventHandler(IEventHandler handler) {\r
-        getEventHandler().add(handler);\r
-    }\r
-\r
-    protected void removeEventHandler(IEventHandler handler) {\r
-        getEventHandler().remove(handler);\r
-    }\r
-\r
-    @Override\r
-    public int getEventMask() {\r
-        return 0;\r
-    }\r
-\r
-    @Override\r
-    public boolean handleEvent(Event e) {\r
-        int eventType = EventTypes.toType(e);\r
-        switch (eventType) {\r
-            case EventTypes.Command:\r
-                return handleCommand((CommandEvent) e);\r
-\r
-            case EventTypes.FocusGained:\r
-            case EventTypes.FocusLost:\r
-                return handleFocusEvent((FocusEvent) e);\r
-\r
-            case EventTypes.KeyPressed:\r
-                return keyPressed((KeyPressedEvent) e);\r
-            case EventTypes.KeyReleased:\r
-                return keyReleased((KeyReleasedEvent) e);\r
-\r
-            case EventTypes.MouseButtonPressed:\r
-                return mouseButtonPressed((MouseButtonPressedEvent) e);\r
-            case EventTypes.MouseButtonReleased:\r
-                return mouseButtonReleased((MouseButtonReleasedEvent) e);\r
-            case EventTypes.MouseClick:\r
-                return mouseClicked((MouseClickEvent) e);\r
-            case EventTypes.MouseDoubleClick:\r
-                return mouseDoubleClicked((MouseDoubleClickedEvent) e);\r
-            case EventTypes.MouseMoved:\r
-                return mouseMoved((MouseMovedEvent) e);\r
-            case EventTypes.MouseDragBegin:\r
-                return mouseDragged((MouseDragBegin) e);\r
-            case EventTypes.MouseEnter:\r
-                return mouseEntered((MouseEnterEvent) e);\r
-            case EventTypes.MouseExit:\r
-                return mouseExited((MouseExitEvent) e);\r
-            case EventTypes.MouseWheel:\r
-                return mouseWheelMoved((MouseWheelMovedEvent) e);\r
-\r
-            case EventTypes.Time:\r
-                return handleTimeEvent((TimeEvent) e);\r
-        }\r
-        return false;\r
-    }\r
-\r
-    protected boolean keyReleased(KeyReleasedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean keyPressed(KeyPressedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean handleCommand(CommandEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean handleFocusEvent(FocusEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean handleKeyEvent(KeyEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseButtonPressed(MouseButtonPressedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseClicked(MouseClickEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseMoved(MouseMovedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseDragged(MouseDragBegin e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseEntered(MouseEnterEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseExited(MouseExitEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean mouseWheelMoved(MouseWheelMovedEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected boolean handleTimeEvent(TimeEvent e) {\r
-        return false;\r
-    }\r
-\r
-    protected void setCursor(int cursorType) {\r
-        Component rootPane = NodeUtil.findRootPane(this);\r
-        if (rootPane != null)\r
-            rootPane.setCursor(Cursor.getPredefinedCursor(cursorType));\r
-    }\r
-\r
-    protected void setCursor(Cursor cursor) {\r
-        Component rootPane = NodeUtil.findRootPane(this);\r
-        if (rootPane != null)\r
-            rootPane.setCursor(cursor);\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.scenegraph.g2d;
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Shape;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.simantics.scenegraph.INode;
+import org.simantics.scenegraph.Node;
+import org.simantics.scenegraph.ParentNode;
+import org.simantics.scenegraph.g2d.events.Event;
+import org.simantics.scenegraph.g2d.events.EventTypes;
+import org.simantics.scenegraph.g2d.events.FocusEvent;
+import org.simantics.scenegraph.g2d.events.IEventHandler;
+import org.simantics.scenegraph.g2d.events.KeyEvent;
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyPressedEvent;
+import org.simantics.scenegraph.g2d.events.KeyEvent.KeyReleasedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonPressedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseButtonReleasedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseClickEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDoubleClickedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseDragBegin;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseEnterEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseExitEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
+import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;
+import org.simantics.scenegraph.g2d.events.NodeEventHandler;
+import org.simantics.scenegraph.g2d.events.TimeEvent;
+import org.simantics.scenegraph.g2d.events.command.CommandEvent;
+import org.simantics.scenegraph.utils.GeometryUtils;
+import org.simantics.scenegraph.utils.NodeUtil;
+
+public abstract class G2DNode extends Node implements IG2DNode {
+
+    private static final long serialVersionUID = 8283264115992894707L;
+
+    protected int z = 0;
+    protected AffineTransform transform = IdentityAffineTransform.INSTANCE;
+
+    @SyncField("z")
+    public void setZIndex(int z) {
+        if (z != this.z) {
+            G2DParentNode parent = (G2DParentNode) getParent();
+            if (parent != null)
+                parent.invalidateChildOrder();
+            this.z = z;
+        }
+    }
+
+    public int getZIndex() {
+        return z;
+    }
+    
+    public boolean validate() {
+       return true;
+    }
+    
+    @Override
+    public void refresh() {
+    }
+
+    @Override
+    public void cleanup() {
+        retractMapping();
+        repaint();
+    }
+
+    public void repaint() {
+       INode parent = getParent();
+        while(parent != null && !(parent instanceof G2DSceneGraph))
+            parent = parent.getParent();
+        if(parent == null || ((G2DSceneGraph)parent).getRootPane() == null) return;
+        ((G2DSceneGraph)parent).getRootPane().repaint();
+    }
+
+
+    // Bounds and transformation
+
+    public AffineTransform getTransform() {
+        return transform;
+    }
+
+    @PropertySetter("Transform")
+    @SyncField("transform")
+    public void setTransform(AffineTransform transform) {
+        assert(transform != null);
+        if (transform.isIdentity())
+            this.transform = IdentityAffineTransform.INSTANCE;
+        else
+            this.transform = transform;
+    }
+
+    /**
+     * Return bounds transformed with local transformation
+     * 
+     * @return transformed bounds
+     */
+    public Rectangle2D getBounds() {
+        Rectangle2D local = getBoundsInLocal();
+        if (local == null)
+            return null;
+        // TODO: potential spot for CPU/memory allocation optimization
+        // by using more specialized implementations
+        return transform.createTransformedShape(local).getBounds2D();
+    }
+
+    /**
+     * Return bounds in local coordinates
+     * 
+     * @return bounds
+     */
+    abstract public Rectangle2D getBoundsInLocal();
+    
+    public Rectangle2D getBoundsInLocal(boolean ignoreNulls) {
+       return getBoundsInLocal();
+    }
+
+    // Helper methods for bounds checking
+
+    public boolean contains(Point2D point) {
+        Rectangle2D bounds = getBounds();
+        if(bounds == null) return false;
+        return bounds.contains(point);
+    }
+
+    public boolean containsLocal(Point2D localPoint) {
+        Rectangle2D bounds = getBoundsInLocal();
+        if(bounds == null) return false;
+        return bounds.contains(localPoint);
+    }
+
+    public boolean intersects(Rectangle2D b) {
+        if (b == null)
+            return true;
+        Rectangle2D a = getBounds();
+        if (a == null)
+            return true;
+        /*
+         * Compared to Rectangle2D.intersects, this
+         * intersects closed (not open) shapes.
+         */
+        double ax = a.getX();
+        double ay = a.getY();
+        double aw = a.getWidth();
+        double ah = a.getHeight();
+        double bx = b.getX();
+        double by = b.getY();
+        double bw = b.getWidth();
+        double bh = b.getHeight();
+        return (ax + aw >= bx &&
+                ay + ah >= by &&
+                ax <= bx + bw &&
+                ay <= by + bh);
+    }
+
+    public Point2D localToParent(Point2D point) {
+        return transform.transform(point, null);
+    }
+
+    public Rectangle2D localToParent(Rectangle2D rect) {
+        return transform.createTransformedShape(rect).getBounds2D();
+    }
+
+    public Point2D parentToLocal(Point2D point) {
+        AffineTransform inverse = null;
+        try {
+            inverse = transform.createInverse();
+            return inverse.transform(point, null);
+        } catch (NoninvertibleTransformException e) {
+            e.printStackTrace(); // FIXME
+        }
+        return point;
+    }
+
+    public Point2D parentToLocal(Point2D src, Point2D dst) {
+        AffineTransform inverse = null;
+        try {
+            inverse = transform.createInverse();
+            return inverse.transform(src, dst);
+        } catch (NoninvertibleTransformException e) {
+            e.printStackTrace(); // FIXME
+        }
+        return src;
+    }
+
+    public Rectangle2D parentToLocal(Rectangle2D rect) {
+        AffineTransform inverse = null;
+        try {
+            inverse = transform.createInverse();
+            return inverse.createTransformedShape(rect).getBounds2D();
+        } catch (NoninvertibleTransformException e) {
+            e.printStackTrace(); // FIXME
+        }
+        return rect;
+    }
+
+    public Point2D localToControl(Point2D point) {
+        IG2DNode node = this;
+        while(node != null) {
+            point = node.getTransform().transform(point, null);
+            node = (G2DParentNode)node.getParent(); // FIXME: it should be G2DParentNode but you can never be sure
+        }
+        return point;
+    }
+
+    public Rectangle2D localToControl(Rectangle2D rect) {
+        Shape shape = rect;
+        IG2DNode node = this;
+        while(node != null) {
+            shape = node.getTransform().createTransformedShape(shape);
+            node = (G2DParentNode)node.getParent(); // FIXME: it should be G2DParentNode but you can never be sure
+        }
+
+        return shape.getBounds2D();
+    }
+
+    public Point2D controlToLocal(Point2D point) {
+        AffineTransform at = NodeUtil.getGlobalToLocalTransform(this, null);
+        if (at == null)
+            return point;
+        return at.transform(point, null);
+    }
+
+    public Rectangle2D controlToLocal(Rectangle2D rect) {
+        AffineTransform at = NodeUtil.getGlobalToLocalTransform(this, null);
+        if (at == null)
+            return rect;
+        return GeometryUtils.transformRectangle(at, rect);
+    }
+
+    @Override
+    public String toString() {
+        return super.toString() + " [z=" + z + ",transform=" + transform + "]";
+    }
+
+    /**
+     * @see org.simantics.scenegraph.g2d.IG2DNode#getRootNode()
+     */
+    public G2DSceneGraph getRootNode2D() {
+        ParentNode<?> root = getRootNode();
+        return (G2DSceneGraph) root;
+    }
+
+    @Override
+    public boolean hasFocus() {
+        return getFocusNode() == this;
+    }
+
+    @Override
+    public IG2DNode getFocusNode() {
+        return getRootNode2D().getFocusNode();
+    }
+
+    @Override
+    public void setFocusNode(IG2DNode node) {
+        getRootNode2D().setFocusNode(node);
+    }
+
+    protected NodeEventHandler getEventHandler() {
+        return NodeUtil.getNodeEventHandler(this);
+    }
+
+    protected void addEventHandler(IEventHandler handler) {
+        getEventHandler().add(handler);
+    }
+
+    protected void removeEventHandler(IEventHandler handler) {
+        getEventHandler().remove(handler);
+    }
+
+    @Override
+    public int getEventMask() {
+        return 0;
+    }
+
+    @Override
+    public boolean handleEvent(Event e) {
+        int eventType = EventTypes.toType(e);
+        switch (eventType) {
+            case EventTypes.Command:
+                return handleCommand((CommandEvent) e);
+
+            case EventTypes.FocusGained:
+            case EventTypes.FocusLost:
+                return handleFocusEvent((FocusEvent) e);
+
+            case EventTypes.KeyPressed:
+                return keyPressed((KeyPressedEvent) e);
+            case EventTypes.KeyReleased:
+                return keyReleased((KeyReleasedEvent) e);
+
+            case EventTypes.MouseButtonPressed:
+                return mouseButtonPressed((MouseButtonPressedEvent) e);
+            case EventTypes.MouseButtonReleased:
+                return mouseButtonReleased((MouseButtonReleasedEvent) e);
+            case EventTypes.MouseClick:
+                return mouseClicked((MouseClickEvent) e);
+            case EventTypes.MouseDoubleClick:
+                return mouseDoubleClicked((MouseDoubleClickedEvent) e);
+            case EventTypes.MouseMoved:
+                return mouseMoved((MouseMovedEvent) e);
+            case EventTypes.MouseDragBegin:
+                return mouseDragged((MouseDragBegin) e);
+            case EventTypes.MouseEnter:
+                return mouseEntered((MouseEnterEvent) e);
+            case EventTypes.MouseExit:
+                return mouseExited((MouseExitEvent) e);
+            case EventTypes.MouseWheel:
+                return mouseWheelMoved((MouseWheelMovedEvent) e);
+
+            case EventTypes.Time:
+                return handleTimeEvent((TimeEvent) e);
+        }
+        return false;
+    }
+
+    protected boolean keyReleased(KeyReleasedEvent e) {
+        return false;
+    }
+
+    protected boolean keyPressed(KeyPressedEvent e) {
+        return false;
+    }
+
+    protected boolean handleCommand(CommandEvent e) {
+        return false;
+    }
+
+    protected boolean handleFocusEvent(FocusEvent e) {
+        return false;
+    }
+
+    protected boolean handleKeyEvent(KeyEvent e) {
+        return false;
+    }
+
+    protected boolean mouseButtonPressed(MouseButtonPressedEvent e) {
+        return false;
+    }
+
+    protected boolean mouseButtonReleased(MouseButtonReleasedEvent e) {
+        return false;
+    }
+
+    protected boolean mouseClicked(MouseClickEvent e) {
+        return false;
+    }
+
+    protected boolean mouseDoubleClicked(MouseDoubleClickedEvent e) {
+        return false;
+    }
+
+    protected boolean mouseMoved(MouseMovedEvent e) {
+        return false;
+    }
+
+    protected boolean mouseDragged(MouseDragBegin e) {
+        return false;
+    }
+
+    protected boolean mouseEntered(MouseEnterEvent e) {
+        return false;
+    }
+
+    protected boolean mouseExited(MouseExitEvent e) {
+        return false;
+    }
+
+    protected boolean mouseWheelMoved(MouseWheelMovedEvent e) {
+        return false;
+    }
+
+    protected boolean handleTimeEvent(TimeEvent e) {
+        return false;
+    }
+
+    protected void setCursor(int cursorType) {
+        Component rootPane = NodeUtil.findRootPane(this);
+        if (rootPane != null)
+            rootPane.setCursor(Cursor.getPredefinedCursor(cursorType));
+    }
+
+    protected void setCursor(Cursor cursor) {
+        Component rootPane = NodeUtil.findRootPane(this);
+        if (rootPane != null)
+            rootPane.setCursor(cursor);
+    }
+    
+    public void accept(IG2DNodeVisitor visitor) {
+        visitor.enter(this);
+        visitor.leave(this);
+    }
+
+}