- Undocumented Matlab - https://undocumentedmatlab.com -

Customizing uitree

Posted By Yair Altman On August 18, 2010 | 44 Comments

Last week, I introduced the semi-documented uitree function [1] that enables displaying data in a hierarchical (tree) control in Matlab GUI.
Today, I will continue by describing how uitrees can be customized.
Note that although uitrees use Java objects internally, we can create and customize uitree using pure-Matlab code.

Creating non-standard tree types

To start the discussion, let’s create a simple uitree whose Root node is not one of the automatically-processed types (disk folder, GUI handle, or Simulink model). There are two ways of creating such a tree: active and reactive:

Actively building the tree

In this method, we actively create nodes and attach them to parent nodes when the tree is first built. For example:

% Fruits
fruits = uitreenode('v0', 'Fruits', 'Fruits', [], false);
fruits.add(uitreenode('v0', 'Apple',  'Apple',  [], true));
fruits.add(uitreenode('v0', 'Pear',   'Pear',   [], true));
fruits.add(uitreenode('v0', 'Banana', 'Banana', [], true));
fruits.add(uitreenode('v0', 'Orange', 'Orange', [], true));
% Vegetables
veggies = uitreenode('v0', 'Veggies', 'Vegetables', [], false);
veggies.add(uitreenode('v0', 'Potato', 'Potato', [], true));
veggies.add(uitreenode('v0', 'Tomato', 'Tomato', [], true));
veggies.add(uitreenode('v0', 'Carrot', 'Carrot', [], true));
% Root node
root = uitreenode('v0', 'Food', 'Food', [], false);
root.add(veggies);
root.add(fruits);
% Tree
figure('pos',[300,300,150,150]);
mtree = uitree('v0', 'Root', root);

The tree automatically display scrollbars if any of the presented tree-nodes requires more than the available tree space:

User-created tree    User-created tree
User-created tree

Reactively building the tree

In this method, also called “lazy loading”, we only create child nodes as a reaction to their parent node’s expansion. This is the method given in uitree‘s semi-documented help section. The tree will initially display only the root node, and additional tree-nodes will be created as needed when the root or any of its child nodes is expanded.
For example (note how the data model is passed as an extra parameter to the ExpandFcn callback):

% Create the data
food.veggies = {'Potato','Tomato','Carrot'};
food.fruits = {'Apple','Pear','Banana','Orange'};
% Create the tree with an ExpandFcn  callback
root = uitreenode('v0', 'Food', 'Food', [], false);
figure('pos',[300,300,150,150]);
mtree = uitree('v0', 'Root',root, 'ExpandFcn',{@myExpandFcn,food});
% The following function should be added to Matlab's path:
function nodes = myExpandfcn(tree, value, model)
  try
    nodeIdx = 0;
    if strcmp(value,'Food')
      nodeNames = fieldnames(model);
      isLeaf = false;
    else
      nodeNames = model.(value);
      isLeaf = false;
    end
    for nodeIdx = 1 : length(nodeNames)
      nodeName = nodeNames{nodeIdx};
      nodes(nodeIdx) = uitreenode(nodeName,nodeName,[],isLeaf);
    end
  catch
    % never mind...
  end
  if isempty(nodeIdx) || nodeIdx == 0
      nodes = [];
  end
end

Resizing the tree

uitrees are created with a default position of (0,0), a width of 200 (or less if the figure is narrower) and a height spanning the entire figure’s content area. This can easily be modified following the tree’s creation using its Position property:

mtree = uitree(...);
mtree.Position = [100,100,50,150];  % modify position & size
mtree.Position(4) = 100;  % limit tree height to 100 pixels

Java-based customizations

Today’s article used pure Matlab code (or more precisely, Java code wrapped in pure Matlab). Many additional customizations are available at the JTree-level. The underlying jtree handle can easily be retrieved:

jtree = mtree.getTree;
jtree = get(mtree, 'tree');  % an alternative

As an example customization that uses jtree, consider one of my earliest articles on this website: Adding a context-menu to a uitree [2].
Interested readers might also benefit from looking at the tree manipulations that I have programmed in my FindJObj [3] utility.
Next week’s article will conclude my uitree mini-series by describing how specific tree nodes can be customized. If you have any special customization request, please post a comment below [4].

Categories: GUI, Java, Medium risk of breaking in future versions, Semi-documented function


44 Comments (Open | Close)

