In my previous posts I have shown how Matlab’s semi-documented uitree and uitreenode functions can be used to display hierarchical (tree) control in Matlab GUI. Today 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 nodes.
There are actually several ways this can be done:
Matlab icon control
The simplest is to create two icons (checked/unchecked) and switch the node’s icon whenever it is selected (use mtree’s NodeSelectedCallback or jtree’s MouseClickedCallback callbacks) – a sample implementation was posted by Gwendolyn Fischer a couple of years ago, based on even earlier posts by John Anderson, Brad Phelan and me. Here it is, with minor fixes:
function uitree_demo % function based on treeExperiment6 by John Anderson % see http://www.mathworks.com/matlabcentral/newsreader/view_thread/104957#269485 % % The mousePressedCallback part is inspired by Yair Altman % % derived from Brad Phelan's tree demo % create a tree model based on UITreeNodes and insert into uitree. % add and remove nodes from the treeModel and update the display import javax.swing.* import javax.swing.tree.*; % figure window f = figure('Units', 'normalized'); b1 = uicontrol( 'string','add Node', ... 'units' , 'normalized', ... 'position', [0 0.5 0.5 0.5], ... 'callback', @b1_cb); b2 = uicontrol( 'string','remove Node', ... 'units' , 'normalized', ... 'position', [0.5 0.5 0.5 0.5], ... 'callback', @b2_cb); %[I,map] = imread([matlab_work_path, '/checkedIcon.gif']); [I,map] = checkedIcon; javaImage_checked = im2java(I,map); %[I,map] = imread([matlab_work_path, '/uncheckedIcon.gif']); [I,map] = uncheckedIcon; javaImage_unchecked = im2java(I,map); % javaImage_checked/unchecked are assumed to have the same width iconWidth = javaImage_unchecked.getWidth; % create top node rootNode = uitreenode('v0','root', 'File List', [], 0); % [matlab_work_path, '/fileListIcon.gif'],0); % create two children with checkboxes cNode = uitreenode('v0','unselected', 'File A', [], 0); % as icon is embedded here we set the icon via java, otherwise one could % use the uitreenode syntax uitreenode(value, string, icon, isLeaf) with % icon being a qualified pathname to an image to be used. cNode.setIcon(javaImage_unchecked); rootNode.add(cNode); cNode = uitreenode('v0','unselected', 'File B', [], 0); cNode.setIcon(javaImage_unchecked); rootNode.add(cNode); % set treeModel treeModel = DefaultTreeModel( rootNode ); % create the tree tree = uitree('v0'); tree.setModel( treeModel ); % we often rely on the underlying java tree jtree = handle(tree.getTree,'CallbackProperties'); % some layout drawnow; set(tree, 'Units', 'normalized', 'position', [0 0 1 0.5]); set(tree, 'NodeSelectedCallback', @selected_cb ); % make root the initially selected node tree.setSelectedNode( rootNode ); % MousePressedCallback is not supported by the uitree, but by jtree set(jtree, 'MousePressedCallback', @mousePressedCallback); % Set the mouse-press callback function mousePressedCallback(hTree, eventData) %,additionalVar) % if eventData.isMetaDown % right-click is like a Meta-button % if eventData.getClickCount==2 % how to detect double clicks % Get the clicked node clickX = eventData.getX; clickY = eventData.getY; treePath = jtree.getPathForLocation(clickX, clickY); % check if a node was clicked if ~isempty(treePath) % check if the checkbox was clicked if clickX <= (jtree.getPathBounds(treePath).x+iconWidth) node = treePath.getLastPathComponent; nodeValue = node.getValue; % as the value field is the selected/unselected flag, % we can also use it to only act on nodes with these values switch nodeValue case 'selected' node.setValue('unselected'); node.setIcon(javaImage_unchecked); jtree.treeDidChange(); case 'unselected' node.setValue('selected'); node.setIcon(javaImage_checked); jtree.treeDidChange(); end end end end % function mousePressedCallback function selected_cb( tree, ev ) nodes = tree.getSelectedNodes; node = nodes(1); path = node2path(node); end function path = node2path(node) path = node.getPath; for i=1:length(path); p{i} = char(path(i).getName); end if length(p) > 1 path = fullfile(p{:}); else path = p{1}; end end % add node function b1_cb( h, env ) nodes = tree.getSelectedNodes; node = nodes(1); parent = node; childNode = uitreenode('v0','dummy', 'Child Node', [], 0); treeModel.insertNodeInto(childNode,parent,parent.getChildCount()); % expand to show added child tree.setSelectedNode( childNode ); % insure additional nodes are added to parent tree.setSelectedNode( parent ); end % remove node function b2_cb( h, env ) nodes = tree.getSelectedNodes; node = nodes(1); if ~node.isRoot nP = node.getPreviousSibling; nN = node.getNextSibling; if ~isempty( nN ) tree.setSelectedNode( nN ); elseif ~isempty( nP ) tree.setSelectedNode( nP ); else tree.setSelectedNode( node.getParent ); end treeModel.removeNodeFromParent( node ); end end end % of main function treeExperiment6 function [I,map] = checkedIcon() I = uint8(... [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0; 2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1; 2,2,2,2,2,2,2,2,2,2,2,2,0,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,0,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,0,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,0,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,0,0,1,1,2,2,3,1; 2,2,1,0,0,1,1,0,0,1,1,1,2,2,3,1; 2,2,1,1,0,0,0,0,1,1,1,1,2,2,3,1; 2,2,1,1,0,0,0,0,1,1,1,1,2,2,3,1; 2,2,1,1,1,0,0,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,0,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1; 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1]); map = [0.023529,0.4902,0; 1,1,1; 0,0,0; 0.50196,0.50196,0.50196; 0.50196,0.50196,0.50196; 0,0,0; 0,0,0; 0,0,0]; end function [I,map] = uncheckedIcon() I = uint8(... [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1; 2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1; 1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1]); map = ... [0.023529,0.4902,0; 1,1,1; 0,0,0; 0.50196,0.50196,0.50196; 0.50196,0.50196,0.50196; 0,0,0; 0,0,0; 0,0,0]; end

