Dynamic uitree from database

32 views (last 30 days)
Miguel
Miguel on 10 Dec 2012
Hello,
I am using uitree to map the records on a database but I am having trouble because it is not dynamic.
I initially define the root node (for instance Cars), then add some child nodes nodes to it (for instance Makes), and then I use:
[myTree myContainer] = uitree('v0', 'Root', myRoot,'ExpandFcn',{@myExpandFcn});
In myExpandFcn I define the SQL query based on the expanded node info (let's say the make was Ferrari), and then add as many childnodes (for instance MakeOwners) to the expanded node (Make) as the records I retrieve from the database. So far so good, everything seemed to be working.
But the problem is that myExpandFcn is apparently only called on the first time a node is expanded. If the database changes (more people buy Ferraris) I can not map those changes on the tree. Theoretically speaking this seems like a simple problem to solve if myExpandFcn was called every time a node was expanded.
So far I did not find anybody with a similar problem, so I am a bit lost how this could be achieved. Maybe it is just a tree property that can be set? Or maybe there is another way around it?
Any hints on this are very welcome :-)
Miguel

Answers (2)

Jan
Jan on 10 Dec 2012
Edited: Jan on 10 Dec 2012
UITREE is still weak after all these years. See Answers: Wanted features for UITREE.
I had more success with the NodeWillExpand callback, because the NodeExpanded is called the first timne only as you observe:
DlgH = figure;
% This code is taken from Matlab's UITREE function partially:
M_treeH = com.mathworks.hg.peer.UITreePeer;
M_treeH.setRoot([]); % Remove default JTree->colors/sports/food
TreeH = javacomponent(M_treeH, Position, DlgH); % Set Position as needed
set(TreeH, ...
'Visible', Visible, ... % 0 or 1
'MultipleSelectionEnabled', 0, ...
'NodeWillExpandCallback', {@nodeWillExpandFcn, DlgH}, ...
'NodeExpandedCallback', {@nodeExpandedFcn, DlgH}, ...
'NodeSelectedCallback', {@nodeSelectedFcn, DlgH});
...
function nodeWillExpand_L(TreeH, EventData, DlgH)
EventNodeH = EventData.getCurrentNode;
if TreeH.isLoaded(EventNodeH)
NodeUD = get(EventNodeH, 'UserData');
...
This is not a running example, but it should demonstrate how to set the callbacks manually.
Good luck. I you find that this is inconvenient or want a (well) documented method, please send an enhancement request to TMW. The more user ask for improvements, the more likely is an update. Currently the (documented) GUI objects have less power than my AtariST from 1985.

M
M on 13 Dec 2012
Edited: M on 13 Dec 2012
Thanks for the tips Jan! :-)
Below there is a working example, just in case someone has a similar problem. Just copy-paste it to an m-file and it should work.
I could not get around another problem. How can I programmatically set the scroll position of the tree? Say I have 100 nodes (car makes) and I want to scroll down to the 80th. Selecting the node is easy, but to scroll I could only find this method:
TreeH.ScrollPane.scrollRectToVisible
but because I am not a Java programmer I am having a hard time making it work. Is this the right way to do it? Or is there better way? Any more tips are welcome!
Miguel
--------------------
function MyDynamicTree % This is a running example based on the cool tips given by Jan Simon :-)
clc
DlgH = figure();
TreePosition = [5 5 300 300];
% <1x1 com.mathworks.hg.peer.UITreePeer>
M_treeH = com.mathworks.hg.peer.UITreePeer;
M_treeH.setRoot([]); %[JS] Remove default JTree->colors/sports/food
%<1x1 javahandle_withcallbacks.com.mathworks.hg.peer.UITreePeer>
TreeH = javacomponent(M_treeH, TreePosition, DlgH);
set(TreeH, ...
'Visible', 1, ... %[JS] 0 or 1
'MultipleSelectionEnabled', 0, ...
'NodeWillExpandCallback', {@nodeWillExpandFcn, DlgH}, ...
'NodeExpandedCallback', {@nodeExpandedFcn, DlgH}, ...
'NodeSelectedCallback', {@nodeSelectedFcn, DlgH});
%set some nodes and add them to the root node
myRoot = uitreenode('v0', 0, 'Cars', [], false);
Node10 = uitreenode('v0', 10, 'Audi', [], true);
Node20 = uitreenode('v0', 20, 'Ferrari', [], false);
Node30 = uitreenode('v0', 30, 'Mercedes', [], true);
myRoot.add(Node10);
myRoot.add(Node20);
myRoot.add(Node30);
%set the tree and expand myRoot node
TreeH.setRoot(myRoot);
TreeH.expand(myRoot);
end
function nodeWillExpandFcn(TreeH, EventData, DlgH)
EventNodeH = EventData.getCurrentNode;
if TreeH.isLoaded(EventNodeH)
NodeUD = get(EventNodeH, 'UserData');
end
% Simulates a dynamic number (between 1 and 5) of ferrari owners.
% Each owner has a random name of 10 letters.
% Data from owners could be retreived from database in this callback.
% For small number of childnodes a simple way of updating info is to
% remove all children and add them all again. Maybe not efficient but
% it works.
if EventData.getCurrentNode.getValue == 20
EventNodeH.removeAllChildren;
nNodes = 1 + round(4*rand);
for i=1:nNodes
Value = 20 + i;
Name = char(round(97 + 25*rand(1,10))); %random name
NodeTmp = uitreenode('v0', Value, Name, [], true);
EventNodeH.add(NodeTmp);
end
end
TreeH.reloadNode(EventNodeH); %was the way I found to draw changes
end
function nodeSelectedFcn(TreeH, EventData, DlgH)
end
function nodeExpandedFcn(TreeH, EventData, DlgH)
end

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!