44 Comments To "Customizing uitree"

#1 Comment By Scott Koch On August 19, 2010 @ 10:23

Hi Yair –

Thanks for your uitree series. As far as customization goes I’d be interested in creating components for nodes (button, combo box, and maybe even a editable text field).

Scott

#2 Comment By Jason On August 19, 2010 @ 11:58

Hi Yair,

Since your very first posts I began to experiment with uitree, I think you convinced me that MATLAB isn’t as locked-down as I thought…

Anyway, regarding uitree customizations, it would be interesting to see how to manage the drag behavior outside the uitree panel. Let’s say we don’t care about drop position, but we want to drag a file tree selection (for example) to another panel. The effect might be to import data files into a plot or something like that.

Regards,
Jason

#3 Comment By Yair Altman On August 19, 2010 @ 12:12

@Scott – I have an entire article planned to answer your question, showing how this can be done in several different ways. Hold on…

@Jason – DnD is a complex issue that requires a mini-series of its own. It’s in my [11] list, but not planned for the near future…

#4 Comment By Prasath On August 19, 2010 @ 20:30

Yair,

Is there a way in MATLAB to differentiate tree nodes in unique colors ?. I mean first node in red, second in blue, third in green and so on.

Thanks,
Prasath
=========

#5 Comment By Yair Altman On August 19, 2010 @ 23:12

@Prasath – use [12] for your node labels. More on this in next week’s post.

#6 Pingback By Customizing uitree nodes – part 2 | Undocumented Matlab On September 1, 2010 @ 11:02

[…] I conclude this mini-series by answering a reader’s request to show how checkboxes, radio buttons and other similar controls can be attached to tree […]

#7 Comment By Chris On October 15, 2010 @ 04:38

Hello Yair,

thank you very much for your numerous explanations around the uitree functionality in Matlab. Without this I had never managed to make a GUI with working tree menu.

But I have still one open question: Is it possible to get and set the expansion structure of the tree menu? If a add menu items on the fly by user input and reload the tree menu, all nodes are collapsed. I am searching for a way to expand – after a reload – exactly the items which were expanded before.

Do you know a method to realize this?

Thank you in advance.

Regards
Chris

#8 Comment By Yair Altman On October 15, 2010 @ 05:57

@Chris – collapsing/expansion are tree capabilities, not node capabilities. After all, hierarchy nodes can be presented in several different formats (other than a tree) that do not necessarily involve collapsing/expansion.

The tree object (jtree = mtree.getTree) has the isCollapsed(nodeNumber) / isExpanded(nodeNumber)methods that you can use to query the state, and corresponding collapseRow(nodeNumber) / expandRow(nodeNumber) methods for setting the state. There are also similar methods for querying/setting the state of a given hierarchy path.

Read [13] for more details.

-Yair

#9 Comment By rahill On October 24, 2011 @ 00:11

Hi Yair
I ready need to know about drag and drop in matlab uitree,I have a treeview with 2 chil node in level 1.one of them will show data file names,and the second have some nodes that will define plot types, I want to drag the data name and drop it to plot types,I really need to know more about it.
Could you help me please?
thanks for your attention.
rahill

#10 Comment By Yair Altman On October 24, 2011 @ 01:01

@Rahill – yes this is possible, but it is not easy. It is certainly not something that I can explain in a blog comment. I plan to write about DND in a series of articles sometime in early 2012. In the meantime, if you would like my consulting assistance, please contact me by email (use the link at the top right of any page on the website).

#11 Comment By Jason D. On November 8, 2011 @ 12:24

I’m using a tree control and a list box in conjunction with each other. Between the two are left/right arrow buttons, so items from the tree may be move to the list and vice versa. I’ve been trying to find some easy mechanism to track items to hide/show or add/remove, such as keeping track of which items in the tree control have been selected for the list box and then forcing node expansion to refresh the children shown. The expand callback doesn’t seem to be triggering beyond the first expansion done.

What I’m currently doing is removing all nodes with a particular parent (category, basically) and then reloading the children from the data model. I tried doing a sort of insert to just put the item back roughly where it was removed, but I can’t seem to find the proper syntax to insert a node at a particular position in the list of children.

So, is there a way to force the expand callback function to refresh the child nodes? Is there an efficient way to insert a child at a particular position?

Thanks.

#12 Comment By ninad On September 20, 2012 @ 04:04