uitree with custom checkbox icons
Custom Java classes
An alternative is to create a custom tree Java class and/or a custom TreeCellRenderer/TreeCellEditor. Specifically, to change the icons of each node you have to implement your own java component which derives from DefaultMutableTreeNode.
Some online resources to get you started:
- Sun’s official JTree customization tutorial
- Santhosh Kumar’s custom tree icons, tree-node checkboxes, and selective tree-node checkboxes
- Java2s’s multiple JTree customization snippets
Built-in classes
Another option is to use Matlab’s built-in classes, either com.mathworks.mwswing.checkboxtree.CheckBoxTree or com.jidesoft.swing.CheckBoxTree:
import com.mathworks.mwswing.checkboxtree.* jRoot = DefaultCheckBoxNode('Root'); l1a = DefaultCheckBoxNode('Letters'); jRoot.add(l1a); l1b = DefaultCheckBoxNode('Numbers'); jRoot.add(l1b); l2a = DefaultCheckBoxNode('A'); l1a.add(l2a); l2b = DefaultCheckBoxNode('b'); l1a.add(l2b); l2c = DefaultCheckBoxNode('<html><b>α'); l1a.add(l2c); l2d = DefaultCheckBoxNode('<html><i>β'); l1a.add(l2d); l2e = DefaultCheckBoxNode('3.1415'); l1b.add(l2e); % Present the standard MJTree: jTree = com.mathworks.mwswing.MJTree(jRoot); jScrollPane = com.mathworks.mwswing.MJScrollPane(jTree); [jComp,hc] = javacomponent(jScrollPane,[10,10,120,110],gcf); % Now present the CheckBoxTree: jCheckBoxTree = CheckBoxTree(jTree.getModel); jScrollPane = com.mathworks.mwswing.MJScrollPane(jCheckBoxTree); [jComp,hc] = javacomponent(jScrollPane,[150,10,120,110],gcf);

