source: java/main/src/main/java/com/framsticks/gui/TreeNode.java @ 98

Last change on this file since 98 was 98, checked in by psniegowski, 11 years ago

HIGHLIGHTS:

CHANGELOG:
Get data also on tree expansion.

Use nice framstick icon for empty nodes.

Update panel after reload if it is current.

Add shallow reload procedure.

Cut Gui prefix from several tree classes.

Bring back counter of GuiTreeNode?.

Use IdentityHashMap? were it is more appriopriate.

Remove TreeListener?.

Do not use TreeListener? in GUI.

Minor change.

Done migration to GuiTreeModel?.

BrowserTest? in that version always crashes frams.linux.

Move rendering implementation into GuiAbstractNode?.

Use hand-crafted list in GuiTreeNode?.

Generally, it would be a great place for WeakIdentityHashMap?
(but there is none in Java Collection Framework).

Remove superfluous logging.

Fix bug in GuiTreeNode?.

Use IdentityHashMap? instead of HashMap?.

Improve structure update.

Filter out invalid uids in UniqueListAccess?.

Improve TreeCellRenderer?.

Add filtering in TrackConsole?.

Improve TreeModel?.

More changes.

More improvements.

More changes.

Remove TreeNode?.

Support MetaNode? in the GuiTreeModel?.

Implement more in GuiTreeModel?.

Add CompositeParam? interface to FramsClass? and AccessInterface?.

Allow access by number to UniqueList?.

Add UidComparator?.

Use TreeMap? as a default accessee in unique list.

It keeps order of keys.

Introduce classes to use with new TreeModel?.

Another step.

Migrate from TreeNode? to Node in many places.

Remove some uses of TreeNode? as DefaultMutableTreeNode?.

Remove Path from TreeNode? interface.

Remove Path from TreeNode?.

Add Path recration from node feature.

Reworking TreeCellRenderer?.

Minor change of TreeOperations? interface.

Remove last methods from TreeNode?.

Another minor step.

Do not store reference to TreeAtFrame? in TreeNode?.

Add proxy exceptionHandler to StatusBar?.

Move panels management to TreeAtFrame?.

Store localChanges in the NodeAtFrame?.

More cleanup.

Move name computing to TreeCellRenderer?.

Move tooltip and icon computations to TreeCellRenderer?.

More dispatches removed.

Remove most dispatching from TreeNode?.

TreeNode? does not actually redispatch tasks.

Make Tree embedded in Browser use SwingDispatcher?.

Make lazy binding of Tree with Dispatcher.

Minor changes.

Organizational change in AbstractTree?.

Make AbstractTree? compose from Thread instead of inherit from it.

Make SwingDispatcher? and AtOnceDispatcher? Joinable compatible.

Add ListPanelProvider?.

Improve Controls readonly and enabled handling.

Properly pass ExceptionHandlers? in more places.

Make Tree.get accept ValueParam?.

  • This is to allow access number of list elements.

Remove not needed get redirection in ClientAtServer?.

Rename tryResolve to tryGet.

Unify tryResolveAndGet into tryResolve.

Remove resolveTop from Tree interface.

Make Tree.get accept Future<Path>.

Use get to implement resolveTop also in ObjectTree?.

Unify resolveTop and get in RemoteTree?.

Another minor step.

More minor changes in tree operations.

Minor organizational changes.

In RemoteTree? first fetch info for root.

Reworking resolving.

Minor changes.

Make ListAccess? return proxy iterators (instead of creating temporary collection).

Let AccessInterface? return Iterable<Param>.

Improve resolving.

More improvements.

First working completion in ManagedConsole?.

Rename resolve to resolveTop.

This reflects the actuall functionality.

Change semantic of tryResolve and tryResolveAndGet.