Hi,Great work.
How to use the swingx treetable in matlab.

#13 Comment By Yair Altman On September 22, 2012 @ 10:09

@Ninad – this is outside the scope of a simple blog comment. In general, you need to get your relevant Java classes (table model, cell renderers/editors) into the Java classpath, then instantiate the JXTreeTable object in Matlab and call its various methods to configure it, and finally display it onscreen using the javacomponent function. There are several online resources with examples showing how to create the Java classes ( [14]).

As an alternative to JXTreeTable, consider using JIDE’s TreeTable, which is already included in Matlab.

If you need personal assistance with setting any of these, please [15] for a consulting proposal.

#14 Comment By Graham Searle On November 2, 2012 @ 05:26

I’m trying to integrate a uitree into a GUI with a black background. I can set the tree’s background color as required, but it doesn’t quite achieve what I hoped – the names of each node retain a white border.
Here’s an example code snippet:

myFig = figure;
rootNodeDesc = 'myTree';
root = uitreenode('v0','somethingOrOther',rootNodeDesc,[],false);
nodeDesc = 'myNode';
node = uitreenode('v0','val',nodeDesc,[],true);
root.add(node)
mtree = uitree('v0','Root',root,'parent',myFig);
jtree = mtree.getTree;
jtree.setBackground(java.awt.Color(0,0,0));

Anyone have any suggestions please?
See the screenshot in the following link if you want to see what I see (using R2008b and R2012a) – click for hi-res image:

[16]

Thanks!

#15 Comment By Yair Altman On November 2, 2012 @ 05:39

@Graham – try setting a custom CellRenderer. It’s not very difficult once you get the concept. It’s the same idea as in uitables: [17], [18].

#16 Comment By Graham Searle On November 2, 2012 @ 05:37

Hurrumph – the code above is not properly displayed; I am using html inside the nodess description strings to set the bgcolor to black, and the font color to be white. But this is being stripped out by this webpage.

#17 Comment By Yair Altman On November 2, 2012 @ 05:41

place a space between the < and the "html" parts…

#18 Comment By Graham Searle On November 2, 2012 @ 06:56

Thanks on both counts! I’ll have a go at using a custom CellRenderer as you suggest.

#19 Comment By yh On November 26, 2012 @ 09:06

I tried this example, but I can only see the root(Food). what is the problem?
Thanks

#20 Comment By Yair Altman On November 26, 2012 @ 09:09

@yh – did you try to expand (double-click) the root node?

#21 Comment By yh On November 26, 2012 @ 09:42

thanks

#22 Comment By Simon On February 15, 2013 @ 04:20

Hi Yair,

As far as I understand, each uitree comes with its own panel. Is it possible two uitree’s to share a common panel? Fir example, add ‘Drinks’ to the same level as ‘Food’?

Thanks

#23 Comment By Yair Altman On February 15, 2013 @ 04:38

@Simon – you can make both Food and Drinks children of the same uitree root. You can then decide whether or not to display the root:

jtree.setRootVisible(false);

There is also a corresponding ShowsRootHandles property. This is all explained in p. 179 of my book.

#24 Comment By Pezz On April 3, 2014 @ 00:51

Hello, how to i add another level of nodes, so for example add below Apple, ‘Granny Smith’,’Sweet’,’Cooking’ etc?

#25 Comment By Yair Altman On April 3, 2014 @ 15:25

@Pezz – simply keep the Apple uitreenode’s handle in some variable, and then use the add() method, just like I did to add Apple to the Fruits node.

#26 Comment By Pezz On April 4, 2014 @ 03:16

Yep okay perfect. Thanks for your speedy reply. I wasn’t keeping the handle.

Quick question: , [], false), what do these statements mean at the end of the .add method?

#27 Comment By Yair Altman On April 4, 2014 @ 06:57

the input args to uitreenode are:
* the string ‘v0’ (optional)
* the node value
* the node label
* the full path to the node’s icon – see [19]
* boolean flag whether the node is a leaf or has children nodes

#28 Comment By Pezz On April 4, 2014 @ 14:35

Okay perfect thank you.

#29 Comment By Ben Lawrence On May 8, 2014 @ 17:04

Is there a way of displaying the ‘value’ of leaf (a vector, a scalar, a string, etc) to the right of the ‘name’ of the leaf in the uitree gui?

#30 Comment By Yair Altman On May 8, 2014 @ 17:14