a regular MJTree (left) and a CheckBoxTree (right)
Note: Matlab’s CheckBoxTree does not have a separate data model. Instead, it relies on the base MJTree’s model, which is a DefaultTreeModel by default. JIDE’s CheckBoxTree does have its own model.
This concludes my uitree mini-series. If you have any special customizations, please post a comment below.
Related posts:
- Customizing uitree nodes – part 1 This article describes how to customize specific nodes of Matlab GUI tree controls created using the undocumented uitree function...
- Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
- uitree This article describes the undocumented Matlab uitree function, which displays data in a GUI tree component...
- An interesting uitree utility ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...
- Adding a context-menu to a uitree uitree is an undocumented Matlab function, which does not easily enable setting a context-menu. Here's how to do it....
- Customizing uicontrol border Matlab uicontrol borders can easily be modified - this article shows how...


I prefer pure Java solution and then putting JPanel containing JTree into MATLAB figure using javacomponent(). I used code from http://www.javaspecialists.eu/archive/Issue145.html
This is great. Is there a way to apply a filter to display only certain file types when using the tree for a file system?
@Mikhail – the link you posted is to a TristateCheckBox class, not a CheckBox tree. I plan to write an article someday about Matlab’s internal tri-state checkbox classes. Being internal and available in Matlab out-of-the-box, they are more useful than 3rd-party classes.
@Amy – filters are not available by default in uitree, but you can trap the node expansion callback function to implement this relatively easily.
@Mikhail – as promised, I posted the tri-state checkbox article last week.
It took me over a year from your comment, but I guess that it is better late than never, right?
Thanks for your great entry. I really like jave based checkbox tree.
Do you know how to callback in java based checkbox tree?
Thanks again for the great post. I’ve been playing with jtrees a lot lately and could now really use some customization of the Drag and Drop behavior. So, here’s a vote for a post on DnD.
Thanks
Scott
How do I get the information which checkboxes are checked when I use com.mathworks.mwswing.checkboxtree.CheckBoxTree?
Found a solution:
l1a.getSelectionStatethis is amazing!
i have a question about how to hide the Root.
just like a file system directory, use this method i can just display the files in C:\, how to show the files in D:\ within the same tree?
@Rex – I’m not sure you can using a simple single command: “My Computer” is not really a valid system folder. However, you can setup two tree nodes, one for C:\ and the other for D:\, and display them in a uitree. It’s not as simple as a one-line command, but it’s not very difficult and it will do what you want.
hi,Yair
I am an antenna engineer. I want to design a GUI to manage my antenna pattern data.
I realized a tree i need with actxcontrol about 4 years ago. This tree inluced some icons, i integrate them with a ActvieX Dll design with visual basic to load the pictures. But according to your blog, i think using VBScript to load the image is more effective.
Now i want to design a tree with uitree, but i do not know how to make them within one tree:
Root1
|__Child11
| |_____Subchild111
| |_____Subchild112
|__Child12
|_____Subchild121
|_____Subchild122
Root2
|__Child21
| |_____Subchild211
| |_____Subchild212
|__Child22
|_____Subchild221
|_____Subchild222
@Rex – the previous article in this series described how to create a custom tree.
Hi Yair,
We have used ‘com.jidesoft.swing.CheckBoxTree’
We want to have callback for two different user actions, namely,
- Checkbox checking event and
- Mouse click on the string without checking the check box itself
For the first event, we managed to handle it using the following lines of code
However for the second event we did not manage to find a listener.
Please advise
Thanks in advance
Amjad
@Amjad – there are several callbacks that you can use – all of them directly on the
jCheckBoxTreeobject. Specifically, your best guess would probably be MouseClickedCallback. Also, take a look at the related ClickInCheckBoxOnly boolean property.Pingback: Tri-state checkbox | Undocumented Matlab