Undocumented Matlab
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT
  • SERVICES
    • Consulting
    • Development
    • Training
    • Gallery
    • Testimonials
  • PRODUCTS
    • IQML: IQFeed-Matlab connector
    • IB-Matlab: InteractiveBrokers-Matlab connector
    • EODML: EODHistoricalData-Matlab connector
    • Webinars
  • BOOKS
    • Secrets of MATLAB-Java Programming
    • Accelerating MATLAB Performance
    • MATLAB Succinctly
  • ARTICLES
  • ABOUT
    • Policies
  • CONTACT

uitree

August 11, 2010 80 Comments

Can you guess which built-in Matlab function is the top search-term on UndocumentedMatlab.com and yet one of the least discussed topic on the CSSM forum?
The answer is uitree – Matlab’s built-in function for displaying data in a hierarchical (tree) GUI component. uitree has been included in all Matlab 7 releases, but has never been officially supported. Like most other uitools in the %matlabroot%/toolbox/matlab/uitools/ folder, uitree and its companion uitreenode are semi-documented, meaning that they have no support or doc-page, but do have readable help sections within their m-files. In our case, edit the uitree.m and uitreenode.m files to see their help section.
Note the following comment within %matlabroot%/toolbox/local/hgrc.m, which implies that uitree may soon become fully supported, although its interface might change somewhat (as was the case when uitable became supported in R2008a):
Temporarily turn off old uitree and uitreenode deprecated function warning… When we introduce the new documented uitree to replace the old undocumented uitree …
Like most other uitools (e.g. uitable and uitab), uitree is based on an underlying Java component, which ultimately extends Swing’s standard JTree. uitree sets up a scrollable JTree on-screen without the hassle of setting up a scrollable viewport and other similar nuts and bolts. In fact, you don’t need to know any Java to use uitree (although knowing JTree can greatly help you customize it) – uitrees can be manipulated using pure Matlab code, as shall be seen below.
uitree accepts an optional figure handle followed by P-V (property-value) pairs. Settable properties are Root, ExpandFcn, SelectionChangeFcn, Position (also Parent, but read on). As in uitab, a ‘v0’ input argument may be necessary to suppress a warning message. Note that uitrees are always created as a direct child of the containing figure, ignoring creation-time Parent values. However, the Parent property can be modified following the tree’s creation:

