]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java
3D framework (Simca 2012)
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / scenegraph / base / ParentNode.java
diff --git a/org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java b/org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java
new file mode 100644 (file)
index 0000000..6811217
--- /dev/null
@@ -0,0 +1,153 @@
+package org.simantics.g3d.scenegraph.base;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+\r
+import org.simantics.utils.datastructures.MapList;\r
+\r
+public abstract class ParentNode<T extends INode> extends Node {\r
+\r
+       private MapList<String, T> children = new MapList<String, T>();\r
+\r
+       public synchronized void addNode(String relName, T child) {\r
+               if (child.getParent() != null)\r
+                       child.getParent().removeNode(child.getParentRel(), child);\r
+\r
+               child.setParent(this, relName);\r
+               children.add(relName, (T) child);\r
+\r
+               childrenChanged();\r
+               fireNodeAdded(child, relName);\r
+       }\r
+\r
+       /**\r
+        * Removes child node and it's hierarchy.\r
+        * @param relName\r
+        * @param child\r
+        * @return\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public synchronized final boolean removeNode(String relName, INode child) {\r
+               if (children.remove(relName, (T) child)) {\r
+                       fireNodeRemoved(child, relName);\r
+                   child.remove();\r
+                       child.setParent(null, null);\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       \r
+       /**\r
+        * Removes child node. The child nodes hierarchy is left intact.\r
+        * @param relName\r
+        * @param child\r
+        * @return\r
+        */\r
+       @SuppressWarnings("unchecked")\r
+       public synchronized final boolean deattachNode(String relName, INode child) {\r
+               if (children.remove(relName, (T) child)) {\r
+                       fireNodeRemoved(child, relName);\r
+                       child.setParent(null, null);\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+       \r
+       public synchronized final boolean removeNodes(String relName) {\r
+               List<T> nodes = children.getValues(relName);\r
+               for (T child : nodes) {\r
+                       if (children.remove(relName, (T) child)) {\r
+                               fireNodeRemoved(child, relName);\r
+                           child.remove();\r
+                               child.setParent(null, null);\r
+                               \r
+                       }\r
+               }\r
+               return nodes.size() > 0;\r
+       }\r
+\r
+       public synchronized final void removeNodes() {\r
+               synchronized (children) {\r
+                       boolean changed = false;\r
+                       for (String key : children.getKeys()) {\r
+                               for (T child : children.getValues(key)) {\r
+                                       if (child != null) {\r
+                                               changed = true;\r
+                                               if (child instanceof ParentNode<?>) {\r
+                                                       ((ParentNode<?>) child).removeNodes();\r
+                                               }\r
+                                               child.cleanup();\r
+                                               child.setParent(null, null);\r
+                                               // if (propertyChangeListener != null) {\r
+                                               // propertyChangeListener.propertyChange(new\r
+                                               // PropertyChangeEvent(this,\r
+                                               // "children["+child.getId()+"]", child.getClass(),\r
+                                               // NULL)); // "children" is a special field name\r
+                                               // }\r
+                                       }\r
+                               }\r
+                       }\r
+                       children.clear();\r
+                       if (changed)\r
+                               childrenChanged();\r
+               }\r
+       }\r
+\r
+       public synchronized List<T> getNodes(String rel) {\r
+               return children.getValues(rel);\r
+       }\r
+\r
+       public synchronized List<T> getNodes() {\r
+               List<T> result = new ArrayList<T>();\r
+               for (String s : children.getKeys())\r
+                       result.addAll(children.getValues(s));\r
+               return result;\r
+       }\r
+\r
+       protected void childrenChanged() {\r
+       }\r
+\r
+\r
+       @Override\r
+       public void remove() {\r
+               synchronized (children) {\r
+                       List<T> toRemove = new ArrayList<T>();\r
+               \r
+                       for (String key : children.getKeys()) {\r
+               \r
+                               for (T child : children.getValues(key)) {\r
+                                       if (child != null) {\r
+                                               toRemove.add(child);\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       for (T n : toRemove) {\r
+                               n.remove();\r
+                       }\r
+                       \r
+                       children.clear();\r
+                       if (toRemove.size() > 0)\r
+                               childrenChanged();\r
+                       super.remove();\r
+                       \r
+               }\r
+       }\r
+       \r
+       \r
+       \r
+       \r
+       protected void fireNodeAdded(INode node, String rel) {\r
+               for (NodeListener listener : listeners) {\r
+                       listener.nodeAdded(this, node, rel);\r
+               }\r
+       }\r
+       \r
+       protected void fireNodeRemoved(INode node, String rel) {\r
+               for (NodeListener listener : listeners) {\r
+                       listener.nodeRemoved(this, node, rel);\r
+               }\r
+       }\r
+       \r
+}\r