Changeset 100 for java/main/src/main/java/com/framsticks/gui/tree
- Timestamp:
- 07/12/13 23:41:06 (11 years ago)
- Location:
- java/main/src/main/java/com/framsticks/gui/tree
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
java/main/src/main/java/com/framsticks/gui/tree/AbstractNode.java
r99 r100 1 1 package com.framsticks.gui.tree; 2 3 import com.framsticks.gui.AbstractPanel; 2 4 3 5 … … 9 11 10 12 public abstract int getChildCount(); 11 public abstract AbstractNodegetChild(int number);12 public abstract int getIndexOfChild( AbstractNodechild);13 public abstract Object getChild(int number); 14 public abstract int getIndexOfChild(Object child); 13 15 14 16 public abstract boolean isLeaf(); 15 17 public abstract void render(TreeCellRenderer renderer); 16 18 19 public abstract AbstractPanel getPanel(); 20 17 21 } -
java/main/src/main/java/com/framsticks/gui/tree/EmptyNode.java
r99 r100 2 2 3 3 4 import com.framsticks.gui.AbstractPanel; 5 import com.framsticks.gui.Frame; 4 6 import com.framsticks.gui.ImageProvider; 5 7 import com.framsticks.params.CompositeParam; … … 8 10 9 11 protected final CompositeParam param; 12 protected final Frame frame; 10 13 11 14 /** 12 15 * @param param 13 16 */ 14 public EmptyNode( CompositeParam param) {17 public EmptyNode(Frame frame, CompositeParam param) { 15 18 this.param = param; 19 this.frame = frame; 16 20 } 17 21 … … 22 26 23 27 @Override 24 public AbstractNodegetChild(int number) {28 public Object getChild(int number) { 25 29 return null; 26 30 } 27 31 28 32 @Override 29 public int getIndexOfChild( AbstractNodechild) {33 public int getIndexOfChild(Object child) { 30 34 return -1; 31 35 } … … 33 37 @Override 34 38 public boolean isLeaf() { 35 return true;39 return false; 36 40 } 37 41 38 42 @Override 39 43 public void render(TreeCellRenderer renderer) { 40 renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param))); 44 // TODO Auto-generated method stub 45 46 renderer.setToolTipText("?"); 41 47 renderer.setText(param.getId()); 42 renderer.setToolTipText("?"); 48 renderer.setIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED)); 49 } 50 51 /** 52 * @return the param 53 */ 54 public CompositeParam getParam() { 55 return param; 43 56 } 44 57 45 58 @Override 46 public String toString() {47 return param.toString();59 public AbstractPanel getPanel() { 60 return frame.getEmptyPanel(); 48 61 } 49 62 -
java/main/src/main/java/com/framsticks/gui/tree/MetaNode.java
r99 r100 5 5 6 6 7 import com.framsticks.gui.AbstractPanel; 8 import com.framsticks.gui.Frame; 7 9 import com.framsticks.gui.ImageProvider; 8 10 9 11 public class MetaNode extends AbstractNode { 10 12 11 protected List<AbstractNode> children = new LinkedList<>(); 13 protected final Frame frame; 14 protected final List<Object> children = new LinkedList<>(); 12 15 protected String name = "meta node"; 16 17 /** 18 * @param frame 19 */ 20 public MetaNode(Frame frame) { 21 this.frame = frame; 22 } 13 23 14 24 /** 15 25 * @return the children 16 26 */ 17 public List< AbstractNode> getChildren() {27 public List<Object> getChildren() { 18 28 return children; 19 29 } … … 39 49 40 50 @Override 41 public AbstractNodegetChild(int number) {51 public Object getChild(int number) { 42 52 return children.get(number); 43 53 } 44 54 45 55 @Override 46 public int getIndexOfChild( AbstractNodechild) {56 public int getIndexOfChild(Object child) { 47 57 return children.indexOf(child); 48 58 } … … 65 75 } 66 76 77 @Override 78 public AbstractPanel getPanel() { 79 return frame.getEmptyPanel(); 80 } 81 67 82 } -
java/main/src/main/java/com/framsticks/gui/tree/TreeCellRenderer.java
r99 r100 15 15 public class TreeCellRenderer extends DefaultTreeCellRenderer { 16 16 17 p ublic TreeCellRenderer() {17 protected final TreeModel treeModel; 18 18 19 // setOpenIcon(ImageProvider.loadImage(ImageProvider.FOLDER_OPEN)); 20 // setClosedIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED)); 21 // setLeafIcon(ImageProvider.loadImage(ImageProvider.NODE)); 19 20 /** 21 * @param treeModel 22 */ 23 public TreeCellRenderer(TreeModel treeModel) { 24 this.treeModel = treeModel; 22 25 } 23 26 … … 35 38 36 39 if (!(value instanceof AbstractNode)) { 37 set Icon(ImageProvider.loadImage(ImageProvider.SERVER));38 setText("framsticks");40 setText("?"); 41 // treeModel.renderTreeObject(Casting.throwCast(TreeNode.class, value), this); 39 42 return this; 40 43 } … … 92 95 93 96 94 95 97 } -
java/main/src/main/java/com/framsticks/gui/tree/TreeModel.java
r99 r100 1 1 package com.framsticks.gui.tree; 2 2 3 //import java.util.Enumeration;3 import java.util.Enumeration; 4 4 import java.util.Iterator; 5 5 import java.util.LinkedList; 6 6 import java.util.List; 7 7 8 import javax.annotation.Nullable; 8 9 import javax.swing.event.TreeModelEvent; 9 10 import javax.swing.event.TreeModelListener; 10 11 import javax.swing.tree.TreePath; 11 12 12 import org.apache.log4j.Logger; 13 14 13 import org.apache.logging.log4j.Logger; 14 import org.apache.logging.log4j.LogManager; 15 16 import com.framsticks.core.ListChange; 15 17 import com.framsticks.core.Node; 16 18 import com.framsticks.core.Path; 17 import com.framsticks.core.Tree;18 19 import com.framsticks.core.TreeOperations; 19 20 import com.framsticks.gui.Frame; 20 import com.framsticks.params.AccessInterface; 21 import com.framsticks.params.Access; 22 import com.framsticks.params.CompositeParam; 23 import com.framsticks.params.EventListener; 24 import com.framsticks.params.ListAccess; 25 import com.framsticks.params.PrimitiveParam; 26 import com.framsticks.params.Util; 27 import com.framsticks.params.ValueParam; 28 import com.framsticks.params.types.EventParam; 21 29 import com.framsticks.util.FramsticksException; 30 import com.framsticks.util.Misc; 22 31 import com.framsticks.util.UnsupportedOperationException; 23 32 import com.framsticks.util.dispatching.FutureHandler; 24 33 import com.framsticks.util.lang.Casting; 25 34 35 import static com.framsticks.core.TreeOperations.*; 36 26 37 public class TreeModel implements javax.swing.tree.TreeModel { 27 private static final Logger log = Log ger.getLogger(TreeModel.class);38 private static final Logger log = LogManager.getLogger(TreeModel.class); 28 39 29 40 30 41 protected List<TreeModelListener> listeners = new LinkedList<>(); 42 31 43 32 44 protected final Frame frame; … … 45 57 46 58 @Override 47 public AbstractNodegetChild(Object parent, int number) {48 return Casting. assertCast(AbstractNode.class, parent).getChild(number);59 public Object getChild(Object parent, int number) { 60 return Casting.throwCast(AbstractNode.class, parent).getChild(number); 49 61 } 50 62 51 63 @Override 52 64 public int getChildCount(Object parent) { 53 return Casting. assertCast(AbstractNode.class, parent).getChildCount();65 return Casting.throwCast(AbstractNode.class, parent).getChildCount(); 54 66 } 55 67 … … 59 71 return -1; 60 72 } 61 return Casting. assertCast(AbstractNode.class, parent).getIndexOfChild(Casting.assertCast(AbstractNode.class, child));73 return Casting.throwCast(AbstractNode.class, parent).getIndexOfChild(child); 62 74 } 63 75 … … 69 81 @Override 70 82 public boolean isLeaf(Object node) { 71 return Casting. assertCast(AbstractNode.class, node).isLeaf();83 return Casting.throwCast(AbstractNode.class, node).isLeaf(); 72 84 } 73 85 … … 85 97 protected boolean changing = false; 86 98 87 public void nodeStructureChanged(TreePath treePath) { 99 public void treeNodesInserted(TreeModelEvent event) { 100 assert frame.isActive(); 101 try { 102 for (TreeModelListener listener : listeners) { 103 listener.treeNodesInserted(event); 104 } 105 } catch (ArrayIndexOutOfBoundsException e) { 106 } 107 } 108 109 public void treeNodesRemoved(TreeModelEvent event) { 110 assert frame.isActive(); 111 try { 112 for (TreeModelListener listener : listeners) { 113 listener.treeNodesRemoved(event); 114 } 115 } catch (ArrayIndexOutOfBoundsException e) { 116 } 117 } 118 119 public void treeNodesChanged(TreeModelEvent event) { 120 try { 121 for (TreeModelListener listener : listeners) { 122 listener.treeNodesChanged(event); 123 } 124 } catch (ArrayIndexOutOfBoundsException e) { 125 } 126 } 127 128 public TreeModelEvent prepareModelEvent(TreePath treePath, int number, TreeNode node) { 129 return new TreeModelEvent(this, treePath, new int[] {number}, new Object[] { node }); 130 } 131 132 133 public TreeModelEvent prepareModelEventRegarding(Access access, String id, TreePath treeListPath) { 134 135 int number = Util.getNumberOfCompositeParamChild(access, access.get(id, Object.class)); 136 if (number == -1) { 137 log.debug("encountered minor tree inconsistency in {}", treeListPath); 138 return null; 139 } 140 TreeNode node = Casting.throwCast(TreeNode.class, Casting.throwCast(TreeNode.class, treeListPath.getLastPathComponent()).getChild(number)); 141 return prepareModelEvent(treeListPath, number, node); 142 } 143 144 public void treeStructureChanged(TreePath treePath) { 145 88 146 if (treePath == null) { 89 147 return; … … 92 150 93 151 changing = true; 94 log.debug("changing : " +treePath);95 // Enumeration<TreePath> expanded = frame.jtree.getExpandedDescendants(treePath);152 log.debug("changing structure: {}", treePath); 153 Enumeration<TreePath> expanded = frame.getJtree().getExpandedDescendants(treePath); 96 154 TreePath selection = frame.getJtree().getSelectionPath(); 97 155 98 for (TreeModelListener listener : listeners) { 99 listener.treeStructureChanged(new TreeModelEvent(this, treePath)); 100 } 101 // if (expanded != null) { 102 // while (expanded.hasMoreElements()) { 103 // TreePath expansion = expanded.nextElement(); 104 // // log.info("reexpanding: " + expansion); 105 // frame.jtree.expandPath(expansion); 106 // } 107 // } 156 try { 157 for (TreeModelListener listener : listeners) { 158 listener.treeStructureChanged(new TreeModelEvent(this, treePath)); 159 } 160 } catch (ArrayIndexOutOfBoundsException e) { 161 } 162 163 164 if (expanded != null) { 165 while (expanded.hasMoreElements()) { 166 TreePath expansion = expanded.nextElement(); 167 // log.info("reexpanding: {}", expansion); 168 frame.getJtree().expandPath(expansion); 169 } 170 } 171 108 172 if (selection != null) { 109 173 frame.getJtree().setSelectionPath(selection); … … 112 176 } 113 177 114 public Path convertToPath(TreePath treePath) { 178 /** 179 * 180 * This method may return null on conversion failure, which may happen in highload situations. 181 */ 182 public @Nullable Path convertToPath(TreePath treePath) { 115 183 final Object[] components = treePath.getPath(); 116 184 assert components[0] == frame.getRootNode(); … … 128 196 Node node = treeNode.tryCreateNode(); 129 197 if (node == null) { 130 throw new FramsticksException().msg("failed to recreate path").arg("treePath", treePath); 198 return null; 199 // throw new FramsticksException().msg("failed to recreate path").arg("treePath", treePath); 131 200 } 132 201 nodes.add(node); … … 137 206 } 138 207 139 public TreePath convertToTreePath(Path path ) {208 public TreePath convertToTreePath(Path path, boolean forceComplete) { 140 209 assert frame.isActive(); 141 210 … … 143 212 accumulator.add(getRoot()); 144 213 145 for ( AbstractNoder : getRoot().getChildren()) {214 for (Object r : getRoot().getChildren()) { 146 215 if (r instanceof TreeNode) { 147 216 TreeNode root = (TreeNode) r; 148 217 if (root.getTree() == path.getTree()) { 218 Iterator<Node> n = path.getNodes().iterator(); 219 TreeNode treeNode = root; 149 220 accumulator.add(root); 150 151 Iterator<Node> i = path.getNodes().iterator(); 152 i.next(); 153 TreeNode treeNode = root; 154 155 while (i.hasNext()) { 156 Node node = i.next(); 157 treeNode = treeNode.getTreeNodeForChild(node.getObject()); 221 n.next(); 222 while (n.hasNext()) { 223 Node node = n.next(); 224 treeNode = treeNode.prepareTreeNodeForChild(Path.build().tree(path.getTree()).buildUpTo(path.getNodes(), node).finish()); 158 225 if (treeNode == null) { 159 226 break; … … 161 228 accumulator.add(treeNode); 162 229 } 163 164 230 break; 165 231 } … … 167 233 } 168 234 return new TreePath(accumulator.toArray()); 235 } 236 237 /** 238 * @return the listeners 239 */ 240 public List<TreeModelListener> getListeners() { 241 return listeners; 169 242 } 170 243 … … 180 253 return; 181 254 } 182 Access Interfaceaccess = TreeOperations.bindAccess(path);255 Access access = TreeOperations.bindAccess(path); 183 256 184 257 int count = access.getCompositeParamCount(); … … 193 266 return; 194 267 } 195 if ( path.isResolved() && !reload) {268 if (!reload && path.isResolved() && isMarked(path.getTree(), path.getTopObject(), FETCHED_MARK, false)) { 196 269 return; 197 270 } … … 199 272 @Override 200 273 protected void result(Path result) { 201 final TreePath treePath = convertToTreePath(result); 202 203 nodeStructureChanged(treePath); 204 frame.updatePanelIfIsLeadSelection(treePath, result); 274 final TreePath treePath = convertToTreePath(result, true); 275 276 277 if (treePath != null) { 278 treeStructureChanged(treePath); 279 frame.updatePanelIfIsLeadSelection(result); 280 } 205 281 } 206 282 }); 207 283 } 208 284 209 public void chooseTreeNode(finalTreePath treePath) {285 public void expandTreeNode(TreePath treePath) { 210 286 assert frame.isActive(); 211 287 if (treePath == null) { … … 215 291 return; 216 292 } 217 218 293 Path path = convertToPath(treePath); 219 294 if (path == null) { 220 295 return; 221 296 } 297 loadChildren(path.assureResolved(), false); 298 } 299 300 public void chooseTreeNode(final TreePath treePath) { 301 assert frame.isActive(); 302 if (treePath == null) { 303 return; 304 } 305 if (isChanging()) { 306 return; 307 } 308 309 Path path = convertToPath(treePath); 310 if (path == null) { 311 return; 312 } 222 313 path = path.assureResolved(); 223 final Tree tree = path.getTree(); 224 225 frame.getTreeAtFrames().get(tree).useOrCreatePanel(treePath); 226 loadChildren(path, false); 227 228 } 314 315 log.debug("choosing {}", path); 316 frame.showPanelForTreePath(treePath); 317 loadPath(path, false); 318 319 } 320 321 322 protected void registerForEventParam(final TreeNode treeNode, Path path, final EventParam eventParam, ValueParam valueParam) { 323 /** TODO make this listener not bind hold the reference to this TreeNode, maybe hold WeakReference internally */ 324 if (valueParam instanceof PrimitiveParam) { 325 326 treeNode.tryAddListener(path, eventParam, Object.class, new EventListener<Object>() { 327 @Override 328 public void action(Object argument) { 329 loadPath(treeNode.assurePath(), true); 330 } 331 }); 332 333 } else if (valueParam instanceof CompositeParam) { 334 335 final CompositeParam compositeParam = (CompositeParam) valueParam; 336 337 treeNode.tryAddListener(path, eventParam, ListChange.class, new EventListener<ListChange>() { 338 @Override 339 public void action(ListChange listChange) { 340 assert treeNode.getTree().isActive(); 341 342 Path parentPath = treeNode.assurePath(); 343 final Path listPath = parentPath.appendParam(compositeParam).tryFindResolution(); 344 if (!listPath.isResolved()) { 345 /** that situation is quietly ignored - it may happen if first event comes before the container was resolved */ 346 return; 347 } 348 349 log.debug("reacting to change {} in {}", listChange, listPath); 350 final TreePath treeListPath = convertToTreePath(listPath, true); 351 if (treeListPath == null) { 352 throw new FramsticksException().msg("path was not fully converted").arg("path", listPath); 353 } 354 355 if ((listChange.getAction().equals(ListChange.Action.Modify)) && (listChange.getPosition() == -1)) { 356 // get(listPath, future); 357 // treeModel.nodeStructureChanged(treePath); 358 // frame.updatePanelIfIsLeadSelection(treePath, result); 359 return; 360 } 361 final String id = listChange.getBestIdentifier(); 362 363 final ListAccess access = (ListAccess) bindAccess(listPath); 364 switch (listChange.getAction()) { 365 case Add: { 366 Path childPath = listPath.appendParam(access.prepareParamFor(id)).tryFindResolution(); 367 if (!childPath.isResolved()) { 368 childPath = create(childPath); 369 370 TreeModelEvent event = prepareModelEventRegarding(access, id, treeListPath); 371 if (event != null) { 372 treeNodesInserted(event); 373 } else { 374 treeStructureChanged(treeListPath); 375 } 376 frame.updatePanelIfIsLeadSelection(listPath); 377 } 378 379 listPath.getTree().get(childPath, new FutureHandler<Path>(frame) { 380 @Override 381 protected void result(Path result) { 382 if (!result.isResolved()) { 383 log.warn("inconsistency after addition list change: {}", result); 384 } 385 assert frame.isActive(); 386 final TreePath treePath = Misc.throwIfNull(frame.getTreeModel().convertToTreePath(result, true)); 387 388 // treeModel.nodeStructureChanged(treePath); 389 frame.updatePanelIfIsLeadSelection(result); 390 391 log.debug("added {}({}) updated {}", id, result, treePath); 392 } 393 }); 394 break; 395 } 396 case Remove: { 397 398 TreeModelEvent event = prepareModelEventRegarding(access, id, treeListPath); 399 access.set(id, null); 400 if (event != null) { 401 treeNodesRemoved(event); 402 } else { 403 treeStructureChanged(treeListPath); 404 } 405 406 frame.updatePanelIfIsLeadSelection(listPath); 407 408 break; 409 } 410 case Modify: { 411 Path childPath = listPath.appendParam(access.prepareParamFor(id)).tryResolveIfNeeded(); 412 listPath.getTree().get(childPath, new FutureHandler<Path>(frame) { 413 @Override 414 protected void result(Path result) { 415 assert frame.isActive(); 416 // final TreePath treePath = frame.getTreeModel().convertToTreePath(result, true); 417 418 TreeModelEvent event = prepareModelEventRegarding(access, id, treeListPath); 419 if (event != null) { 420 treeNodesChanged(event); 421 } else { 422 treeStructureChanged(treeListPath); 423 } 424 425 frame.updatePanelIfIsLeadSelection(listPath); 426 frame.updatePanelIfIsLeadSelection(result); 427 } 428 }); 429 break; 430 } 431 } 432 } 433 }); 434 } 435 436 } 437 438 439 440 protected final Object createdTag = new Object(); 441 442 443 229 444 } -
java/main/src/main/java/com/framsticks/gui/tree/TreeNode.java
r99 r100 5 5 import java.util.LinkedList; 6 6 import java.util.List; 7 import java.util.concurrent.atomic.AtomicInteger; 8 9 import javax.swing.ImageIcon; 10 import javax.swing.tree.TreePath; 11 12 import org.apache.log4j.Logger; 13 14 import com.framsticks.core.ListChange; 7 8 import org.apache.logging.log4j.LogManager; 9 import org.apache.logging.log4j.Logger; 10 15 11 import com.framsticks.core.Node; 16 12 import com.framsticks.core.Path; … … 19 15 import com.framsticks.gui.ImageProvider; 20 16 import com.framsticks.gui.TreeAtFrame; 21 import com.framsticks.params.AccessInterface; 17 import com.framsticks.gui.TreePanel; 18 import com.framsticks.params.Access; 22 19 import com.framsticks.params.CompositeParam; 23 20 import com.framsticks.params.EventListener; 24 21 import com.framsticks.params.FramsClass; 25 import com.framsticks.params.PrimitiveParam;26 22 import com.framsticks.params.ValueParam; 27 23 import com.framsticks.params.types.EventParam; … … 32 28 import com.framsticks.util.lang.Casting; 33 29 import com.framsticks.util.lang.Containers; 34 import com.framsticks.util.lang.Pair;35 30 import com.framsticks.util.swing.TooltipConstructor; 31 36 32 import static com.framsticks.core.TreeOperations.*; 37 33 38 34 public class TreeNode extends AbstractNode { 39 private static final Logger log = Logger.getLogger(TreeNode.class); 40 41 42 protected static final AtomicInteger counter = new AtomicInteger(); 35 36 private static final Logger log = LogManager.getLogger(TreeNode.class); 43 37 44 38 protected final WeakReference<Object> reference; 39 protected final int hashCode; 40 protected final TreeAtFrame treeAtFrame; 41 protected final String textual; 45 42 protected final CompositeParam param; 46 protected final TreeAtFrame treeAtFrame;47 protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>(); 48 p rotected final int number;49 protected final String textualPath;50 protected final ImageIcon imageIcon;51 protected final TreeModel treeModel; 52 53 protected final List<EventListener<?>> listeners = new LinkedList<>();54 43 protected TreePanel panel; 44 45 public TreeModel getTreeModel() { 46 return treeAtFrame.getFrame().getTreeModel(); 47 } 48 49 /** 50 * @param reference 51 */ 55 52 public TreeNode(TreeAtFrame treeAtFrame, Path path) { 56 53 path.assureResolved(); 57 this.textualPath = path.getTextual(); 54 55 this.reference = new WeakReference<Object>(path.getTopObject()); 56 this.textual = path.getTextual(); 57 this.treeAtFrame = treeAtFrame; 58 58 this.param = path.getTop().getParam(); 59 this.treeAtFrame = treeAtFrame; 60 this.treeModel = treeAtFrame.getFrame().getTreeModel(); 61 this.imageIcon = ImageProvider.loadImage(TreeCellRenderer.findIconName(param)); 62 63 reference = new WeakReference<Object>(path.getTop().getObject()); 64 number = counter.getAndIncrement(); 59 hashCode = System.identityHashCode(path.getTopObject()); 60 61 if (getTree().getSideNote(path.getTopObject(), getTreeModel().createdTag, Object.class) == getTreeModel().createdTag) { 62 return; 63 } 64 65 // path.getTree().putSideNote(path.getTopObject(), Textual.class, path.getTextual()); 66 path.getTree().putSideNote(path.getTopObject(), getTreeModel().createdTag, getTreeModel().createdTag); 65 67 66 68 /** Iterate over all EventParams and for matching ValueParams register listeners. */ 67 if (pa raminstanceof ObjectParam) {68 Access Interfaceaccess = bindAccess(path);69 if (path.getTop().getParam() instanceof ObjectParam) { 70 Access access = bindAccess(path); 69 71 FramsClass framsClass = access.getFramsClass(); 70 72 for (EventParam eventParam : Containers.filterInstanceof(framsClass.getParamEntries(), EventParam.class)) { … … 77 79 continue; 78 80 } 79 registerForEventParam(path, eventParam, valueParam); 80 } 81 } 82 } 83 84 protected <A> void tryAddListener(final Path path, final EventParam eventParam, Class<A> argumentType, final EventListener<A> listener) { 85 treeAtFrame.getTree().addListener(path, eventParam, listener, argumentType, new FutureHandler<Void>(treeAtFrame.getFrame()) { 86 @Override 87 protected void result(Void result) { 88 assert treeAtFrame.getFrame().isActive(); 89 log.debug("registered gui listener for " + eventParam + " at " + path); 90 listeners.add(listener); 91 } 92 }); 93 } 94 95 protected void registerForEventParam(Path path, EventParam eventParam, ValueParam valueParam) { 96 /** TODO make this listener not bind hold the reference to this TreeNode, maybe hold WeakReference internally */ 97 if (valueParam instanceof PrimitiveParam) { 98 99 tryAddListener(path, eventParam, Object.class, new EventListener<Object>() { 100 @Override 101 public void action(Object argument) { 102 treeModel.loadPath(assurePath(), true); 103 } 104 }); 105 106 } else if (valueParam instanceof CompositeParam) { 107 108 final CompositeParam compositeParam = (CompositeParam) valueParam; 109 110 tryAddListener(path, eventParam, ListChange.class, new EventListener<ListChange>() { 111 @Override 112 public void action(ListChange listChange) { 113 assert treeAtFrame.getTree().isActive(); 114 115 final Path listPath = assurePath().appendParam(compositeParam).tryFindResolution().assureResolved(); 116 log.debug("reacting to change " + listChange + " in " + listPath); 117 118 if ((listChange.getAction().equals(ListChange.Action.Modify)) && (listChange.getPosition() == -1)) { 119 // get(listPath, future); 120 return; 121 } 122 final String id = listChange.getBestIdentifier(); 123 124 AccessInterface access = bindAccess(listPath); 125 switch (listChange.getAction()) { 126 case Add: { 127 tryGet(listPath.getTree(), Path.appendString(listPath.getTextual(), id), new FutureHandler<Path>(treeAtFrame.getFrame()) { 128 @Override 129 protected void result(Path result) { 130 final Frame frame = treeAtFrame.getFrame(); 131 assert frame.isActive(); 132 final TreePath treePath = frame.getTreeModel().convertToTreePath(listPath); 133 treeModel.nodeStructureChanged(treePath); 134 frame.updatePanelIfIsLeadSelection(treePath, listPath); 135 log.debug("added " + id + "(" + result + ") updated " + treePath); 136 } 137 }); 138 break; 139 } 140 case Remove: { 141 access.set(id, null); 142 Frame frame = treeAtFrame.getFrame(); 143 treeModel.nodeStructureChanged(frame.getTreeModel().convertToTreePath(listPath)); 144 break; 145 } 146 case Modify: { 147 tryGet(listPath.getTree(), Path.appendString(listPath.getTextual(), id), new FutureHandler<Path>(treeAtFrame.getFrame()) { 148 @Override 149 protected void result(Path result) { 150 final Frame frame = treeAtFrame.getFrame(); 151 assert frame.isActive(); 152 final TreePath treePath = frame.getTreeModel().convertToTreePath(result); 153 treeModel.nodeStructureChanged(treePath); 154 frame.updatePanelIfIsLeadSelection(treePath, listPath); 155 } 156 }); 157 break; 158 } 159 } 160 } 161 }); 162 } 163 164 } 165 166 protected Path assurePath() { 167 return Path.to(treeAtFrame.getTree(), textualPath).assureResolved(); 168 } 169 170 public Node tryCreateNode() { 171 Object child = lock(); 172 if (child == null) { 173 return null; 174 } 175 return Path.to(treeAtFrame.getTree(), textualPath).assureResolved().getTop(); 176 } 177 178 @Override 179 public int getChildCount() { 180 Object referent = lock(); 181 if (referent == null) { 182 return 0; 183 } 184 AccessInterface access = bindAccessFor(referent); 185 final int count = access.getCompositeParamCount(); 186 return count; 187 } 188 189 public TreeNode getTreeNodeForChild(Object child) { 190 Iterator<Pair<WeakReference<Object>, WeakReference<TreeNode>>> i = children.iterator(); 191 while (i.hasNext()) { 192 Pair<WeakReference<Object>, WeakReference<TreeNode>> p = i.next(); 193 Object object = p.first.get(); 194 if (object == null) { 195 i.remove(); 196 continue; 197 } 198 TreeNode treeNode = p.second.get(); 199 if (treeNode == null) { 200 i.remove(); 201 continue; 202 } 203 if (object == child) { 204 return treeNode; 205 } 206 } 207 return null; 208 209 // WeakReference<GuiTreeNode> resultReference = children.get(child); 210 // if (resultReference == null) { 211 // return null; 212 // } 213 // return resultReference.get(); 81 getTreeModel().registerForEventParam(this, path, eventParam, valueParam); 82 } 83 } 84 } 85 86 @Override 87 public int hashCode() { 88 return hashCode; 89 } 90 91 @Override 92 public boolean equals(Object obj) { 93 if (obj instanceof TreeNode) { 94 return lock() == ((TreeNode) obj).lock(); 95 } 96 return false; 214 97 } 215 98 … … 220 103 throw new FramsticksException().msg("invalid state - missing referent"); 221 104 } 222 AccessInterface access = bindAccessFor(referent); 105 Tree tree = getTree(); 106 Access access = bindAccessForTreeObject(referent); 223 107 224 108 final int count = access.getCompositeParamCount(); … … 227 111 } 228 112 113 /** textual path may be not valid anymore*/ 229 114 CompositeParam childParam = access.getCompositeParam(number); 230 Object child = access.get(childParam, Object.class); 231 if (child == null) { 232 log.debug("returning dummy node for " + childParam + " in " + referent); 233 return new EmptyNode(childParam); 234 } 235 236 TreeNode result = getTreeNodeForChild(child); 237 if (result != null) { 238 return result; 239 } 240 Path path = Path.to(treeAtFrame.getTree(), Path.appendString(textualPath, childParam.getId())).assureResolved(); 241 result = new TreeNode(treeAtFrame, path); 242 243 children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result))); 244 245 return result; 246 115 116 try { 117 Path path = Path.to(tree, getTextual()).appendParam(childParam).tryFindResolution(); 118 if (!path.isResolved()) { 119 path = create(path); 120 } 121 return prepareTreeNodeForChild(path); 122 } catch (FramsticksException e) { 123 } 124 return new EmptyNode(getFrame(), childParam); 125 126 } 127 128 public TreeNode prepareTreeNodeForChild(Path path) { 129 assert path.getTree() == getTree(); 130 Object parent = lock(); 131 Iterator<Node> n = path.getNodes().iterator(); 132 while (n.hasNext()) { 133 if (n.next().getObject() == parent) { 134 break; 135 } 136 } 137 if (!n.hasNext()) { 138 return null; 139 // throw new FramsticksException().msg("tree node is not on path (or is last)").arg("path", path).arg("node", this); 140 } 141 return new TreeNode(treeAtFrame, path); 247 142 } 248 143 … … 252 147 253 148 @Override 254 public int getIndexOfChild( AbstractNodechild) {149 public int getIndexOfChild(Object child) { 255 150 final TreeNode treeChild = Casting.tryCast(TreeNode.class, child); 256 151 if (treeChild == null) { … … 262 157 return -1; 263 158 } 264 final Access Interface access = bindAccessFor(parentObject);159 final Access access = bindAccessForTreeObject(parentObject); 265 160 266 161 final int count = access.getCompositeParamCount(); … … 271 166 } 272 167 } 273 log.debug( child + " not found in " +this);168 log.debug("{} not found in {}", child, this); 274 169 return -1; 275 170 } 276 171 277 /** 278 * @return the param 279 */ 280 public CompositeParam getParam() { 281 return param; 282 } 283 284 /** 285 * @return the tree 286 */ 172 public Frame getFrame() { 173 return getTreeAtFrame().getFrame(); 174 } 175 176 public TreeAtFrame getTreeAtFrame() { 177 return treeAtFrame; 178 } 179 287 180 public Tree getTree() { 288 return treeAtFrame.getTree(); 289 } 290 181 return getTreeAtFrame().getTree(); 182 } 183 184 protected Path assurePath() { 185 return Path.to(getTree(), getTextual()).assureResolved(); 186 } 291 187 292 188 @Override 293 189 public String toString() { 294 return param.toString(); 295 } 296 297 public static Node tryGetNode(TreePath treePath) { 298 return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode(); 190 return getTextual(); 191 } 192 193 public Node tryCreateNode() { 194 Object child = lock(); 195 if (child == null) { 196 return null; 197 } 198 String textual = getTextual(); 199 Path path = Path.tryTo(getTree(), textual); 200 if (path.isResolved(textual)) { 201 return path.getTop(); 202 } 203 return null; 204 } 205 206 @Override 207 public int getChildCount() { 208 Object referent = lock(); 209 if (referent == null) { 210 return 0; 211 } 212 Access access = bindAccessForTreeObject(referent); 213 final int count = access.getCompositeParamCount(); 214 return count; 299 215 } 300 216 … … 305 221 return true; 306 222 } 307 return bindAccessFor (referent).getCompositeParamCount() == 0;308 } 309 310 protected Access Interface bindAccessFor(Object child) {311 return treeAtFrame.getTree().prepareAccess(param).select(child);223 return bindAccessForTreeObject(referent).getCompositeParamCount() == 0; 224 } 225 226 protected Access bindAccessForTreeObject(Object child) { 227 return bindAccessFromSideNote(getTree(), child); 312 228 } 313 229 314 230 @Override 315 231 public void render(TreeCellRenderer renderer) { 232 233 Object child = lock(); 234 if (child == null) { 235 renderer.setToolTipText("?"); 236 renderer.setText("?"); 237 renderer.setIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED)); 238 return; 239 } 240 Access access = bindAccessForTreeObject(child); 241 CompositeParam param = getTree().getSideNote(child, CompositeParam.class, CompositeParam.class); 316 242 String name = param.getId(); 317 243 318 Object child = lock(); 319 if (child != null) { 320 AccessInterface access = bindAccessFor(child); 321 322 StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name")); 323 324 if (nameParam != null) { 325 name = access.get(nameParam, String.class); 326 } 327 328 renderer.setToolTipText(new TooltipConstructor() 244 StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name")); 245 246 if (nameParam != null) { 247 name = access.get(nameParam, String.class); 248 } 249 250 renderer.setToolTipText(new TooltipConstructor() 329 251 .append("frams", access.getId()) 330 252 .append("java", child.getClass().getCanonicalName()) … … 333 255 .append("id", param.getId()) 334 256 .append("object", Integer.toHexString(System.identityHashCode(child))) 335 .append("number", number) 336 .append("textual path", textualPath) 257 .append("size", access.getCompositeParamCount()) 337 258 .build()); 338 } else { 339 renderer.setToolTipText(new TooltipConstructor() 340 .append("param", param) 341 .append("textual path", textualPath) 342 .build()); 343 } 259 260 renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param))); 344 261 renderer.setText(name); 345 renderer.setIcon(imageIcon); 346 262 } 263 264 // public static class Textual { 265 // } 266 267 public String getTextual() { 268 return textual; 269 // return getTree().getSideNote(lock(), Textual.class, String.class); 270 } 271 272 protected final Object listenersTag = new Object(); 273 274 public List<EventListener<?>> getListeners() { 275 @SuppressWarnings("unchecked") 276 List<EventListener<?>> result = getTree().getSideNote(lock(), listenersTag, List.class); 277 if (result == null) { 278 result = new LinkedList<>(); 279 getTree().putSideNote(lock(), listenersTag, result); 280 } 281 282 return result; 283 } 284 285 protected <A> void tryAddListener(final Path path, final EventParam eventParam, Class<A> argumentType, final EventListener<A> listener) { 286 getTree().addListener(path, eventParam, listener, argumentType, new FutureHandler<Void>(getFrame()) { 287 @Override 288 protected void result(Void result) { 289 assert getFrame().isActive(); 290 log.debug("registered gui listener for {} at {}", eventParam, path); 291 getListeners().add(listener); 292 } 293 }); 294 } 295 296 @Override 297 public TreePanel getPanel() { 298 if (panel != null) { 299 return panel; 300 } 301 panel = getTreeAtFrame().preparePanel(param); 302 return panel; 347 303 } 348 304
Note: See TracChangeset
for help on using the changeset viewer.