source:
java/main/src/main/java/com/framsticks/gui/TreeNode.java
@
98
Last change on this file since 98 was 98, checked in by , 11 years ago | |
---|---|
File size: 5.6 KB |
Rev | Line | |
---|---|---|
[77] | 1 | package com.framsticks.gui; |
2 | ||
[98] | 3 | import java.lang.ref.WeakReference; |
4 | import java.util.Iterator; | |
5 | import java.util.LinkedList; | |
6 | import java.util.List; | |
7 | import java.util.concurrent.atomic.AtomicInteger; | |
8 | ||
9 | import javax.swing.tree.TreePath; | |
10 | ||
11 | import org.apache.log4j.Logger; | |
12 | ||
13 | import com.framsticks.core.Node; | |
[97] | 14 | import com.framsticks.core.Tree; |
[77] | 15 | import com.framsticks.gui.view.TreeCellRenderer; |
16 | import com.framsticks.params.AccessInterface; | |
[84] | 17 | import com.framsticks.params.CompositeParam; |
[98] | 18 | import com.framsticks.params.types.StringParam; |
19 | import com.framsticks.util.FramsticksException; | |
[84] | 20 | import com.framsticks.util.lang.Casting; |
[98] | 21 | import com.framsticks.util.lang.Pair; |
[84] | 22 | import com.framsticks.util.swing.TooltipConstructor; |
[77] | 23 | |
[98] | 24 | public class TreeNode extends AbstractNode { |
25 | private static final Logger log = Logger.getLogger(TreeNode.class); | |
[77] | 26 | |
27 | ||
[98] | 28 | protected static final AtomicInteger counter = new AtomicInteger(); |
[77] | 29 | |
[98] | 30 | protected final WeakReference<Object> reference; |
[97] | 31 | protected final CompositeParam param; |
[98] | 32 | protected final Tree tree; |
33 | protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>(); | |
34 | protected final int number; | |
[77] | 35 | |
[98] | 36 | public TreeNode(Tree tree, CompositeParam param, Object object) { |
37 | this.tree = tree; | |
38 | this.param = param; | |
39 | reference = new WeakReference<Object>(object); | |
40 | number = counter.getAndIncrement(); | |
41 | } | |
[77] | 42 | |
[98] | 43 | public TreeNode(Node node) { |
44 | this(node.getTree(), node.getParam(), node.assureResolved().getObject()); | |
[84] | 45 | } |
[77] | 46 | |
[98] | 47 | public Node tryCreateNode() { |
48 | Object child = lock(); | |
49 | if (child == null) { | |
50 | return null; | |
51 | } | |
52 | return new Node(tree, param, child); | |
[77] | 53 | } |
54 | ||
[98] | 55 | @Override |
56 | public int getChildCount() { | |
57 | Object referent = lock(); | |
58 | if (referent == null) { | |
59 | return 0; | |
[84] | 60 | } |
[98] | 61 | AccessInterface access = tree.prepareAccess(param).select(referent); |
62 | final int count = access.getCompositeParamCount(); | |
63 | return count; | |
[84] | 64 | } |
[77] | 65 | |
[98] | 66 | public TreeNode getTreeNodeForChild(Object child) { |
67 | Iterator<Pair<WeakReference<Object>, WeakReference<TreeNode>>> i = children.iterator(); | |
68 | while (i.hasNext()) { | |
69 | Pair<WeakReference<Object>, WeakReference<TreeNode>> p = i.next(); | |
70 | Object object = p.first.get(); | |
71 | if (object == null) { | |
72 | i.remove(); | |
73 | continue; | |
[84] | 74 | } |
[98] | 75 | TreeNode treeNode = p.second.get(); |
76 | if (treeNode == null) { | |
77 | i.remove(); | |
78 | continue; | |
79 | } | |
80 | if (object == child) { | |
81 | return treeNode; | |
82 | } | |
[84] | 83 | } |
[98] | 84 | return null; |
[77] | 85 | |
[98] | 86 | // WeakReference<GuiTreeNode> resultReference = children.get(child); |
87 | // if (resultReference == null) { | |
88 | // return null; | |
89 | // } | |
90 | // return resultReference.get(); | |
[84] | 91 | } |
[77] | 92 | |
[98] | 93 | @Override |
94 | public AbstractNode getChild(int number) { | |
95 | Object referent = lock(); | |
96 | if (referent == null) { | |
97 | throw new FramsticksException().msg("invalid state - missing referent"); | |
[84] | 98 | } |
[98] | 99 | AccessInterface access = tree.prepareAccess(param).select(referent); |
[77] | 100 | |
[98] | 101 | final int count = access.getCompositeParamCount(); |
102 | if (number >= count) { | |
103 | throw new FramsticksException().msg("invalid state - no child"); | |
104 | } | |
[77] | 105 | |
[98] | 106 | CompositeParam childParam = access.getCompositeParam(number); |
107 | Object child = access.get(childParam, Object.class); | |
108 | if (child == null) { | |
109 | log.debug("returing dummy node for " + childParam + " in " + referent); | |
110 | return new EmptyNode(childParam); | |
[84] | 111 | } |
[77] | 112 | |
[98] | 113 | TreeNode result = getTreeNodeForChild(child); |
114 | if (result != null) { | |
115 | return result; | |
[84] | 116 | } |
[98] | 117 | result = new TreeNode(tree, childParam, child); |
[77] | 118 | |
[98] | 119 | children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result))); |
[77] | 120 | |
[98] | 121 | return result; |
[77] | 122 | |
[84] | 123 | } |
124 | ||
[98] | 125 | public Object lock() { |
126 | return reference.get(); | |
[84] | 127 | } |
[77] | 128 | |
[98] | 129 | @Override |
130 | public int getIndexOfChild(AbstractNode child) { | |
131 | final TreeNode treeChild = Casting.tryCast(TreeNode.class, child); | |
132 | if (treeChild == null) { | |
133 | return -1; | |
[84] | 134 | } |
[98] | 135 | final Object childObject = treeChild.lock(); |
136 | final Object parentObject = lock(); | |
137 | if (childObject == null || parentObject == null) { | |
138 | return -1; | |
[77] | 139 | } |
[98] | 140 | final AccessInterface access = tree.prepareAccess(param).select(parentObject); |
[77] | 141 | |
[98] | 142 | final int count = access.getCompositeParamCount(); |
143 | for (int i = 0; i < count; ++i) { | |
144 | Object c = access.get(access.getCompositeParam(i), Object.class); | |
145 | if (c == childObject) { | |
146 | return i; | |
[84] | 147 | } |
148 | } | |
[98] | 149 | log.debug(child + " not found in " + this); |
150 | return -1; | |
[84] | 151 | } |
[77] | 152 | |
[98] | 153 | /** |
154 | * @return the param | |
155 | */ | |
156 | public CompositeParam getParam() { | |
157 | return param; | |
[84] | 158 | } |
[77] | 159 | |
[98] | 160 | /** |
161 | * @return the tree | |
162 | */ | |
163 | public Tree getTree() { | |
164 | return tree; | |
[84] | 165 | } |
[77] | 166 | |
167 | ||
[84] | 168 | @Override |
[98] | 169 | public String toString() { |
170 | return param.toString(); | |
[84] | 171 | } |
[77] | 172 | |
[98] | 173 | public static Node tryGetNode(TreePath treePath) { |
174 | return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode(); | |
[84] | 175 | } |
[77] | 176 | |
[84] | 177 | @Override |
[98] | 178 | public boolean isLeaf() { |
179 | Object referent = lock(); | |
180 | if (referent == null) { | |
181 | return true; | |
182 | } | |
183 | AccessInterface access = tree.prepareAccess(param).select(referent); | |
184 | return access.getCompositeParamCount() == 0; | |
[84] | 185 | } |
[77] | 186 | |
187 | ||
[98] | 188 | @Override |
189 | public void render(TreeCellRenderer renderer) { | |
190 | String name = param.getId(); | |
[77] | 191 | |
[98] | 192 | Object child = lock(); |
193 | if (child != null) { | |
194 | AccessInterface access = tree.prepareAccess(param).select(child); | |
[77] | 195 | |
[98] | 196 | StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name")); |
[77] | 197 | |
[98] | 198 | if (nameParam != null) { |
199 | name = access.get(nameParam, String.class); | |
200 | } | |
[78] | 201 | |
[98] | 202 | renderer.setToolTipText(new TooltipConstructor() |
203 | .append("frams", access.getId()) | |
204 | .append("java", child.getClass().getCanonicalName()) | |
205 | .append("access", access.getClass().getSimpleName()) | |
206 | .append("name", name) | |
207 | .append("id", param.getId()) | |
208 | .append("object", Integer.toHexString(System.identityHashCode(child))) | |
209 | .append("number", number) | |
210 | .build()); | |
211 | } else { | |
212 | renderer.setToolTipText("?"); | |
[77] | 213 | } |
[98] | 214 | renderer.setText(name); |
215 | renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param))); | |
[96] | 216 | |
[77] | 217 | } |
[97] | 218 | |
[77] | 219 | } |
Note: See TracBrowser
for help on using the repository browser.