File size: 5.6 KB
Line 
1package com.framsticks.gui;
2
3import java.lang.ref.WeakReference;
4import java.util.Iterator;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.concurrent.atomic.AtomicInteger;
8
9import javax.swing.tree.TreePath;
10
11import org.apache.log4j.Logger;
12
13import com.framsticks.core.Node;
14import com.framsticks.core.Tree;
15import com.framsticks.gui.view.TreeCellRenderer;
16import com.framsticks.params.AccessInterface;
17import com.framsticks.params.CompositeParam;
18import com.framsticks.params.types.StringParam;
19import com.framsticks.util.FramsticksException;
20import com.framsticks.util.lang.Casting;
21import com.framsticks.util.lang.Pair;
22import com.framsticks.util.swing.TooltipConstructor;
23
24public class TreeNode extends AbstractNode {
25        private static final Logger log = Logger.getLogger(TreeNode.class);
26
27
28        protected static final AtomicInteger counter = new AtomicInteger();
29
30        protected final WeakReference<Object> reference;
31        protected final CompositeParam param;
32        protected final Tree tree;
33        protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>();
34        protected final int number;
35
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        }
42
43        public TreeNode(Node node) {
44                this(node.getTree(), node.getParam(), node.assureResolved().getObject());
45        }
46
47        public Node tryCreateNode() {
48                Object child = lock();
49                if (child == null) {
50                        return null;
51                }
52                return new Node(tree, param, child);
53        }
54
55        @Override
56        public int getChildCount() {
57                Object referent = lock();
58                if (referent == null) {
59                        return 0;
60                }
61                AccessInterface access = tree.prepareAccess(param).select(referent);
62                final int count = access.getCompositeParamCount();
63                return count;
64        }
65
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;
74                        }
75                        TreeNode treeNode = p.second.get();
76                        if (treeNode == null) {
77                                i.remove();
78                                continue;
79                        }
80                        if (object == child) {
81                                return treeNode;
82                        }
83                }
84                return null;
85
86                // WeakReference<GuiTreeNode> resultReference = children.get(child);
87                // if (resultReference == null) {
88                //      return null;
89                // }
90                // return resultReference.get();
91        }
92
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");
98                }
99                AccessInterface access = tree.prepareAccess(param).select(referent);
100
101                final int count = access.getCompositeParamCount();
102                if (number >= count) {
103                        throw new FramsticksException().msg("invalid state - no child");
104                }
105
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);
111                }
112
113                TreeNode result = getTreeNodeForChild(child);
114                if (result != null) {
115                        return result;
116                }
117                result = new TreeNode(tree, childParam, child);
118
119                children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result)));
120
121                return result;
122
123        }
124
125        public Object lock() {
126                return reference.get();
127        }
128
129        @Override
130        public int getIndexOfChild(AbstractNode child) {
131                final TreeNode treeChild = Casting.tryCast(TreeNode.class, child);
132                if (treeChild == null) {
133                        return -1;
134                }
135                final Object childObject = treeChild.lock();
136                final Object parentObject = lock();
137                if (childObject == null || parentObject == null) {
138                        return -1;
139                }
140                final AccessInterface access = tree.prepareAccess(param).select(parentObject);
141
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;
147                        }
148                }
149                log.debug(child + " not found in " + this);
150                return -1;
151        }
152
153        /**
154         * @return the param
155         */
156        public CompositeParam getParam() {
157                return param;
158        }
159
160        /**
161         * @return the tree
162         */
163        public Tree getTree() {
164                return tree;
165        }
166
167
168        @Override
169        public String toString() {
170                return param.toString();
171        }
172
173        public static Node tryGetNode(TreePath treePath) {
174                return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode();
175        }
176
177        @Override
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;
185        }
186
187
188        @Override
189        public void render(TreeCellRenderer renderer) {
190                String name = param.getId();
191
192                Object child = lock();
193                if (child != null) {
194                        AccessInterface access = tree.prepareAccess(param).select(child);
195
196                        StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
197
198                        if (nameParam != null) {
199                                name = access.get(nameParam, String.class);
200                        }
201
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("?");
213                }
214                renderer.setText(name);
215                renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param)));
216
217        }
218
219}
Note: See TracBrowser for help on using the repository browser.