]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/g3d/scenegraph/base/ParentNode.java
681121778d8cf2cb083a874809774a8f18fb6475
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / g3d / scenegraph / base / ParentNode.java
1 package org.simantics.g3d.scenegraph.base;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.List;\r
6 \r
7 import org.simantics.utils.datastructures.MapList;\r
8 \r
9 public abstract class ParentNode<T extends INode> extends Node {\r
10 \r
11         private MapList<String, T> children = new MapList<String, T>();\r
12 \r
13         public synchronized void addNode(String relName, T child) {\r
14                 if (child.getParent() != null)\r
15                         child.getParent().removeNode(child.getParentRel(), child);\r
16 \r
17                 child.setParent(this, relName);\r
18                 children.add(relName, (T) child);\r
19 \r
20                 childrenChanged();\r
21                 fireNodeAdded(child, relName);\r
22         }\r
23 \r
24         /**\r
25          * Removes child node and it's hierarchy.\r
26          * @param relName\r
27          * @param child\r
28          * @return\r
29          */\r
30         @SuppressWarnings("unchecked")\r
31         public synchronized final boolean removeNode(String relName, INode child) {\r
32                 if (children.remove(relName, (T) child)) {\r
33                         fireNodeRemoved(child, relName);\r
34                     child.remove();\r
35                         child.setParent(null, null);\r
36                         return true;\r
37                 }\r
38                 return false;\r
39         }\r
40         \r
41         /**\r
42          * Removes child node. The child nodes hierarchy is left intact.\r
43          * @param relName\r
44          * @param child\r
45          * @return\r
46          */\r
47         @SuppressWarnings("unchecked")\r
48         public synchronized final boolean deattachNode(String relName, INode child) {\r
49                 if (children.remove(relName, (T) child)) {\r
50                         fireNodeRemoved(child, relName);\r
51                         child.setParent(null, null);\r
52                         return true;\r
53                 }\r
54                 return false;\r
55         }\r
56         \r
57         public synchronized final boolean removeNodes(String relName) {\r
58                 List<T> nodes = children.getValues(relName);\r
59                 for (T child : nodes) {\r
60                         if (children.remove(relName, (T) child)) {\r
61                                 fireNodeRemoved(child, relName);\r
62                             child.remove();\r
63                                 child.setParent(null, null);\r
64                                 \r
65                         }\r
66                 }\r
67                 return nodes.size() > 0;\r
68         }\r
69 \r
70         public synchronized final void removeNodes() {\r
71                 synchronized (children) {\r
72                         boolean changed = false;\r
73                         for (String key : children.getKeys()) {\r
74                                 for (T child : children.getValues(key)) {\r
75                                         if (child != null) {\r
76                                                 changed = true;\r
77                                                 if (child instanceof ParentNode<?>) {\r
78                                                         ((ParentNode<?>) child).removeNodes();\r
79                                                 }\r
80                                                 child.cleanup();\r
81                                                 child.setParent(null, null);\r
82                                                 // if (propertyChangeListener != null) {\r
83                                                 // propertyChangeListener.propertyChange(new\r
84                                                 // PropertyChangeEvent(this,\r
85                                                 // "children["+child.getId()+"]", child.getClass(),\r
86                                                 // NULL)); // "children" is a special field name\r
87                                                 // }\r
88                                         }\r
89                                 }\r
90                         }\r
91                         children.clear();\r
92                         if (changed)\r
93                                 childrenChanged();\r
94                 }\r
95         }\r
96 \r
97         public synchronized List<T> getNodes(String rel) {\r
98                 return children.getValues(rel);\r
99         }\r
100 \r
101         public synchronized List<T> getNodes() {\r
102                 List<T> result = new ArrayList<T>();\r
103                 for (String s : children.getKeys())\r
104                         result.addAll(children.getValues(s));\r
105                 return result;\r
106         }\r
107 \r
108         protected void childrenChanged() {\r
109         }\r
110 \r
111 \r
112         @Override\r
113         public void remove() {\r
114                 synchronized (children) {\r
115                         List<T> toRemove = new ArrayList<T>();\r
116                 \r
117                         for (String key : children.getKeys()) {\r
118                 \r
119                                 for (T child : children.getValues(key)) {\r
120                                         if (child != null) {\r
121                                                 toRemove.add(child);\r
122                                         }\r
123                                 }\r
124                         }\r
125 \r
126                         for (T n : toRemove) {\r
127                                 n.remove();\r
128                         }\r
129                         \r
130                         children.clear();\r
131                         if (toRemove.size() > 0)\r
132                                 childrenChanged();\r
133                         super.remove();\r
134                         \r
135                 }\r
136         }\r
137         \r
138         \r
139         \r
140         \r
141         protected void fireNodeAdded(INode node, String rel) {\r
142                 for (NodeListener listener : listeners) {\r
143                         listener.nodeAdded(this, node, rel);\r
144                 }\r
145         }\r
146         \r
147         protected void fireNodeRemoved(INode node, String rel) {\r
148                 for (NodeListener listener : listeners) {\r
149                         listener.nodeRemoved(this, node, rel);\r
150                 }\r
151         }\r
152         \r
153 }\r