[mtree, container] = uitree('v0', 'Root','C:\', 'Parent',hPanel); % Parent is ignored
set(container, 'Parent', hPanel);  % fix the uitree Parent

[mtree, container] = uitree('v0', 'Root','C:\', 'Parent',hPanel); % Parent is ignored set(container, 'Parent', hPanel); % fix the uitree Parent

A simple uitree
A simple uitree

uitree returns two arguments: a handle to the created tree (a Java object wrapped within a Matlab handle) and an entirely-undocumented second optional argument holding a handle to the Matlab GUI container of the created tree. These two arguments are exactly the two arguments returned from the javacomponent function that I described last week.

uitreenode

uitree automatically understands Root objects of type Handle Graphics, Simulink model or char string (interpreted as a file-system folder name). Other Root types require setting dedicated ExpandFcn, SelectionChangeFcn Matlab callbacks (see uitree‘s help section or below for examples).
If we need to create a custom tree hierarchy (i.e., our root node is not an HG object, Simulink model or folder name), then we need to use the semi-documented uitreenode function as follows:

node = uitreenode('v0',handle(mtree),'my root','c:\root.gif',false);
mtree.setRoot(node);
set(mtree,'Root',node);  % alternative to mtree.setRoot()

node = uitreenode('v0',handle(mtree),'my root','c:\root.gif',false); mtree.setRoot(node); set(mtree,'Root',node); % alternative to mtree.setRoot()

uitreenode accepts 4 arguments: a string or handle value (the node’s “internal” value), a string description (shown next to the node’s icon), an icon filename ([] will result in an icon assigned based on the node value), and a flag indicating whether the node is a leaf (no children) or not.
uitreenode returns a node object, which is little more than a Matlab handle wrapper for a Java Swing DefaultMutableTreeNode.

Node manipulation

Nodes can be added, moved or removed by node methods: node.add(anotherNode) adds anotherNode to the end of this node’s children list (possibly detaching it from its previous parent); node.insert(anotherNode,index) does the same but inserts anotherNode at a specific child index, rather than at the end; node.clone() makes a duplicate of this node that can then be added to another node; node.remove(index) and node.remove(node) remove a specific node whereas node.removeFromParent() removes this node; node.removeAllChildren() removes all children, if any, of this node.
Nodes can also be added and removed at the tree level: mtree.add(parent,nodes) allows adding a list of nodes to a parent node and mtree.remove(nodes) removes the specified nodes.
In order to programmatically collapse and expand nodes, use mtree.collapse(node) and mtree.expand(node).
Nodes can be programmatically selected using mtree.setSelectedNode(node). Multiple nodes may be selected using mtree.setSelectedNodes, if an earlier call to mtree.setMultipleSelectionEnabled(true) was made (default is multiple-selection disabled):

mtree.setSelectedNode(root);  % root is a node
mtree.setSelectedNodes([root,node1,node2]);  % select 3 nodes

mtree.setSelectedNode(root); % root is a node mtree.setSelectedNodes([root,node1,node2]); % select 3 nodes

programmatically selecting multiple tree nodes
programmatically selecting multiple tree nodes

The currently-selected node(s) can be accessed using mtree.getSelectedNodes. Node selection callbacks often require knowledge of the currently selected rows:

% Tree set up
mtree = uitree(..., 'SelectionChangeFcn',@mySelectFcn);
set(mtree, 'SelectionChangeFcn',@mySelectFcn); % an alternative
% The tree-node selection callback
function nodes = mySelectFcn(tree, value)
    selectedNodes = tree.getSelectedNodes;
    if ~isempty(selectedNodes)
        % ...
    end
end  % mySelectFcn

% Tree set up mtree = uitree(..., 'SelectionChangeFcn',@mySelectFcn); set(mtree, 'SelectionChangeFcn',@mySelectFcn); % an alternative % The tree-node selection callback function nodes = mySelectFcn(tree, value) selectedNodes = tree.getSelectedNodes; if ~isempty(selectedNodes) % ... end end % mySelectFcn

Interested readers might also benefit from looking at the tree manipulations that I have programmed in my FindJObj utility.
Next week’s article will show how uitrees can be customized. There are numerous possible customizations, including icons, labels, appearance, and behavior. So if you have any special request, please post a comment below.

Related posts:

  1. Customizing uitree – This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  2. An interesting uitree utility – ExploreStruct is a utility that shows how custom uitrees can be integrated in Matlab GUI...
  3. Customizing uitree nodes – part 2 – This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  4. Customizing uitree nodes – part 1 – This article describes how to customize specific nodes of Matlab GUI tree controls created using the undocumented uitree function...
  5. 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....
  6. Tab panels – uitab and relatives – This article describes several undocumented Matlab functions that support tab-panels...
GUI Handle graphics Java Pure Matlab Semi-documented function uitools
Print Print
« Previous
Next »
80 Responses
  1. Luc VDP June 28, 2010 at 05:24 Reply

    Hello,
    I’m trying to make a tree to store links to interesting m-files.
    So I’d like to learn a bit more about using Uitree.
    This is the code I have so far.
    I have problems adding nodes in the tree : I don’t get my tree refreshed without restarting my gui.
    Any feedback is welcome

    function tree
    % Treeview showing interesting matlab files in ArcelorMittal Gent
    %
    % Example : tree
    %
    % Copyright 2010-06-27 - luc.vandeputte@arcelormittal.com
     
    %% Create window
    myFig = figure('NumberTitle','off',...
    'Menubar','none',...
    'Toolbar','none',...
    'Name', 'ArcelorMittal Gent Matlab Tree', ...
    'ResizeFcn',@ResizeFcn);
     
    %% Load treedata
    treedata=load('treedata');
    treedata=treedata.treedata;
     
    %% Create root tree node
    root = uitreenode('v0', 0, 'Interesting Matlab files', [], false);
     
    % Create tree on certain position (and add root node)
    posFig=get(myFig,'OuterPosition');
    posTree=[2, 2 , posFig(1,3)/3, posFig(1,4)-84];
    myTree = uitree('v0', 'Parent', myFig, ...
    'Position', posTree, ...
    'Root', root, ...
    'ExpandFcn', @ExpandFcn );
    set(myTree,'NodeSelectedCallback', @SelectFcn);
     
    % Create Path label
    myLabelPath  = uicontrol('Style','edit', 'Fontsize', 10, 'String', 'Path:', 'HorizontalAlignment','left');
     
    % Create command label
    myLabelCommand  = uicontrol('Style','edit', 'Fontsize', 10, 'String', 'Command:', 'HorizontalAlignment','left');
     
    % Create buttons
    myMakeCurrentFolder  = uicontrol('Style','togglebutton', 'Fontsize', 10, 'String', 'Make current folder','Callback',@MakeCurrentFolder);
    myAddToPath  = uicontrol('Style','togglebutton', 'Fontsize', 10, 'String', 'Add to path','Callback',@AddToPath);
    myOpenFile  = uicontrol('Style','pushbutton', 'Fontsize', 10, 'String', 'Open file','Callback',@OpenFile);
    myRun  = uicontrol('Style','pushbutton', 'Fontsize', 10, 'String', 'Run','Callback',@RunCommand);
     
    % Create textbox
    myText  = uicontrol('Style','edit', 'Fontsize', 10, 'Max',2, 'HorizontalAlignment','left');
     
    % Create menu
    myMenu = uimenu(myFig,'Label','Tree');
    myMenuAddMenuAfter = uimenu(myMenu,'Label','Add menu after...','Callback',@MenuAddMenuAfter);
    myMenuAddMenuIn = uimenu(myMenu,'Label','Add menu in...','Callback',@MenuAddMenuIn);
    myMenuAddItemAfter = uimenu(myMenu,'Label','Add item after...','Separator','on','Callback',@MenuAddItemAfter);
    myMenuAddItemIn = uimenu(myMenu,'Label','Add item in...','Callback',@MenuAddItemIn);
    myMenuMove = uimenu(myMenu,'Label','Move...','Separator','on','Separator','on','Callback',@MenuMove);
    myMenuCancelMove = uimenu(myMenu,'Label','Cancel move','Visible','off','Callback',@MenuCancelMove);
    myMenuEdit = uimenu(myMenu,'Label','Edit...','Separator','on','Callback',@MenuEdit);
    myMenuDelete = uimenu(myMenu,'Label','Delete...','Separator','on','Callback',@MenuDelete);
     
    % ???
    selection_hash = java.util.Hashtable;
    toolkit = java.awt.Toolkit.getDefaultToolkit;
    pin_image = toolkit.createImage([matlabroot,'/toolbox/matlab/icons/pin_icon.gif']);
    page_image = toolkit.createImage([matlabroot,'/toolbox/matlab/icons/pageicon.gif']);
     
    % Select root node
    myTree.setSelectedNode(root);
    myTree.expand(root);
     
    %% Action when treenode selected
    function SelectFcn(tree, ~)
    nodes = tree.SelectedNodes;
    if isempty(nodes)
    return
    end
    node = nodes(1);
    treenode=treedata(treedata.Id==node.getValue,:);
    if strcmp(treenode.Type,'F')
    set(myLabelPath,'String',treenode.Path);
    set(myLabelCommand,'String',treenode.Command);
    strTemp=eval(['help(''' treenode.Path{:} treenode.Command{:} ''')']);
    set(myText,'String',strTemp);
    else
    set(myLabelPath,'String','Menu');
    set(myLabelCommand,'String',treenode.Name);
    set(myText,'String','');
    end
    end
     
    %% Action when treenode is Expanded
    function nodes = ExpandFcn(~, value)
    % Take all children
    treenodes = treedata(treedata.ParentId==value,:);
     
    for i = 1:size(treenodes,1)
    if strcmp(treenodes.Type(i),'M') 
    iconpath = [matlabroot,'/toolbox/matlab/icons/foldericon.gif'];
    leaf = false;
    else
    iconpath = [matlabroot,'/toolbox/matlab/icons/pageicon.gif'];
    leaf = true;
    end
    nodes(i) = uitreenode('v0',treenodes.Id(i),treenodes.Name(i), iconpath, leaf);
    end
    if size(treenodes,1) == 0
    nodes = [];
    end
    end
     
    %% Executes when figure is resized.
    function ResizeFcn(hObject, eventdata, handles)
    % hObject    handle to figure1 (see GCBO)
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    posFig=get(myFig,'OuterPosition');
    posTree=[2, 2 , posFig(1,3)/3, posFig(1,4)-58];
    posLabelPath = [posFig(1,3)/3+4, posFig(1,4)-76, 2*posFig(1,3)/3-12, 20];
    posMakeCurrentFolder = [posFig(1,3)/3+4, posFig(1,4)-98, 140, 20];
    posAddToPath = [posFig(1,3)/3+144, posFig(1,4)-98, 90, 20];
    posOpenFile = [posFig(1,3)/3+234, posFig(1,4)-98, 70, 20];
    posRun = [posFig(1,3)/3+304, posFig(1,4)-98, 60, 20];
    posLabelCommand = [posFig(1,3)/3+4, posFig(1,4)-120, 2*posFig(1,3)/3-12, 20];
    posText=[posFig(1,3)/3+4, 2 , 2*posFig(1,3)/3-12, posFig(1,4)-128];
     
    set(myTree,'Position',posTree);
    set(myLabelPath,'Position',posLabelPath);
    set(myMakeCurrentFolder,'Position',posMakeCurrentFolder);
    set(myAddToPath,'Position',posAddToPath);
    set(myOpenFile,'Position',posOpenFile);
    set(myRun,'Position',posRun);
    set(myText,'Position',posText);
     
    set(myLabelCommand,'Position',posLabelCommand);
    end
     
    %% Functions connected to menu
    function MenuAddItemAfter(hObject, eventdata, handles)
    %Let user select the m-file
    [FileName,PathName,FilterIndex] = uigetfile('*.m','Select the MATLAB code file');
    % Show path, command (m-file name) and help information
    if size(FileName,2)>1 
    set(myLabelPath,'String',PathName);
    set(myLabelCommand,'String',FileName);
    strTemp=eval(['help(''' PathName FileName ''')']);
    set(myText,'String',strTemp);
    end
    % Add to treedata
    myNodes = myTree.SelectedNodes;
    myNode = myNodes(1);
    Id = myNode.getValue;
    index = find(treedata.Id == Id);
    treedata1 = treedata(1:index,:);
    treedata2 = dataset();
    treedata2.Id = max(treedata.Id) + 1;
    treedata2.ParentId = treedata.ParentId(index);
    treedata2.Name = {FileName};
    treedata2.Type = 'F';
    treedata2.Path = {PathName};
    treedata2.Command = {FileName};
    treedata3 = treedata(index+1:end,:);
    treedata=[treedata1;treedata2;treedata3];
    save treedata treedata;
    % Refresh tree
    myTree.expand
    myTree.repaint
    %Add new node
    %iconpath = [matlabroot,'/toolbox/matlab/icons/pageicon.gif'];
    %leaf = true;
    %newNode = uitreenode('v0',treedata2.Id,treedata2.Name, iconpath, leaf);
     
    %%% nodes(i) = uitreenode('v0',treenodes.Id(i),treenodes.Name(i), iconpath, leaf);
    %ExpandFcn(myTree,myNode.getParent);
    %myTree.reloadNode(myNode.getParent);
    %myTree.reloadNode(myNode);
    %myTree.reloadNode(myNode);
    %myTree.repaint
    end
     
    function MenuAddItemIn(hObject, eventdata, handles)
    filename = uigetfile;
    end
     
    function MenuAddMenuAfter(hObject, eventdata, handles)
    end
     
    function MenuAddMenuIn(hObject, eventdata, handles)
    end
     
    function MenuMove(hObject, eventdata, handles)
    end
     
    function MenuCancelMove(hObject, eventdata, handles)
    end
     
    function MenuEdit(hObject, eventdata, handles)
    end
     
    function MenuDelete(hObject, eventdata, handles)
    end
     
    function MenuExit(hObject, eventdata, handles)
    %exit
    end
     
    %% Functions connected to buttons
    function MakeCurrentFolder(hObject, eventdata, handles)
    %exit
    end
     
    function AddToPath(hObject, eventdata, handles)
    %exit
    end
     
    function OpenFile(hObject, eventdata, handles)
    %exit
    end
     
    function RunCommand(hObject, eventdata, handles)
    strCommand=get(myLabelCommand,'String');
    eval(strrep(strCommand{:},'.m',''));
    end
     
    end

    function tree % Treeview showing interesting matlab files in ArcelorMittal Gent % % Example : tree % % Copyright 2010-06-27 - luc.vandeputte@arcelormittal.com %% Create window myFig = figure('NumberTitle','off',... 'Menubar','none',... 'Toolbar','none',... 'Name', 'ArcelorMittal Gent Matlab Tree', ... 'ResizeFcn',@ResizeFcn); %% Load treedata treedata=load('treedata'); treedata=treedata.treedata; %% Create root tree node root = uitreenode('v0', 0, 'Interesting Matlab files', [], false); % Create tree on certain position (and add root node) posFig=get(myFig,'OuterPosition'); posTree=[2, 2 , posFig(1,3)/3, posFig(1,4)-84]; myTree = uitree('v0', 'Parent', myFig, ... 'Position', posTree, ... 'Root', root, ... 'ExpandFcn', @ExpandFcn ); set(myTree,'NodeSelectedCallback', @SelectFcn); % Create Path label myLabelPath = uicontrol('Style','edit', 'Fontsize', 10, 'String', 'Path:', 'HorizontalAlignment','left'); % Create command label myLabelCommand = uicontrol('Style','edit', 'Fontsize', 10, 'String', 'Command:', 'HorizontalAlignment','left'); % Create buttons myMakeCurrentFolder = uicontrol('Style','togglebutton', 'Fontsize', 10, 'String', 'Make current folder','Callback',@MakeCurrentFolder); myAddToPath = uicontrol('Style','togglebutton', 'Fontsize', 10, 'String', 'Add to path','Callback',@AddToPath); myOpenFile = uicontrol('Style','pushbutton', 'Fontsize', 10, 'String', 'Open file','Callback',@OpenFile); myRun = uicontrol('Style','pushbutton', 'Fontsize', 10, 'String', 'Run','Callback',@RunCommand); % Create textbox myText = uicontrol('Style','edit', 'Fontsize', 10, 'Max',2, 'HorizontalAlignment','left'); % Create menu myMenu = uimenu(myFig,'Label','Tree'); myMenuAddMenuAfter = uimenu(myMenu,'Label','Add menu after...','Callback',@MenuAddMenuAfter); myMenuAddMenuIn = uimenu(myMenu,'Label','Add menu in...','Callback',@MenuAddMenuIn); myMenuAddItemAfter = uimenu(myMenu,'Label','Add item after...','Separator','on','Callback',@MenuAddItemAfter); myMenuAddItemIn = uimenu(myMenu,'Label','Add item in...','Callback',@MenuAddItemIn); myMenuMove = uimenu(myMenu,'Label','Move...','Separator','on','Separator','on','Callback',@MenuMove); myMenuCancelMove = uimenu(myMenu,'Label','Cancel move','Visible','off','Callback',@MenuCancelMove); myMenuEdit = uimenu(myMenu,'Label','Edit...','Separator','on','Callback',@MenuEdit); myMenuDelete = uimenu(myMenu,'Label','Delete...','Separator','on','Callback',@MenuDelete); % ??? selection_hash = java.util.Hashtable; toolkit = java.awt.Toolkit.getDefaultToolkit; pin_image = toolkit.createImage([matlabroot,'/toolbox/matlab/icons/pin_icon.gif']); page_image = toolkit.createImage([matlabroot,'/toolbox/matlab/icons/pageicon.gif']); % Select root node myTree.setSelectedNode(root); myTree.expand(root); %% Action when treenode selected function SelectFcn(tree, ~) nodes = tree.SelectedNodes; if isempty(nodes) return end node = nodes(1); treenode=treedata(treedata.Id==node.getValue,:); if strcmp(treenode.Type,'F') set(myLabelPath,'String',treenode.Path); set(myLabelCommand,'String',treenode.Command); strTemp=eval(['help(''' treenode.Path{:} treenode.Command{:} ''')']); set(myText,'String',strTemp); else set(myLabelPath,'String','Menu'); set(myLabelCommand,'String',treenode.Name); set(myText,'String',''); end end %% Action when treenode is Expanded function nodes = ExpandFcn(~, value) % Take all children treenodes = treedata(treedata.ParentId==value,:); for i = 1:size(treenodes,1) if strcmp(treenodes.Type(i),'M') iconpath = [matlabroot,'/toolbox/matlab/icons/foldericon.gif']; leaf = false; else iconpath = [matlabroot,'/toolbox/matlab/icons/pageicon.gif']; leaf = true; end nodes(i) = uitreenode('v0',treenodes.Id(i),treenodes.Name(i), iconpath, leaf); end if size(treenodes,1) == 0 nodes = []; end end %% Executes when figure is resized. function ResizeFcn(hObject, eventdata, handles) % hObject handle to figure1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) posFig=get(myFig,'OuterPosition'); posTree=[2, 2 , posFig(1,3)/3, posFig(1,4)-58]; posLabelPath = [posFig(1,3)/3+4, posFig(1,4)-76, 2*posFig(1,3)/3-12, 20]; posMakeCurrentFolder = [posFig(1,3)/3+4, posFig(1,4)-98, 140, 20]; posAddToPath = [posFig(1,3)/3+144, posFig(1,4)-98, 90, 20]; posOpenFile = [posFig(1,3)/3+234, posFig(1,4)-98, 70, 20]; posRun = [posFig(1,3)/3+304, posFig(1,4)-98, 60, 20]; posLabelCommand = [posFig(1,3)/3+4, posFig(1,4)-120, 2*posFig(1,3)/3-12, 20]; posText=[posFig(1,3)/3+4, 2 , 2*posFig(1,3)/3-12, posFig(1,4)-128]; set(myTree,'Position',posTree); set(myLabelPath,'Position',posLabelPath); set(myMakeCurrentFolder,'Position',posMakeCurrentFolder); set(myAddToPath,'Position',posAddToPath); set(myOpenFile,'Position',posOpenFile); set(myRun,'Position',posRun); set(myText,'Position',posText); set(myLabelCommand,'Position',posLabelCommand); end %% Functions connected to menu function MenuAddItemAfter(hObject, eventdata, handles) %Let user select the m-file [FileName,PathName,FilterIndex] = uigetfile('*.m','Select the MATLAB code file'); % Show path, command (m-file name) and help information if size(FileName,2)>1 set(myLabelPath,'String',PathName); set(myLabelCommand,'String',FileName); strTemp=eval(['help(''' PathName FileName ''')']); set(myText,'String',strTemp); end % Add to treedata myNodes = myTree.SelectedNodes; myNode = myNodes(1); Id = myNode.getValue; index = find(treedata.Id == Id); treedata1 = treedata(1:index,:); treedata2 = dataset(); treedata2.Id = max(treedata.Id) + 1; treedata2.ParentId = treedata.ParentId(index); treedata2.Name = {FileName}; treedata2.Type = 'F'; treedata2.Path = {PathName}; treedata2.Command = {FileName}; treedata3 = treedata(index+1:end,:); treedata=[treedata1;treedata2;treedata3]; save treedata treedata; % Refresh tree myTree.expand myTree.repaint %Add new node %iconpath = [matlabroot,'/toolbox/matlab/icons/pageicon.gif']; %leaf = true; %newNode = uitreenode('v0',treedata2.Id,treedata2.Name, iconpath, leaf); %%% nodes(i) = uitreenode('v0',treenodes.Id(i),treenodes.Name(i), iconpath, leaf); %ExpandFcn(myTree,myNode.getParent); %myTree.reloadNode(myNode.getParent); %myTree.reloadNode(myNode); %myTree.reloadNode(myNode); %myTree.repaint end function MenuAddItemIn(hObject, eventdata, handles) filename = uigetfile; end function MenuAddMenuAfter(hObject, eventdata, handles) end function MenuAddMenuIn(hObject, eventdata, handles) end function MenuMove(hObject, eventdata, handles) end function MenuCancelMove(hObject, eventdata, handles) end function MenuEdit(hObject, eventdata, handles) end function MenuDelete(hObject, eventdata, handles) end function MenuExit(hObject, eventdata, handles) %exit end %% Functions connected to buttons function MakeCurrentFolder(hObject, eventdata, handles) %exit end function AddToPath(hObject, eventdata, handles) %exit end function OpenFile(hObject, eventdata, handles) %exit end function RunCommand(hObject, eventdata, handles) strCommand=get(myLabelCommand,'String'); eval(strrep(strCommand{:},'.m','')); end end

    • Scott Koch August 12, 2010 at 09:19 Reply

      Luc VDP –

      Yair will correct me if I’m wrong but I think some of your problem might be related to the fact the ML tree is set up for lazy loading. The leafs aren’t actually created until you expand. So if you want a leaf to show up on a refresh (rather than a user actually clicking on it) you’ll actually have to expand to its location programmatically (I know there’s an .expandrow method but there are probably other ways to).

      Scott

    • Clement Val August 13, 2010 at 14:29 Reply

      For Luc : maybe this is too late or you figure it out, but to refresh the display after altering nodes, you should use the reloadNode() method on the parent node.

  2. Scott Koch August 12, 2010 at 09:20 Reply

    Any idea on how to enable Drag and Drop on older versions of uitree? In Matlab 7.0.4 (Windows), uitree.m mentions a β€œDndEnabled” but it appears to have no affect. However, with ML 2007a DnD appears to be enabled by default.

    What would be really useful is to have DnD available across a figure and or between panels but I’d imagine that’s pretty complicated.

    Scott

    • Malcolm Lidierth August 13, 2010 at 08:42 Reply

      Scott
      Below are some generic solutions that I have taken out of some code I developed to simulate drag-and-drop between a JTree and a MATLAB figure using the WindowButtonMotion callback.
      You may need to shake the mouse to initiate the callback on faster PCs- but that becomes second nature surprisingly quickly.

      function GUIComponentTreeSetupDrop(hObject, DragEventData, fh)
      % LocalSetupDrop = Mouse Dragged Callback
      % Set this up using
      %               obj.setDragEnabled(true);
      %               obj.MouseDraggedCallback={@LocalSetupDrop, fh};
      %                       where obj is a javax.swing component and
      %                       fh is the parent figure handle
      % This function relies on the observation that at least one MouseDragged
      % event will be fired when initiating a drag-and-drop
      setappdata(fh, 'GUIBuilderCurrentDragEventData', DragEventData);
      fcn=get(ancestor(fh, 'figure'), 'WindowButtonMotionFcn');
      set(ancestor(fh, 'figure'), 'WindowButtonMotionFcn', {@LocalMakeDrop, fcn});
      drawnow();
      return
      end
       
      function LocalMakeDrop(fhandle, EventDataToIgnore, fcn)
      % LocalMakeDrop = Simulate a drop action via WindowButtonMotionFcn
      % The figure application data area contains 'GUIBuilderCurrentDragEventData'
      % This contains a java.awt.event.MouseEvent object identifying the drag
      % source and can be used to find what needs to be dropped
      %           e.g. from a javax.swing.JTree
      %                   src=DragEventData.getSource();
      %                   todrop=src.getSelectionPath();
      %                               or
      %                   todrop=src.getSelectionRows();
      %
      % This function requires a WindowButtonMotion event to be fired.
      % On some computers this will nearly always happen when a drop is made. On others,
      % typically on newer machines, you will need to shake the mouse to initiate
      % the drop action.
       
      % Clear WindowButtonMotionFcn to prevent new calls.
      set(fhandle, 'WindowButtonMotionFcn', []);
      % Have we been too slow anyway?
      if isMultipleCall()
      % Only service the first call if we have multiple calls to
      % LocalMakeDrop in the queue
      set(fhandle, 'WindowButtonMotionFcn', @GUIWindowButtonMotionFcn);
      return
      end
      setptr(fhandle,'watch');
      drawnow();
      %-------------------------------------------------------------------------
      % -- USER CODE GOES HERE - it may help to add a drawnow() at the end the code
      %
      drawnow();
      %----------------------------------------------------------
      % Tidy up
      set(fhandle, 'WindowButtonMotionFcn', fcn);
      setptr(fhandle, 'arrow');
      return
      end

      function GUIComponentTreeSetupDrop(hObject, DragEventData, fh) % LocalSetupDrop = Mouse Dragged Callback % Set this up using % obj.setDragEnabled(true); % obj.MouseDraggedCallback={@LocalSetupDrop, fh}; % where obj is a javax.swing component and % fh is the parent figure handle % This function relies on the observation that at least one MouseDragged % event will be fired when initiating a drag-and-drop setappdata(fh, 'GUIBuilderCurrentDragEventData', DragEventData); fcn=get(ancestor(fh, 'figure'), 'WindowButtonMotionFcn'); set(ancestor(fh, 'figure'), 'WindowButtonMotionFcn', {@LocalMakeDrop, fcn}); drawnow(); return end function LocalMakeDrop(fhandle, EventDataToIgnore, fcn) % LocalMakeDrop = Simulate a drop action via WindowButtonMotionFcn % The figure application data area contains 'GUIBuilderCurrentDragEventData' % This contains a java.awt.event.MouseEvent object identifying the drag % source and can be used to find what needs to be dropped % e.g. from a javax.swing.JTree % src=DragEventData.getSource(); % todrop=src.getSelectionPath(); % or % todrop=src.getSelectionRows(); % % This function requires a WindowButtonMotion event to be fired. % On some computers this will nearly always happen when a drop is made. On others, % typically on newer machines, you will need to shake the mouse to initiate % the drop action. % Clear WindowButtonMotionFcn to prevent new calls. set(fhandle, 'WindowButtonMotionFcn', []); % Have we been too slow anyway? if isMultipleCall() % Only service the first call if we have multiple calls to % LocalMakeDrop in the queue set(fhandle, 'WindowButtonMotionFcn', @GUIWindowButtonMotionFcn); return end setptr(fhandle,'watch'); drawnow(); %------------------------------------------------------------------------- % -- USER CODE GOES HERE - it may help to add a drawnow() at the end the code % drawnow(); %---------------------------------------------------------- % Tidy up set(fhandle, 'WindowButtonMotionFcn', fcn); setptr(fhandle, 'arrow'); return end

      • Malcolm Lidierth August 13, 2010 at 08:46

        Error. The “@GUIWindowButtonMotionFcn” in the code above should be “fcn” for a generic solution. GUIWindowButtonMotionFcn is just the standard callback in my particular application.

  3. Stephen L August 31, 2010 at 08:34 Reply

    Is there anyway to have the parent of a tree be a panel rather then a figure?

    Thanks.

    • Yair Altman August 31, 2010 at 14:08 Reply

      @Stephan – as explained in the article, you can set a tree’s parent to a uipanel using the Parent property, but only after the tree has been created:

      hPanel = uipanel(...);
      [mtree, container] = uitree('v0', 'Root','C:');
      set(container, 'Parent', hPanel, 'Position',...);

      hPanel = uipanel(...); [mtree, container] = uitree('v0', 'Root','C:'); set(container, 'Parent', hPanel, 'Position',...);

  4. Drew October 6, 2010 at 15:09 Reply

    I would like to say, I just discovered this blog, and am really blown away. I’m loving all the new stuff I’m learning.

    I’ve been trying to implement a GUI with three tabs. Each tab has a child panel and in one of the tabs I’ve tried to place a uitree. However, regardless of how I set the uitree’s parent value, it always seems to be the figure, and not the panel on the tab. As a result, the uitree is always displayed regardless of which tab is selected.

    I’ve included the code below. Is there something obvious I’m doing incorrectly?

    hTabGroup = uitabgroup('Parent', gcf); drawnow;
     
    tab0 = uitab('Parent', hTabGroup, 'title','Open Existing Project');
    panel0=uipanel('Parent', tab0, 'Title', 'Select Project to Load');
    a0=uicontrol('Parent', panel0, 'Style', 'listbox');
    set(a0, 'String', {'Project_1', 'Project_2', 'Project_3'});
    set(a0, 'Position', [5 5 200 150]);
     
    tab1 = uitab('Parent', hTabGroup, 'title','Create New Project');
    a1 = uipanel('Parent', tab1, 'Title', 'Create a New Project');
     
    tab2 = uitab('Parent', hTabGroup, 'title','Edit Existing Project');
    panel2=uipanel('Parent', tab2, 'Title', 'Select Project to Edit');
     
    % Tree
    [mtree, mtreeContainer] = uitree('Parent', panel2, 'Root','C:');
    set(mtree, 'Position', [5 5 200 150]);

    hTabGroup = uitabgroup('Parent', gcf); drawnow; tab0 = uitab('Parent', hTabGroup, 'title','Open Existing Project'); panel0=uipanel('Parent', tab0, 'Title', 'Select Project to Load'); a0=uicontrol('Parent', panel0, 'Style', 'listbox'); set(a0, 'String', {'Project_1', 'Project_2', 'Project_3'}); set(a0, 'Position', [5 5 200 150]); tab1 = uitab('Parent', hTabGroup, 'title','Create New Project'); a1 = uipanel('Parent', tab1, 'Title', 'Create a New Project'); tab2 = uitab('Parent', hTabGroup, 'title','Edit Existing Project'); panel2=uipanel('Parent', tab2, 'Title', 'Select Project to Edit'); % Tree [mtree, mtreeContainer] = uitree('Parent', panel2, 'Root','C:'); set(mtree, 'Position', [5 5 200 150]);

    • Yair Altman October 6, 2010 at 15:55 Reply

      @Drew – thanks for the compliment.

      uitree is basically just a Java component, and Matlab’s implementation of uitab has a known bug that it does not hide Java or ActiveX objects when switching tabs.

      The link I just gave provides some leads to solving this issue; you can try modifying the m-files in the folders %matlabroot%/toolbox/matlab/@uitools/@uitabgroup and /@uitools/@uitab, or you can use an actual JTabbedPanel (or one of several other Tab implementations mentioned in my uitab article) rather than Matlab’s built-in uitab.

      No easy fix, I’m afraid…

      – Yair

    • Simon February 18, 2013 at 04:09 Reply

      Hi Yair, Hi Drew,

      The following seems to do the trick:

      1) Define the tree through javacomponent and hide it (‘Visible’, 0)

      M_treeH = com.mathworks.hg.peer.UITreePeer;
      M_treeH.setRoot([]);
      handles.uiTreeH = javacomponent(M_treeH, [], handles.TestTab);
      set(handles.uiTreeH,'Units','Pixels','Position',[5 134 265 755], 'Visible',0);

      M_treeH = com.mathworks.hg.peer.UITreePeer; M_treeH.setRoot([]); handles.uiTreeH = javacomponent(M_treeH, [], handles.TestTab); set(handles.uiTreeH,'Units','Pixels','Position',[5 134 265 755], 'Visible',0);

      2) Attach SelectionChangeFcn to the uitabgroup (after defining uiTreeH !), where the uiTreeH visibility is toggled depending on the tab selected:

      set(uitabgroupHandle,'SelectionChangeFcn',{@UITabSelectionChange_Callback,handles});
      ...
       
      function UITabSelectionChange_Callback(hObject,eventdata,handles)
      if eventdata.NewValue == 2
      set(handles.uiTreeH,'Visible',1); 
      else
      set(handles.uiTreeH,'Visible',0); 
      end

      set(uitabgroupHandle,'SelectionChangeFcn',{@UITabSelectionChange_Callback,handles}); ... function UITabSelectionChange_Callback(hObject,eventdata,handles) if eventdata.NewValue == 2 set(handles.uiTreeH,'Visible',1); else set(handles.uiTreeH,'Visible',0); end

      -:) Simon

  5. Tony October 27, 2010 at 23:52 Reply

    Hello,

    I have a question regarding tree creation.

    Typically, I would use node.setSelectedNodes() to mark a parent and then create a new child node below using treeModel.insertNodeInto().

    The problem I am having is that Matlab seems not to wait for the setSelectedNodes-command to be finished before resuming its own code, and therefore, the order of the nodes gets mixed up (some times).

    My first and rather unsatisfying solution to the problem was to use pause() after each selection, making the tree build up very slowly.

    Is there any way to determine how long the java element exactly needs to finish the setSelectedNodes-command?

    Or is this error maybe due to the old Matlab version I am using, 2006a?

    Many thanks for any thoughts on this,
    Tony

    • Yair Altman October 28, 2010 at 00:03 Reply

      @Tony – You do not need to select the parent node.

      As I said in the main article above, nodes can be added directly: node.add(anotherNode) adds anotherNode to the end of node‘s children list (possibly detaching it from its previous parent); node.insert(anotherNode,index) does the same but inserts anotherNode at a specific child index, rather than at the end of the children list.

  6. Teresa Hall November 1, 2010 at 08:14 Reply

    I have created a tree inside a GUI, I do this in the figure create function. So the tree will be available to all the widgets, I put the tree into handles (handles.mtree=tree;). When I leave the create function a get(handles.mtree) returns a tree. But when I try to access it from other widgets, the command get(handles.mtree) returns the container that was created in the in my call to uitree. How do I get back to the actual tree?

    • Yair Altman November 1, 2010 at 13:03 Reply

      @Teresa – I’m not exactly sure what you mean, but if I guess correctly, you may be missing a call to guidata(hObject,handles); after you modify the handles struct with the uitree handle. If you don’t use guidata(), then the handles struct is not updated outside the function.

      -Yair

  7. Teresa Hall November 16, 2010 at 15:54 Reply

    Thanks for your answer. I found another way to get back to the tree. But now I have another question.

    I am trying to store information into the node of the tree to be accessed later in my processing.

    I am:
    1) creating the tree
    2) createing a new node and putting data into it’s UserData area
    3) inserting it into the tree
    4) selecting that node and trying to get the data back.

    % 1) Create the tree
    objects = uitreenode('v0', 'Objects', 'Objects', [], false);
    root = uitreenode('v0', 'Scenario', 'Scenario', [], false);
    root.add(objects);
    scTree = uitree('v0', 'Root',root);
     
    scTree.setSelectedNode(objects)
    selNode=scTree.getSelectedNodes;
    selNode=selNode(1);
     
    % 2) Create the new node and put data into the userdata area
    newNode=uitreenode('v0','selected',struct.name,[],0);
     
    % create a structure to put into the newNode userdata area
    struct.name='abc';
    struct.val=1;
    newNode.UserData=struct;
    % NOTE: The new node is a "javahandle.com.mathworks.hg.peer.UITreeNode"
    % whereas newNode.java is a "com.mathworks.hg.peer.UITreeNode:abc"
     
    % 3) Insert it into the tree
    selNode.add(newNode)
    % or scTree.Model.insertNodeInto(newNode,selNode,selNode.getChildCount());
    scTree.setSelectedNode(newNode);
     
    % 3) selecting that node and trying to get the data back.
    selNode=scTree.getSelectedNodes;
    selNode=selNode(1);
    % NOTE: selNode is a "com.mathworks.hg.peer.UITreeNode:abc", the same as
    % newNode.java.

    % 1) Create the tree objects = uitreenode('v0', 'Objects', 'Objects', [], false); root = uitreenode('v0', 'Scenario', 'Scenario', [], false); root.add(objects); scTree = uitree('v0', 'Root',root); scTree.setSelectedNode(objects) selNode=scTree.getSelectedNodes; selNode=selNode(1); % 2) Create the new node and put data into the userdata area newNode=uitreenode('v0','selected',struct.name,[],0); % create a structure to put into the newNode userdata area struct.name='abc'; struct.val=1; newNode.UserData=struct; % NOTE: The new node is a "javahandle.com.mathworks.hg.peer.UITreeNode" % whereas newNode.java is a "com.mathworks.hg.peer.UITreeNode:abc" % 3) Insert it into the tree selNode.add(newNode) % or scTree.Model.insertNodeInto(newNode,selNode,selNode.getChildCount()); scTree.setSelectedNode(newNode); % 3) selecting that node and trying to get the data back. selNode=scTree.getSelectedNodes; selNode=selNode(1); % NOTE: selNode is a "com.mathworks.hg.peer.UITreeNode:abc", the same as % newNode.java.

    My question is how do I get back to the userdata in the javahandle.com.mathworks.hg.peer.UITreeNode object create earlier?

    • Donn Shull November 17, 2010 at 09:47 Reply

      @Teresa – Use the handle method ie: selNode.handle. This will return the javahandle.com.mathworks.hg.peer.UITreeNode you need. So for your example selNode.handle.UserData will return your struct. handle and java are complementary methods for converting to and from the javahandle package.

      • Teresa Hall November 17, 2010 at 09:50

        Thank You!
        Thank You!
        Thank You!

    • Magnus Hanses February 22, 2013 at 04:23 Reply

      besides to return the UserData, is it possible to change it?

    • Magnus Hanses February 22, 2013 at 04:31 Reply

      just realized you can set it the same way

      selNode.handle.UserData = newData;

      selNode.handle.UserData = newData;

  8. Everest November 17, 2010 at 14:40 Reply

    I’ve got a giant Excel file (~6000 entries) with values like this:

    /CE_2/CE2_Normal_Telemetry/CCE_Amp_Temperature_Trip_Low
    /CE_2/CE2_Normal_Telemetry/CCE_Amplifier_Temperature_Rate
    /CE_2/CE2_Normal_Telemetry/CCE_Converter_Temp_Trip_High
    /CE_2/CE2_Normal_Telemetry/CCE_Converter_Temp_Trip_Low
    /CE_2/CE2_Normal_Telemetry/CCSDS_API
    /CE_2/CE2_Normal_Telemetry/CCSDS_Sequence_Count
    /CE_2/CE2_Normal_Telemetry/CCSDS_Size
    /CE_2/CE2_Normal_Telemetry/CCSDS_Time
    /CE_2/CE2_Normal_Telemetry/CRC
    /CE_2/CE2_Normal_Telemetry/CSYNC

    Writing gargantuan code to decimate and rebuild this list manually in a UITREE.

    Anybody know of a shortcut?

  9. Henrik Toft January 16, 2011 at 12:20 Reply

    Hi

    Great post and discussion about “the tree”. Is there any way to make “Computer” or “Desktop” root, so the entire PC can be browsed?

    Regards,
    Henrik

    • Jason January 20, 2011 at 14:54 Reply

      Henrik,

      You could do it yourself, or use uigetfile instead.

      Regards,
      Jason

  10. Joe Burgel February 4, 2011 at 07:51 Reply

    All,

    I’m having a lot of problems with uitree – specifically with the expand function. If I give the root node more than one child and It returns those two node’s in the roots expand handler, uitree chokes… This is topping off two days of frustration in using uitree.

    All this frustration has got me thinking… What’s the advantage to uitree over simply implementing a JTree? What’s the advantage to all these ML wrapped java objects? I’ve put JTree’s in my ML apps before with little or no problems whatsoever. What am I getting for all the uitree frustration? Simplicity? Ease of use? I’m not seeing it.

    • Yair Altman February 5, 2011 at 10:30 Reply

      @Joe – I tend to agree that if you know your way around Java’s JTree (or better still, JIDE’s JTree extensions) then you don’t gain much with uitree. However, keep in mind that many if not most Matlab users are not so comfortable using Java – a built-in Matlab wrapper would be something they would happily use, but not a Java JTree.

      It was the same story with Matlab’s uitable. After many years in undocumented limbo, uitable (which was initially not much more than a JTable wrapper) finally became documented in 2008. Perhaps the same will happen to uitree some day…

      • Joe Burgel February 7, 2011 at 15:01

        Thanks for the reply Yair. I agree with you. I’m not a Java power coder but the online doc is very thorough. I can bump my way though. Java in ML is somewhat tedious although a lot less so now that I’m in ML 2010 and awtinvoke is no longer needed. If you write software for a living and have the time to learn, picking up Java is time well spent I think. I think I’ll go back to a JTree for now and maybe pick up uitree when it’s full grown. Thanks for all you Java support on this forum. I wouldn’t have gotten very far without it.

  11. Venkat February 8, 2011 at 00:13 Reply

    Hi,
    I have problem using uitree and uicontrol together. I am using a tree and a edit box on a figure window. I am trying to read different data through edit boxes for each node.
    Edit box’s callback function is not getting called when I immediately click on the tree’s node after entering data in edit box. After entering data in edit box, If I click enter or click on any other uiobject or on figure, then the callback is invoked. Edit box Callback is not working if I click immediately on tree’s node. Can someone suggest me how to fix this problem?

    • Yair Altman February 8, 2011 at 16:52 Reply

      @Venkat – try to set your edit-box’s FocusLostCallback property, because the standard Matlab handles indeed do not update the edit-box’s value in such cases. You’ll need to gain access to the edit-box’s underlying Java handle for this, using the findjobj utility.

  12. johnson jonaris May 19, 2011 at 12:27 Reply

    I have a problem with NodeSelectedCallback, in a GUIDE project when the function is called for some reason it doesn’t consider the calling figure as its current figure
    I tested that using the below simple program that draws a a tree with one node, in the callback function I ask for the current figure using gcf, it creates a new one.
    Any clue why this happens ?

    function varargout = treetest(varargin)
    gui_Singleton = 1;
    gui_State = struct('gui_Name',       mfilename, ...
    'gui_Singleton',  gui_Singleton, ...
    'gui_OpeningFcn', @treetest_OpeningFcn, ...
    'gui_OutputFcn',  @treetest_OutputFcn, ...
    'gui_LayoutFcn',  [] , ...
    'gui_Callback',   []);
    if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
    end
     
    if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
    else
    gui_mainfcn(gui_State, varargin{:});
    end
     
    function treetest_OpeningFcn(hObject, eventdata, handles, varargin)
    import javax.swing.*
    import javax.swing.tree.*;
     
    handles.output = hObject;
    handles.rootNode = uitreenode('v0', 'root', 'ConnectomeVis', [], 0);
    handles.treeModel = DefaultTreeModel( handles.rootNode );           
    [handles.mTree, handles.TreeCon] = uitree('v0','Root',handles.rootNode);
    handles.mTree.setModel( handles.treeModel );
    set (handles.TreeCon,'Units', 'normalized','Position',[0 0 1 1])
    handles.mTree.setSelectedNode( handles.rootNode );
    nodes = handles.mTree.getSelectedNodes;
    parent = nodes(1);
    childNode = uitreenode('v0','Subject', 'Sub', [], 0);
    handles.treeModel.insertNodeInto(childNode,parent,parent.getChildCount());
    handles.mTree.setSelectedNode( childNode );
    handles.mTree.setSelectedNode( parent );
    set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles})
    guidata(hObject, handles);
     
    function NodeSelectedCallback (hObject, eventdata, handles)
     
    gcf
     
    function varargout = treetest_OutputFcn(hObject, eventdata, handles) 
     
    varargout{1} = handles.output;

    function varargout = treetest(varargin) gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @treetest_OpeningFcn, ... 'gui_OutputFcn', @treetest_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end function treetest_OpeningFcn(hObject, eventdata, handles, varargin) import javax.swing.* import javax.swing.tree.*; handles.output = hObject; handles.rootNode = uitreenode('v0', 'root', 'ConnectomeVis', [], 0); handles.treeModel = DefaultTreeModel( handles.rootNode ); [handles.mTree, handles.TreeCon] = uitree('v0','Root',handles.rootNode); handles.mTree.setModel( handles.treeModel ); set (handles.TreeCon,'Units', 'normalized','Position',[0 0 1 1]) handles.mTree.setSelectedNode( handles.rootNode ); nodes = handles.mTree.getSelectedNodes; parent = nodes(1); childNode = uitreenode('v0','Subject', 'Sub', [], 0); handles.treeModel.insertNodeInto(childNode,parent,parent.getChildCount()); handles.mTree.setSelectedNode( childNode ); handles.mTree.setSelectedNode( parent ); set(handles.mTree, 'NodeSelectedCallback', {@NodeSelectedCallback,handles}) guidata(hObject, handles); function NodeSelectedCallback (hObject, eventdata, handles) gcf function varargout = treetest_OutputFcn(hObject, eventdata, handles) varargout{1} = handles.output;

    • Yair Altman May 30, 2011 at 12:35 Reply

      @Johnson – gcf only returns the current figure if its HandleVisibility property is ‘on’. Otherwise, it skips this figure and if no other figure is open that has HandleVisibility=’on’, then gcf will simply create a new (empty) figure.

      To solve this, you have several choices:

      1. Set your figure’s HandleVisibility property to ‘on’
      2. Run set(0,’ShowHiddenHandles’,’on’) – (the default is ‘off’)
      3. Use gcbf instead of gcf

  13. Mola March 6, 2012 at 09:00 Reply

    Hi,
    is there a way to add additional informations to the tree? Something columnwise like it is in a file browser: 1st column = filenames, 2nd column: file size, 3rd column: modification date…
    Regards,
    Mola

    • Yair Altman March 6, 2012 at 09:09 Reply

      @Mola – yes: you can use com.jidesoft.grid.TreeTable for this. JIDE components are discussed in several places in this blog and in section 5.7 of my Matlab-Java book, although TreeTable is not extensively covered in either of them. In fact, PropertyTable is a specialized class of TreeTable that only has two columns (the property name and its value), and this is extensively covered both in this blog and the book. If you want to use TreeTable, you will need to use the JIDE-grids programmer’s guide for more information.

  14. sebbo April 2, 2012 at 02:40 Reply

    Hi,

    if possible I’d like to use drag & drop to move nodes from one tree to another.
    I partly suceeded using drag&drop within two trees with to code below.
    With the nodeDraggedCallback as is, any dragged node is simply added to the dropped-over node.

    This however stops working as soon as I try to drag a node from tree1 to tree2.
    The drop than results in matlab dropping the node that was last selected in tree2.

    Is there a callback or similar possibility to set the “drop-data” for a jtree manually?

    Glad about any help,
    sebbo

    mtree1.setDndEnabled(true);
    mtree2.setDndEnabled(true);
     
    set([mtree1, mtree2], 'NodeDroppedCallback', @nodeDroppedCallback);
     
    function nodeDroppedCallback( tree, nodeDroppedEvt )
    draggedNode = nodeDroppedEvt.getSourceNode().clone();
    targetNode  = nodeDroppedEvt.getTargetNode();
     
    targetNode.add(draggedNode);
    fprintf('adding node %s to %sn', char(draggedNode.getName()),  char(targetNode.getName()));
    tree.expand( targetNode );
    tree.getModel().nodeStructureChanged( targetNode );

    mtree1.setDndEnabled(true); mtree2.setDndEnabled(true); set([mtree1, mtree2], 'NodeDroppedCallback', @nodeDroppedCallback); function nodeDroppedCallback( tree, nodeDroppedEvt ) draggedNode = nodeDroppedEvt.getSourceNode().clone(); targetNode = nodeDroppedEvt.getTargetNode(); targetNode.add(draggedNode); fprintf('adding node %s to %sn', char(draggedNode.getName()), char(targetNode.getName())); tree.expand( targetNode ); tree.getModel().nodeStructureChanged( targetNode );

  15. yh November 27, 2012 at 11:39 Reply

    how to display all the first leval nodes by default(without clicking)

  16. uiinspect | Undocumented Matlab January 24, 2013 at 07:39 Reply

    […] I have chosen to use the built-in component com.mathworks.hg.peer.UITreePeer that underlies the built-in uitree function. […]

  17. CJ March 21, 2013 at 10:05 Reply

    Yair-
    Thanks so much for your great website, I use it extensively,
    simple question,
    Is there a way to change the displayed name of the root object when using uitree with a file system folder without using uitreenode and having to create the expand functions. I basically want the automatic functionality created by the example below but I want a different Name displayed so the user does not see the entire folder path..?
    ex: [mtree, container] = uitree(‘v0’, ‘Root’,’C:\’);
    Thanks very much,
    CJ

    • Yair Altman March 21, 2013 at 10:33 Reply

      @CJ – you can point the root to a different path (e.g., ‘C:\Yair\’).

      If you wish to modify the root node (name, icon etc.) you can use the direct reference mtree.Root. For example:

      mtree.Root.setName('Root node');
      mtree.Tree.repaint;

      mtree.Root.setName('Root node'); mtree.Tree.repaint;

      You can automatically expand the Root node as follows:

      mtree.Tree.expandRow(0);

      mtree.Tree.expandRow(0);

      More alternatives for controlling and customizing the uitree can be found in section 4.2 of my Matlab-Java programming book.

  18. Peke Pexon April 22, 2013 at 00:16 Reply

    I updated to Matlab 2013a and after that my tree will appear in a very, very small window. Is there any way I can affect the size of the uitree window?

    • Yair Altman April 22, 2013 at 00:27 Reply

      @Peke – you can set the uitree’s parent container’s Position property to any large position vector that you like. See the top of the article on this page.

  19. Mohammad May 21, 2013 at 05:31 Reply

    Hi Yair,

    I would appreciate if you can tell me how to update size and the position of a uitree embedded in a guide GUI, when the guided GUI resize behavior is proportional.

    Thank you.

    Regards,
    Mohammad

    • Yair Altman May 28, 2013 at 17:42 Reply

      @Mohammad – update the mtree‘s Units and Position properties (example).

  20. treeTable | Undocumented Matlab August 6, 2013 at 01:09 Reply

    […] in a table control that can be used in Matlab GUI. Such a control, which is a combination of a uitree and uitable, is typically called a tree-table. We can find numerous examples of it in everyday […]

  21. Daniel J August 8, 2013 at 01:38 Reply

    Hi Yair,

    First of all, awesome post, it’s been incredibly useful, and also thanks to everyone who’s posted such useful questions too!

    I have a quick one, is there any way of saving the created tree and its nodes in a *.mat file without loosing the javahandle properties? I’m storing all components in a structure for future callback, but when I save said structure it warns me that it can’t serialize the objects… what I’m trying to do is a ‘save/load project’ function and I’d like the user to be able to store everything in the tree and then load it back after closing the gui.

    Thanks beforehand for your valuable response!

    Daniel

    • Yair Altman August 8, 2013 at 01:39 Reply

      @Daniel – I am not aware of any direct way of doing this (which does not say that there isn’t any, only that at the moment I can’t think of one…)

    • Malcolm Lidierth August 8, 2013 at 05:05 Reply

      @Daniel

      I faced a similar issue saving MATLAB figures containing Java Swing components. The problem is that the MAT-file format does not support serialisation of most Java objects, while the standard Java bean encoder does not support MATLAB.

      JTree, like all Swing components has the following warning in its docs:

      Warning: Serialized objects of this class will not be compatible with future Swing releases. The current serialization support is appropriate for short term storage or RMI between applications running the same version of Swing. As of 1.4, support for long term storage of all JavaBeansTM has been added to the java.beans package. Please see XMLEncoder.

      The solution I used was to create 2 files in a folder:
      [1] an XML file using java.bean.XMLEncoder for Java objects (a package like xstream could also be used). Java-containing property fields are set empty after saving.
      [1] a MAT-file with properties containing MATLAB contents. As all Java objects are removed at step 1 – no exceptions get thrown.

      Reload by loading the MAT-file then setting the Java properties from the XML file.

      At least when nested fields are all MATLAB or all Java the two serialization steps should then be fairly automatic – xstream might save some work there compared to the bean encoder which needs persistence delegates to be added.

      An alternative might be to convert all fields to Java and save as XML- but then you need to save info about which to convert back.

    • Daniel J September 2, 2013 at 03:46 Reply

      @ Malcolm

      Thank you for your reply! I’d like to try that solution, while Mathworks decides to provide more support for this function… However I’m not completely familiar with encoding java objects, I hope I’m not being a pest if I ask you if you could be so kind of giving me a little example.. Your response is highly appreciated!

  22. Domenico August 12, 2013 at 03:47 Reply

    Hello Yair,

    I have a “node” given by the “uitreenode” function. With “mtree” by “uitree” function I am able to simply expand the nodes with:

    mtree.expand(node)

    mtree.expand(node)

    But before expanding I would like to know if the node is already expanded. With “jtree” there is a function “isExpanded” which does not exist with “uitree” unfortunately. And even the following does not work:

    mtree.tree.isExpanded(node)

    mtree.tree.isExpanded(node)

    as a “UITreeNode” is not accepted by “isExpanded” but a “TreePath”, and I am not able to convert it to it.

    Any ideas how I can solve the problem?

    Thanks and regards,
    Domenico

    • Yair Altman August 12, 2013 at 03:55 Reply

      @Domenico – I think that jPath = javax.swing.tree.TreePath(node.getPath) should return the TreePath object that you need.

    • Domenico August 14, 2013 at 06:35 Reply

      Great! That was the solution. Thank you very much Yair!

      Cheers,
      Domenico

  23. Leif I. Myklebust August 31, 2013 at 13:39 Reply

    Hi.
    Thanks for this excellent website (as well as your book)
    Quick question:
    I have a lazy loaded uitree, where the icon colors are dependent on the status of nodes downwards in the hierarchy.
    When the status changes, I basically want the tree to “forget” abaout all earlier expanded branches in the tree, i.e. to re-execute the nodeExpandedFunction when I expand the tree…

  24. MICHELE December 22, 2013 at 09:10 Reply

    Hello
    I’m working on a GUI which simply includes a graphical area and a tree.
    I’m using uisplitpane by Y.Altman and uipanel and uitab from undocumented matlab functions.
    The tree is generated within a tab.
    I get no error when running my script but I cannot see the tree correctly within the tab if I try to move panes or resize the figure. It seems it is independent from the panel which is its parent.
    See the example below.
    I also followed this tread https://www.mathworks.com/matlabcentral/newsreader/view_thread/268477 but I’m unable to find a solution as I’m not expert in programming. I

    • MICHELE December 22, 2013 at 09:14 Reply

      Can anyone help me please?

      here is the code:

      h = figure('Units','normalized','Position',[.1 .1 .3 .5],'Name','MyGUI',...
      'dockcontrol','off','menubar','figure');
       
      % Split figure
      [hDown,hUp,hDiv1]=uisplitpane(h,'Orientation','ver');
      hDiv1.DividerLocation = 0.3;
       
      % Split again
      [hLeft,hRight,hDiv2]=uisplitpane(hUp,'Orientation','hor');
      hDiv2.DividerLocation = 0.4;
      drawnow
       
      % Create panel for each subfigure
      hp1 = uipanel('Parent',hLeft,'Title','Panel 1','FontSize',7,...
      'Units', 'normalized','Position',[0 0 1 1]);
      hp2 = uipanel('Parent',hRight,'Title','Panel 2','FontSize',7,...
      'Units', 'normalized','Position',[0 0 1 1]);
      hp3 = uipanel('Parent',hDown,'Title','Plot Area','FontSize',7,...
      'Units', 'normalized','Position',[0 0 1 1]);
       
      % Generate plot sample
      t=0:.1:10; hax1=axes('Parent',hp3); plot(t,sin(t)); title('SIN(X)');
       
      % Add Tabs
      hTabGroup = uitabgroup(hp1);
      tab1 = uitab(hTabGroup,'title','Tree 1');
      tab2 = uitab(hTabGroup,'title','Tree 2');
      % Add panel to each tab
      hp4 = uipanel('Parent',tab1,...
      'Units','normalized','Position',[0 0 1 1]); % panel in tab1
      hp5 = uipanel('Parent',tab2,...
      'Units','normalized','Position',[0 0 1 1]); % panel in tab2
      set(hTabGroup,'SelectedTab',tab1);
       
      %% TREE
      % Fruits
      fruits = uitreenode('v0', 'Fruits', 'Fruits', [], false);
      fruits.add(uitreenode('v0', 'Apple', 'Apple', [], true));
      fruits.add(uitreenode('v0', 'Pear', 'Pear', [], true));
      % Vegetables
      veggies = uitreenode('v0', 'Veggies', 'Vegetables', [], false);
      veggies.add(uitreenode('v0', 'Potato', 'Potato', [], true));
      veggies.add(uitreenode('v0', 'Tomato', 'Tomato', [], true));
      % Root node
      root = uitreenode('v0', 'Food', 'Food', [], false);
      root.add(veggies);
      root.add(fruits);
       
      [mtree, container] = uitree('v0', 'Root', root);
      set(container,'Parent',hp4)
      set(container,'Units','normalized','Position', [0 0 1 1]);

      h = figure('Units','normalized','Position',[.1 .1 .3 .5],'Name','MyGUI',... 'dockcontrol','off','menubar','figure'); % Split figure [hDown,hUp,hDiv1]=uisplitpane(h,'Orientation','ver'); hDiv1.DividerLocation = 0.3; % Split again [hLeft,hRight,hDiv2]=uisplitpane(hUp,'Orientation','hor'); hDiv2.DividerLocation = 0.4; drawnow % Create panel for each subfigure hp1 = uipanel('Parent',hLeft,'Title','Panel 1','FontSize',7,... 'Units', 'normalized','Position',[0 0 1 1]); hp2 = uipanel('Parent',hRight,'Title','Panel 2','FontSize',7,... 'Units', 'normalized','Position',[0 0 1 1]); hp3 = uipanel('Parent',hDown,'Title','Plot Area','FontSize',7,... 'Units', 'normalized','Position',[0 0 1 1]); % Generate plot sample t=0:.1:10; hax1=axes('Parent',hp3); plot(t,sin(t)); title('SIN(X)'); % Add Tabs hTabGroup = uitabgroup(hp1); tab1 = uitab(hTabGroup,'title','Tree 1'); tab2 = uitab(hTabGroup,'title','Tree 2'); % Add panel to each tab hp4 = uipanel('Parent',tab1,... 'Units','normalized','Position',[0 0 1 1]); % panel in tab1 hp5 = uipanel('Parent',tab2,... 'Units','normalized','Position',[0 0 1 1]); % panel in tab2 set(hTabGroup,'SelectedTab',tab1); %% TREE % Fruits fruits = uitreenode('v0', 'Fruits', 'Fruits', [], false); fruits.add(uitreenode('v0', 'Apple', 'Apple', [], true)); fruits.add(uitreenode('v0', 'Pear', 'Pear', [], true)); % Vegetables veggies = uitreenode('v0', 'Veggies', 'Vegetables', [], false); veggies.add(uitreenode('v0', 'Potato', 'Potato', [], true)); veggies.add(uitreenode('v0', 'Tomato', 'Tomato', [], true)); % Root node root = uitreenode('v0', 'Food', 'Food', [], false); root.add(veggies); root.add(fruits); [mtree, container] = uitree('v0', 'Root', root); set(container,'Parent',hp4) set(container,'Units','normalized','Position', [0 0 1 1]);

  25. Yuval Cohen February 23, 2014 at 23:35 Reply

    Hello,
    I was wondering if there is a simple method to move a node up and down the tree (place it above its sibling for example) or change it’s parent such that it is one level higher or lower.

    Thanks,
    Yuval

    P.S. Great web site.

    • Yair Altman February 24, 2014 at 01:35 Reply

      @Yuval – here’s a simple example:

      node      = mtree.getTree.getPathForRow(8).getLastPathComponent;  % original row = 8+1=9
      newParent = mtree.getTree.getPathForRow(4).getLastPathComponent;  % target row = below 4+1=5
      mtree.getModel.removeNodeFromParent(node);
      mtree.getModel.insertNodeInto(node, newParent, 0);

      node = mtree.getTree.getPathForRow(8).getLastPathComponent; % original row = 8+1=9 newParent = mtree.getTree.getPathForRow(4).getLastPathComponent; % target row = below 4+1=5 mtree.getModel.removeNodeFromParent(node); mtree.getModel.insertNodeInto(node, newParent, 0);

  26. Carla March 20, 2014 at 13:16 Reply

    Hi Yair,

    First of all, thank you so much for this blog and your book. In the last few days they have been instrumental. I have been working with uitree and trying to incorporate it into my own version of Matlab’s “Find Files” tool. Uitree is amazing for grabbing a directory and displaying its contents. What I cannot seem to figure out for the life of me is how to get the selection the user makes in the uitree back into the GUI to allow for use as a variable in the rest of the function. I’ve tried setting up callback functions similar to the above and some other things I found on google. Do you have any recommendations as to how I could go about doing this? (My alternative is to rewrite the program from scratch and just not use uitree. But it would be so much cooler if I could get this to work.) Thanks so much for any advice/recommendations.

    Very Respectfully,
    Carla

    • Yair Altman March 20, 2014 at 13:20 Reply

      @Carla – this is explained in the following articles of the uitree miniseries, as well as in my book (section 4.2).

  27. Forrest June 3, 2014 at 15:13 Reply

    Hi Yair,

    As everyone else has said, this website is a wonderful resource. I’ll be sure to check out your book too.

    I’ve looked through the uitree miniseries, but I’m having a little trouble getting my entire tree to expand. I’ve made too many attempts to remember them all, but they include:

    tree.expand;
    for i = 1:root.getChildCount()
    tree.expand(tree.Name(i));
    end
    for i = 1:root.getChildCount()
    tree.expand(i));
    end
    for i = 1:root.getChildCount()
    tree.setSelectedNode(i));
    end
    tree.expandRow();
    root.expandRow();
    root.expandRow(2); % It was a full loop

    tree.expand; for i = 1:root.getChildCount() tree.expand(tree.Name(i)); end for i = 1:root.getChildCount() tree.expand(i)); end for i = 1:root.getChildCount() tree.setSelectedNode(i)); end tree.expandRow(); root.expandRow(); root.expandRow(2); % It was a full loop

    Unfortunately, none of these work, and most of these methods aren’t found by Matlab. How can I expand an entire tree?

    Additionally, I’ve been having some difficulty with drag and dropping multiple nodes into another node. I can select multiple nodes and I can drag and drop a single node into another node, but when I select multiple nodes and try dropping them into another node, only one of them is added. The code I’m using is below and obviously getSourceNode() only gets a single source node. Is it possible to get multiple source nodes and add each of them?

    tree = uitree('v0','Root',root);
    set(tree,'MultipleSelectionEnabled',1);
    tree.setDndEnabled(true);
    set(ctree,'NodeDroppedCallback',@nodeDroppedCallback);
     
    function nodeDroppedCallback( tree, nodeDroppedEvt )
    draggedNode = nodeDroppedEvt.getSourceNode();
    targetNode  = nodeDroppedEvt.getTargetNode(); 
    targetNode.add(draggedNode);
    tree.reloadNode(tree.getRoot);  
    tree.expand(tree.getRoot);
    tree.expand(targetNode);
    tree.getModel().nodeStructureChanged( targetNode );

    tree = uitree('v0','Root',root); set(tree,'MultipleSelectionEnabled',1); tree.setDndEnabled(true); set(ctree,'NodeDroppedCallback',@nodeDroppedCallback); function nodeDroppedCallback( tree, nodeDroppedEvt ) draggedNode = nodeDroppedEvt.getSourceNode(); targetNode = nodeDroppedEvt.getTargetNode(); targetNode.add(draggedNode); tree.reloadNode(tree.getRoot); tree.expand(tree.getRoot); tree.expand(targetNode); tree.getModel().nodeStructureChanged( targetNode );

    • Forrest June 4, 2014 at 10:51 Reply

      Actually, since yesterday I’ve been able to solve both of these problems, but in doing so I’ve introduced another. I now import javax.swing.tree.*; and create the treeModel and tree a little differently. Now when nodes have no children there is no unnecessary little expansion button next to them.

      Additionally, I realized I could simply loop through the selected nodes and move them one at a time. Unfortunately, the ‘add’ function doesn’t seem to be working as documented. I interpretted ‘targetNode.add(draggedNode)’ to effectively move draggedNode to become a child of targetNode. Instead, draggedNode is becoming a child of targetNode but the original draggedNode is remaining when it’s supposed to be removed from its previous parent.

      I’ve tried programatically selecting nodes and expanding nodes and reloading nodes, but none of these have fixed the problem. Below is the new callback function I’m using when a group of nodes is dragged and dropped.

      % --- Executes on drag and drop in tree.
      function nodeDroppedCallback(tree, nodeDroppedEvt)
      targetNode  = nodeDroppedEvt.getTargetNode();
      draggedNodes = tree.getSelectedNodes;
       
      for i = 1:length(draggedNodes)
      targetNode.add(draggedNodes(i));
      tree.reloadNode(draggedNodes(i));
      tree.expand(targetNode);
      tree.setSelectedNode(draggedNodes(i));
      end    
       
      tree.getModel().nodeStructureChanged(targetNode);

      % --- Executes on drag and drop in tree. function nodeDroppedCallback(tree, nodeDroppedEvt) targetNode = nodeDroppedEvt.getTargetNode(); draggedNodes = tree.getSelectedNodes; for i = 1:length(draggedNodes) targetNode.add(draggedNodes(i)); tree.reloadNode(draggedNodes(i)); tree.expand(targetNode); tree.setSelectedNode(draggedNodes(i)); end tree.getModel().nodeStructureChanged(targetNode);

    • Forrest June 5, 2014 at 08:59 Reply

      So… I’ve fixed the updating issue. The problem was that I was using reloadNode() on the dragged node when I should be using it on the (previous) parent node of the dragged node.

      The nodeDropped callback function now looks like this:

      function nodeDroppedCallback(tree, nodeDroppedEvt)
      targetNode  = nodeDroppedEvt.getTargetNode();
      draggedNodes = tree.getSelectedNodes;
      for i = 1:length(draggedNodes)
      % Get past parent of node that's being dragged
      parent = draggedNodes(i).getParent();
      % Move draggedNode to targetNode
      targetNode.add(draggedNodes(i));
      % Reload the old parent node of draggedNode
      tree.reloadNode(parent);
      % Expand targetNode
      tree.expand(targetNode);
      end    
      tree.getModel().nodeStructureChanged(targetNode);

      function nodeDroppedCallback(tree, nodeDroppedEvt) targetNode = nodeDroppedEvt.getTargetNode(); draggedNodes = tree.getSelectedNodes; for i = 1:length(draggedNodes) % Get past parent of node that's being dragged parent = draggedNodes(i).getParent(); % Move draggedNode to targetNode targetNode.add(draggedNodes(i)); % Reload the old parent node of draggedNode tree.reloadNode(parent); % Expand targetNode tree.expand(targetNode); end tree.getModel().nodeStructureChanged(targetNode);

      Unfortunately, this has brought me back to the previous issue: whenever I drag and drop a new node, the rest of the tree’s nodes collapse. Is there a quick way to expand all of the tree nodes?

      • Yair Altman June 5, 2014 at 09:04

        @Forrest, try this:

        com.jidesoft.tree.TreeUtils.expandAll(jtree);

        com.jidesoft.tree.TreeUtils.expandAll(jtree);

      • Forrest June 5, 2014 at 12:30

        Unfortunately I get

        No method 'expandAll' with matching signature found for class 'com.jidesoft.tree.TreeUtils'.

        No method 'expandAll' with matching signature found for class 'com.jidesoft.tree.TreeUtils'.

        the tree that I pass to this function is

        javahandle_withcallbacks.com.mathworks.hg.peer.UITreePeer

        javahandle_withcallbacks.com.mathworks.hg.peer.UITreePeer

        I have seen I can create a jtree with

        jtree = handle(ctree.getTree,'CallbackProperties');

        jtree = handle(ctree.getTree,'CallbackProperties');

        where ctree is my uitree, but should I be doing something with this jtree?

      • Yair Altman June 5, 2014 at 23:24

        As I wrote above, expandAll() expects a jtree parameter, not a uitree (UITreePeer).

    • Forrest June 6, 2014 at 11:52 Reply

      Even if I try accessing the jtree that I create in my OpeningFcn through handles, I get an error. Can I convert the UITreePeer into a jtree just for the expandAll() command?

      Thanks so much

  28. Daniel December 23, 2014 at 23:14 Reply

    Hello Yair,

    I created a uitree in my GUIDE created UI:

    % --- Executes just before ImageSearchDialog is made visible.
    function ImageSearchDialog_OpeningFcn(hObject, eventdata, handles, varargin)
    % This function has no output args, see OutputFcn.
    % hObject    handle to figure
    % eventdata  reserved - to be defined in a future version of MATLAB
    % handles    structure with handles and user data (see GUIDATA)
    % varargin   command line arguments to ImageSearchDialog (see VARARGIN)
     
    % Choose default command line output for ImageSearchDialog
    handles.output = hObject;
     
    % Update handles structure
    handles.root = uitreenode('v0', 'root', 'Study Root', [], false);
    [handles.mtree1, handles.mtree1Con] = uitree('v0','Root', handles.root);
    handles.mtree1.Position = [20,20,1350,550];
    handles.mtree1.expand(handles.root)
    guidata(hObject, handles);

    % --- Executes just before ImageSearchDialog is made visible. function ImageSearchDialog_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to ImageSearchDialog (see VARARGIN) % Choose default command line output for ImageSearchDialog handles.output = hObject; % Update handles structure handles.root = uitreenode('v0', 'root', 'Study Root', [], false); [handles.mtree1, handles.mtree1Con] = uitree('v0','Root', handles.root); handles.mtree1.Position = [20,20,1350,550]; handles.mtree1.expand(handles.root) guidata(hObject, handles);

    And I also created a function, which should create my tree:

    function createUItree(result, retrieveLevel, pb, handles)
    switch retrieveLevel
    case 'STUDY'
    for i = 1:numel(result)
    patientID = result(i).patientID;
    patientName = result(i).patientName;
    patientBirthdate = result(i).patientBirthdate;
    studyInstanceUID = result(i).studyInstanceUID;
    studyDescription = result(i).studyDescription;
    accessionNumber = result(i).accessionNumber;
    nodePatient = [patientName,'  *',patientBirthdate,'  ',studyDescription,'  ',patientID,'  ',studyInstanceUID,'  ',accessionNumber];
    patientNode(i) = uitreenode('v0',patientID ,nodePatient ,[], false);
     
    handles.root.add(patientNode(i));
    end
    (...more code...)

    function createUItree(result, retrieveLevel, pb, handles) switch retrieveLevel case 'STUDY' for i = 1:numel(result) patientID = result(i).patientID; patientName = result(i).patientName; patientBirthdate = result(i).patientBirthdate; studyInstanceUID = result(i).studyInstanceUID; studyDescription = result(i).studyDescription; accessionNumber = result(i).accessionNumber; nodePatient = [patientName,' *',patientBirthdate,' ',studyDescription,' ',patientID,' ',studyInstanceUID,' ',accessionNumber]; patientNode(i) = uitreenode('v0',patientID ,nodePatient ,[], false); handles.root.add(patientNode(i)); end (...more code...)

    I have the feeling, that I miss to call a function to update my tree. So my question is, what is missing to complete my code, that it works.

    Best Regards

    Daniel

    • Yair Altman December 24, 2014 at 06:48 Reply

      @Daniel – you did not specify what exactly is wrong, but perhaps you are not calling your createUITree function from your main code. Anyway, if you’d like me to fix your specific program, I’d be happy to do it for a small consulting fee – send me an email and I will try to help.

    • Daniel December 27, 2014 at 11:17 Reply

      Hi, i could solve it with

      reloadNode(root)

      reloadNode(root)

      . This was the function to update the tree. But i have to say, now i have problems with this part of your article

      mtree.setSelectedNodes([root,node1,node2]);  % select 3 nodes

      mtree.setSelectedNodes([root,node1,node2]); % select 3 nodes

      .

      In my source code, he just select the first entry

      function [ output_args ] = mySelectFcn( tree, value )
      selectedNodes = tree.getSelectedNodes;
      if ~isempty(selectedNodes)
      level = selectedNodes(1).getLevel;
      if level == 2
      node = selectedNodes(1);
      %numChilds = node.getChildCount();
       
      %for i = 1:numChilds
      %childNode(i) =  child;
      % end
       
      %tree.setSelectedNodes(childNode);
       
      child1 = node.getChildAt(0);
      child2 = node.getChildAt(1);
      child3 = node.getChildAt(2);
      tree.setSelectedNodes([child1,child2,child3]);              
      end
      end
      end

      function [ output_args ] = mySelectFcn( tree, value ) selectedNodes = tree.getSelectedNodes; if ~isempty(selectedNodes) level = selectedNodes(1).getLevel; if level == 2 node = selectedNodes(1); %numChilds = node.getChildCount(); %for i = 1:numChilds %childNode(i) = child; % end %tree.setSelectedNodes(childNode); child1 = node.getChildAt(0); child2 = node.getChildAt(1); child3 = node.getChildAt(2); tree.setSelectedNodes([child1,child2,child3]); end end end

      I really don t know why (Multiselection is enabled) lol I am a student and this work is for my Bachelor’s Degree πŸ˜€

    • Daniel December 27, 2014 at 11:55 Reply

      i found the mistake. mtree.setMultipleSelectionEnabled(true) don’t work. It works with mtree.MultipleSelectionEnabled=true;

      Best Regards and a happy new year πŸ˜€

  29. Hoby Ratefy March 6, 2015 at 02:26 Reply

    Hello everyone,
    I’m delighted to find commands to create trees easily in MATLAB without using Java, many thanks Yair !
    I’m designing a tree in a Matlab program, and I’m searching through the commands to find a node’s information. I’ve found commands such as getChildCount, getLevel, getName, getValue that return results (doubles or strings), but there’s one I’m struggling with, and I believe it would be very useful if I could get it to work, it’s getIndex. It returns nothing, could you help me please ?
    Many thanks !

  30. amin October 28, 2015 at 08:49 Reply

    hi….thank u ur very mach usefull web site ….really really
    u can help me ,,how i rtl my uitree in matlab

    thank for all

  31. hi October 28, 2015 at 18:00 Reply

    how i inverse orientation of my uitree:from left t right 2 right to left …plz help me

  32. Yasser ElNemr June 29, 2016 at 16:40 Reply

    Hallo ,
    Thanks for the great work. i used it in several applications and it is working perfectly.

    However in my current application i need the root node to point to a specific folder which has some sub-folders (up to 9 levels of sub-folders)

    Thanks

  33. Geert van Kempen January 12, 2018 at 23:09 Reply

    Would anybody know how I can use a Fixed Width font in a uitreenode?

    • Yair Altman January 13, 2018 at 17:53 Reply

      Set the node’s label to an HTML fixed-width font, for example: '<html><pre>tree node label</pre>'

  34. OrO July 24, 2018 at 11:04 Reply

    I would like to know if there are any limitations with MATLAB Compiler. I think it should work but I just want to be sure.

    • Yair Altman July 24, 2018 at 11:13 Reply

      @Oro – I don’t believe there are any limitations, but don’t take my word for it – simply compile and test! – it’s much faster to test it yourself than to wait for an answer on a public blog…

  35. Zahraa December 10, 2018 at 08:17 Reply

    Hello, I want the root node to be a folder selected form the hard drive and to open its content (subfolders and files) in a tree, so I tried using uigetdir as an input argument for the uitreenode. It displays it on the figure as the root node but does not open the subfolders and files located in it. How can I be able to open the folder?
    Any help appreciated.

    • Yair Altman December 10, 2018 at 19:49 Reply

      Follow the code in the article to select and display the root note, and then simply double-click the root node to open its sub-folders.

  36. Zahraa December 12, 2018 at 15:33 Reply

    When I run:
    tree = uitree(‘v0’, ‘Root’,uigetdir, ‘Parent’, []);
    I am able to select the folder from the computer and it is set as the root folder. I click on the root and the files and subfolders open, however when I click on the subfolders they do not open and the plus on the side just disappears. Is there a way to open them recursively? Thank you.

  37. SOULEYMANE Zakaria June 28, 2022 at 11:46 Reply

    Hello.

    Thank you for sharing. I would like to know if someone could help me with the syntax it takes to use uitree on “Appdesigner”.

    When I use the syntax you have indicated above, it opens a .fig window (where the tree appears) in addition to the Appdesigner window (The tree does not appear). I tried several combinations of code but it didn’t work. I hope someone can help me out.

    Thanks in advance …

    • Yair Altman July 3, 2022 at 17:17 Reply

      See the documentation of the uitree function. The text in my article refers to the legacy (Java-based) uitree version, which is not documented, whereas it is documented and supported (with slightly different syntax) for web-based figures (uifigure and figures created by App Designer).

Leave a Reply
HTML tags such as <b> or <i> are accepted.
Wrap code fragments inside <pre lang="matlab"> tags, like this:
<pre lang="matlab">
a = magic(3);
disp(sum(a))
</pre>
I reserve the right to edit/delete comments (read the site policies).
Not all comments will be answered. You can always email me (altmany at gmail) for private consulting.

Click here to cancel reply.

Useful links
  •  Email Yair Altman
  •  Subscribe to new posts (feed)
  •  Subscribe to new posts (reader)
  •  Subscribe to comments (feed)
 
Accelerating MATLAB Performance book
Recent Posts

Speeding-up builtin Matlab functions – part 3

Improving graphics interactivity

Interesting Matlab puzzle – analysis

Interesting Matlab puzzle

Undocumented plot marker types

Matlab toolstrip – part 9 (popup figures)

Matlab toolstrip – part 8 (galleries)

Matlab toolstrip – part 7 (selection controls)

Matlab toolstrip – part 6 (complex controls)

Matlab toolstrip – part 5 (icons)

Matlab toolstrip – part 4 (control customization)

Reverting axes controls in figure toolbar

Matlab toolstrip – part 3 (basic customization)

Matlab toolstrip – part 2 (ToolGroup App)

Matlab toolstrip – part 1

Categories
  • Desktop (45)
  • Figure window (59)
  • Guest bloggers (65)
  • GUI (165)
  • Handle graphics (84)
  • Hidden property (42)
  • Icons (15)
  • Java (174)
  • Listeners (22)
  • Memory (16)
  • Mex (13)
  • Presumed future risk (394)
    • High risk of breaking in future versions (100)
    • Low risk of breaking in future versions (160)
    • Medium risk of breaking in future versions (136)
  • Public presentation (6)
  • Semi-documented feature (10)
  • Semi-documented function (35)
  • Stock Matlab function (140)
  • Toolbox (10)
  • UI controls (52)
  • Uncategorized (13)
  • Undocumented feature (217)
  • Undocumented function (37)
Tags
AppDesigner (9) Callbacks (31) Compiler (10) Desktop (38) Donn Shull (10) Editor (8) Figure (19) FindJObj (27) GUI (141) GUIDE (8) Handle graphics (78) HG2 (34) Hidden property (51) HTML (26) Icons (9) Internal component (39) Java (178) JavaFrame (20) JIDE (19) JMI (8) Listener (17) Malcolm Lidierth (8) MCOS (11) Memory (13) Menubar (9) Mex (14) Optical illusion (11) Performance (78) Profiler (9) Pure Matlab (187) schema (7) schema.class (8) schema.prop (18) Semi-documented feature (6) Semi-documented function (33) Toolbar (14) Toolstrip (13) uicontrol (37) uifigure (8) UIInspect (12) uitable (6) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
Contact us
Captcha image for Custom Contact Forms plugin. You must type the numbers shown in the image
Undocumented Matlab Β© 2009 - Yair Altman
This website and Octahedron Ltd. are not affiliated with The MathWorks Inc.; MATLAB® is a registered trademark of The MathWorks Inc.
Scroll to top