@Ben – simply update the lean name (label) to include all the information that you need. You can use [20] if you wish.

#31 Comment By Ben On May 9, 2014 @ 09:22

Thanks – Do you mean just put all the info as a string into the ‘name’ field? If I used HTML formatting will that allow me to format the ‘name’ and the ‘value’ data differently? are there any examples out there?

#32 Comment By Yair Altman On May 10, 2014 @ 10:46

@Ben – yes. You will need to learn HTML, it’s not too difficult. Example: ‘<html><b>Name</b>: <i>Value’

#33 Comment By kpmandani On September 8, 2014 @ 09:43

In the above figure example,can we get a check box against potato,tomato, carrot for vegetables and apples,pear, banana… in fruits? If so can anyone suggest me what code should I add to the above existing code to get it?

#34 Comment By Yair Altman On September 8, 2014 @ 09:49

[21]

#35 Comment By kpmandani On September 8, 2014 @ 09:53

I mean if I go as per your example document [21] , I want checkbox only for the ‘child node’ and options below it and not the node where its written ‘file A’ and ‘file B’. Is it possible. If so, please suggest me the code for it

#36 Comment By Yair Altman On September 8, 2014 @ 09:56

I don’t think there is a simple answer. If you wish me to investigate this (for a consulting fee) then send me an email.

#37 Comment By kpmandani On September 8, 2014 @ 10:07

What I am trying is similar to what we see in computers. Eg when we go inside a folder and select a file, the line below the menu bar shows the file/folder location. Can I do it the same for the above and display its output in the command window?

#38 Comment By Sebastian On December 14, 2016 @ 15:17

Hi Yair,

I am using the uitree inside a MATLAB GUI. Basically I want to browse in .mat-files (simulation results). Until now I am able generate a uitree, but I am not able to delete it and load another .mat-file. Can you help me how it is possible to use uitrees for different .mat-files?

Thank you very much,
Sebastian

My code example for the generation of a uitree:

import javax.swing.*;
warning('off', 'MATLAB:hg:JavaSetHGProperty');

[filename,pathname]=uigetfile('*.mat', 'File zum Laden auswählen');
a=[pathname,filename];
data = load(a);
name = fieldnames(data);

handles.data = cell(2,1);
handles.data{1} = data;

handles.root = uitreenode('v0', filename, filename, [], false);
handles.tree = uitree('v0', hObject,'Root', handles.root,'ExpandFcn', @(obj, ev)myExpfcn4(obj, ev, hObject, handles));
set(handles.tree, 'Units', 'normalized', 'position', [0 0 0.25 1]);
set(handles.tree, 'NodeWillExpandCallback', @(obj, ev) nodeWillExpand_cb4(obj, ev, hObject, handles));
set(handles.tree, 'NodeSelectedCallback', @(obj, ev)nodeSelected_cb4(obj, ev, hObject, handles));

handles.t = handles.tree.Tree;
set(handles.t, 'MousePressedCallback', @mouse_cb);

warning('on', 'MATLAB:hg:JavaSetHGProperty');

#39 Comment By Yair Altman On December 14, 2016 @ 22:33

@Sebastian – did you try to simple create a new uitreenode for the new file and then set the tree’s Root property to this new node?

#40 Comment By Sebastian On December 15, 2016 @ 09:29

@Yair: Thank you very much for your answer!
In my MATLAB-GUI I have a pushbutton for opening a new file. In the Callback of this pushbutton I am using the following code:

% --- Executes on button press in open_pb.
function open_pb_Callback(hObject, eventdata, handles)
% hObject    handle to open_pb (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename,pathname]=uigetfile('*.mat', 'File zum Laden auswählen');
a=[pathname,filename];
data = load(a);
name = fieldnames(data);

handles.data = cell(2,1);
handles.data{1} = data;

handles.root = uitreenode('v0', filename, filename, [], false);
handles.tree = uitree('v0', hObject,'Root', handles.root,'ExpandFcn', @(obj, ev)myExpfcn4(obj, ev, hObject, handles));

% Update handles structure
guidata(hObject, handles);

When I execute this pushbutton, I get the following error message:

Error using uitree_deprecated
Unrecognized parameter.

Error in uitree (line 102)
	[tree, container] = uitree_deprecated(varargin{2:end});

Error in tree_inspector>open_pb_Callback (line 385)
handles.tree = uitree('v0', hObject,'Root', handles.abc,'ExpandFcn', @(obj,ev)myExpfcn4(obj, ev, hObject, handles));

Error in gui_mainfcn (line 95)
        feval(varargin{:});

Error in tree_inspector (line 42)
    gui_mainfcn(gui_State, varargin{:});

Error in
matlab.graphics.internal.figfile.FigFile/read>@(hObject,eventdata)tree_inspector('open_pb_Callback',hObject,eventdata,guidata(hObject)) 
Error while evaluating UIControl Callback

Have you got an idea what is my principal problem?

Thank you very much for your response.

Best regards,
Sebastian

#41 Comment By Paul On December 19, 2016 @ 14:04

Hi everybody,

I am using uitree in a MATLAB-GUI, too. Can you give me an explanation, how it is possible to modify the content of “handles” in the ExpandFcn of uitree. I always have the problem, that the changings are visible when I am in the function call – afterwards they are deleted. Is there a possibility to make changes outside the original GUIDE-Callbacks?

Thank you & best regards
Paul

#42 Comment By ss On June 1, 2017 @ 08:55

Thanks Yair Altman

how to rename or change icon to a uitreenode , I try set(jtree.setEditable(true)), but the name can not be modified

ss

#43 Comment By ss On June 1, 2017 @ 08:57

Thanks Yair Altman

how to rename or change icon to a uitreenode , I try jtree.setEditable(true), but the name can not be modified

ss

#44 Comment By geetha On July 29, 2020 @ 12:22

Hi am uitree and some line am getting this error

error in
@(tree,evd)evalin('base',sprintf(['ldp_temp_blockhandle=%.20f;','set(ldp_temp_blockhandle,''UserData'',setfield(get(ldp_temp_blockhandle,''UserData''),''action'',0));','ldp_temp_blockhandle
= getfield(get(ldp_temp_blockhandle,''UserData''),''system'');','eval(get_param(ldp_temp_blockhandle,''OpenFcn''));'],get(tree.Root,'UserData')))

Error in hgfeval (line 63)
        feval(fcn{1},varargin{:},fcn{2:end});

Error in uitree_deprecated>nodeSelected (line 140)
hgfeval(cbk, tree, evd);

please help in anybody


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/customizing-uitree

URLs in this post:

[1] uitree function: http://undocumentedmatlab.com/blog/uitree/

[2] Adding a context-menu to a uitree: http://undocumentedmatlab.com/blog/adding-context-menu-to-uitree/

[3] FindJObj: http://undocumentedmatlab.com/blog/findjobj-gui-display-container-hierarchy/

[4] below: http://undocumentedmatlab.com/blog/customizing-uitree/#respond

[5] Customizing uitree nodes – part 2 : https://undocumentedmatlab.com/articles/customizing-uitree-nodes-2

[6] Customizing uitree nodes – part 1 : https://undocumentedmatlab.com/articles/customizing-uitree-nodes

[7] uitree : https://undocumentedmatlab.com/articles/uitree

[8] An interesting uitree utility : https://undocumentedmatlab.com/articles/interesting-uitree-utility

[9] Adding a context-menu to a uitree : https://undocumentedmatlab.com/articles/adding-context-menu-to-uitree

[10] Customizing combobox popups : https://undocumentedmatlab.com/articles/customizing-combobox-popups

[11] : https://undocumentedmatlab.com/todo/

[12] : https://undocumentedmatlab.com/blog/html-support-in-matlab-uicomponents/

[13] : http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html

[14] : http://sandarenu.blogspot.com/2008/02/treetable-in-java-using-swingx.html

[15] : mailto:altmany @gmail.com?subject=Undocumented Matlab - Java TreeTable&body=Hi Yair, &cc=;&bcc=

[16] : https://picasaweb.google.com/lh/photo/ll2IA2e_xf4I4y11AOuih9MTjNZETYmyPJy0liipFm0?feat=directlink

[17] : https://undocumentedmatlab.com/blog/uitable-cell-colors/#colors

[18] : https://undocumentedmatlab.com/blog/advanced-jide-property-grids/#comment-117495

[19] : https://undocumentedmatlab.com/blog/customizing-uitree-nodes/#icons

[20] : https://undocumentedmatlab.com/blog/html-support-in-matlab-uicomponents

[21] : https://undocumentedmatlab.com/blog/customizing-uitree-nodes-2

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.