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

An interesting uitree utility

March 30, 2011 5 Comments

“uitree” is consistently one of the most-popular search terms on this site, together with “uitable” and “uitab”. I also receive frequent questions about tree components in Matlab.
I already wrote a series of articles on Matlab’s built-in semi-documented uitree (starting here), and I am on a constant lookout for additional interesting angles on uitree to post here. Brett Shoelson’s recent review of 2005’s Pick-of-the-Week utilities, provided me with such an opportunity.
One of 2005’s featured utilities, Structure Explorer by Hassan Lahdili, originally written using Microsoft’s TreeView ActiveX control, was apparently rewritten using Matlab’s Java-based uitree. This enables the utility to run on non-Windows platforms and have a more consistent look-and-feel with Matlab’s Java-based GUI:

Hassan Lahdili's Structure Explorer (click to enlarge)
Hassan Lahdili's Structure Explorer (click to enlarge)

Hassan’s ExploreStruct utility, in addition to being useful as-is, provides a very useful learning tool for uitree integration in Matlab GUI. This utility uses custom icons for different node types, custom callbacks for node expansion (NodeWillExpandCallback) and node selection (NodeSelectedCallback), and tree context (right-click) menu.
Unfortunately, it appears that the ExploreStruct utility has not been updated for compatibility with the latest Matlab releases. This causes numerous warning messages about not using ‘v0’ when calling uitree and uitreenode. I also had to add a call to drawnow following the uitree‘s creation in line #30, otherwise the tree did not appear (due to EDT issues). Also, I had to comment out line #83 (set(root,’UIContextMenu’, cmenu);) which caused an error (“There is no ‘UIContextMenu’ property in the ‘com.mathworks.hg.peer.UITreeNode’ class”) – the tree’s context-menu actually works even without this line.
Finally, I had to fix line #182 so that the node icons will appear correctly:

%pth = [matlabroot, '\work\exp_struct_icons\'];  %old
pth = [fileparts(which(mfilename)) '\exp_struct_icons\'];  %new

%pth = [matlabroot, '\work\exp_struct_icons\']; %old pth = [fileparts(which(mfilename)) '\exp_struct_icons\']; %new

ExploreStruct is not documented and does not have extensive error-checking that I would like to see in real-world applications. But it is relatively easy to read and understand due to its use of internal functions and meaningful variable names.
Altogether, aside from the minor nuances mentioned above, I believe that readers who are interested in implementing custom tree objects in their Matlab GUI can learn a lot from this utility, and you can easily adapt its code for your own needs (or if you can’t, I am always willing to help).

Related posts:

  1. Customizing uitree – This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  2. Customizing uitree nodes – part 2 – This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  3. uitree – This article describes the undocumented Matlab uitree function, which displays data in a GUI tree component...
  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. ScreenCapture utility – The ScreenCapture utility uses purely-documented Matlab for capturing a screen region as an image from within Matlab. ...
  6. 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....
GUI Java Semi-documented function uitools
Print Print
« Previous
Next »
5 Responses
  1. Aurélien April 4, 2011 at 01:03 Reply

    I often use this utility in my GUIs that I call directly from uimenu . It allows me to check very quickly the contents of my structures. I also added another cell in the right panel (like Name, Size , Class) to display the current value of selected item. Currently it is the best explorer of structure that I found on the FEX.

    I am not really surprised that uitable , uitree are the most-popular search terms. IMHO, these features should have been officially implemented and documented in a MATLAB release for a while since they are really helpful.

  2. Amir May 17, 2015 at 01:48 Reply

    Hello Yair,

    First your blog is really useful and helpful.
    I’m working on a GUI that contain a uitree, now I wanted to export that uitree to enable user to save it to an external variable.
    but, there is known problem that the java class is not serializable.
    Now I’m try to use that uitree utility in order to convert a struct to a uitree, but the utility is not working. (I’m working with R2015a release)
    It getting me an error message:
    “Error using set
    The name ‘UserData’ is not an accessible property for an instance of class
    ‘com.mathworks.mwswing.MJScrollPane’.

    Error in explorestruct (line 37)
    set(tmp, ‘UserData’, cell_Data);”

    It looks like there is no ‘UserData’ field for MJScrollPane, do you know why this field is unavailable and how to solve it?

    • Yair Altman May 17, 2015 at 01:56 Reply

      MathWorks removed the UserData property (and some other generic properties such as ApplicationData) from Java components a few releases ago. In general, code that relies on undocumented features cannot be expected to work forever, it may indeed break in some future release.

      You will need to contact the utility’s creator to adapt it for new Matlab releases, or modify the relevant utility yourself, or hire a consultant to help you.

  3. Peter Cook October 4, 2017 at 02:09 Reply

    Yair,
    I wrote this to fill a need I’ve had for a lightweight “structure explorer” type utility that lets me navigate a struct quickly without the need to necessarily plot the data. I create the tree as I traverse the structure so I didn’t have to make an ExpandFcn/MousePressedCallback; I also wrote a version that expands all nodes initially but it can be a bit overwhelming for a broad or deep tree (e.g. a struct returned by xml2struct). Maybe you or someone reading this page will find this useful as the original utility doesn’t work in recent MATLAB releases.

    function mtree = mapStruct(s)
     
        hFig1 = figure('pos',[32,32,512,960]);
        hFig1.ToolBar = 'none';
        hFig1.MenuBar = 'none';
        hFig1.Name = 'Struct Explorer';
        hFig1.NumberTitle = 'off';
     
        root = uitreenode('v0','root','root',[],false);
        mtree = uitree('v0','Root',root,'Parent',hFig1);
     
        function structTraverse(s,node)
            f = fieldnames(s);
            %explore each field in the input struct s
            for kField = 1 : length(f)
                structField = s.(f{kField}); %structField = getfield(s,f{kField});
     
                %if struct field is a cell array of structs, convert to struct array IFF structs are identical
                if iscell(structField)
                    if all(cellfun(@isstruct,structField))
                        try
                            structField = [structField{:}];
                        catch
                            %add some sort of exception handling
                        end
                    end
                end
     
                %if the structure field is also a struct explore each field
                if isstruct(structField) %strcmp(structFieldClass,'struct')
                    %determine depth of struct field & enumerate if depth > 1
                    structDepth = length(structField);
                    if structDepth > 1
                        newNode = uitreenode('v0',f{kField},f{kField},[],false);
                        node.add(newNode);
                        %if the depth of the structure field is greater than 1
                        %add a blank parent node then add each layer/depth level as a node in the tree
                        for kLayer = 1:structDepth
                            nodeLayerName = sprintf('%s(%d)',f{kField},kLayer);
                            nextNode = uitreenode('v0', nodeLayerName,nodeLayerName,[],false);
                            newNode.add(nextNode);
                            structTraverse(structField(kLayer),nextNode)
                        end
                    else
                        %if the depth of the structure field is 1 add it as a node
                        nextNode = uitreenode('v0',f{kField},f{kField},[],false);
                        node.add(nextNode);
                        structTraverse(structField,nextNode)
                    end
                else
                    %make a node for the variable/attribute and display information about the variable
                    newNode = uitreenode('v0',f{kField},f{kField},[],false);
                    [nRow,nCol] = size(structField);
                    structFieldClass = class(structField);
                    if isempty(structField)
                        displayString = 'empty';
                    elseif nRow==1 && ischar(structField)
                        displayString = structField;
                    elseif nRow==1 && nCol==1 && any(strcmp(structFieldClass,{'single','double','logical'}))
                        displayString = sprintf('%f',structField);
                    else
                        displayString = sprintf('%dx%d %s',nRow,nCol,structFieldClass);
                    end
                    nextNode = uitreenode('v0',displayString,displayString,[],true);
                    newNode.add(nextNode);
                    node.add(newNode);
                end
            end
        end
     
        structTraverse(s,root)
        mtree.reloadNode(root)
        mtree.Position(3) = 512;
     
    end

    function mtree = mapStruct(s) hFig1 = figure('pos',[32,32,512,960]); hFig1.ToolBar = 'none'; hFig1.MenuBar = 'none'; hFig1.Name = 'Struct Explorer'; hFig1.NumberTitle = 'off'; root = uitreenode('v0','root','root',[],false); mtree = uitree('v0','Root',root,'Parent',hFig1); function structTraverse(s,node) f = fieldnames(s); %explore each field in the input struct s for kField = 1 : length(f) structField = s.(f{kField}); %structField = getfield(s,f{kField}); %if struct field is a cell array of structs, convert to struct array IFF structs are identical if iscell(structField) if all(cellfun(@isstruct,structField)) try structField = [structField{:}]; catch %add some sort of exception handling end end end %if the structure field is also a struct explore each field if isstruct(structField) %strcmp(structFieldClass,'struct') %determine depth of struct field & enumerate if depth > 1 structDepth = length(structField); if structDepth > 1 newNode = uitreenode('v0',f{kField},f{kField},[],false); node.add(newNode); %if the depth of the structure field is greater than 1 %add a blank parent node then add each layer/depth level as a node in the tree for kLayer = 1:structDepth nodeLayerName = sprintf('%s(%d)',f{kField},kLayer); nextNode = uitreenode('v0', nodeLayerName,nodeLayerName,[],false); newNode.add(nextNode); structTraverse(structField(kLayer),nextNode) end else %if the depth of the structure field is 1 add it as a node nextNode = uitreenode('v0',f{kField},f{kField},[],false); node.add(nextNode); structTraverse(structField,nextNode) end else %make a node for the variable/attribute and display information about the variable newNode = uitreenode('v0',f{kField},f{kField},[],false); [nRow,nCol] = size(structField); structFieldClass = class(structField); if isempty(structField) displayString = 'empty'; elseif nRow==1 && ischar(structField) displayString = structField; elseif nRow==1 && nCol==1 && any(strcmp(structFieldClass,{'single','double','logical'})) displayString = sprintf('%f',structField); else displayString = sprintf('%dx%d %s',nRow,nCol,structFieldClass); end nextNode = uitreenode('v0',displayString,displayString,[],true); newNode.add(nextNode); node.add(newNode); end end end structTraverse(s,root) mtree.reloadNode(root) mtree.Position(3) = 512; end

    • Yair Altman October 4, 2017 at 11:17 Reply

      @Peter – Thanks for sharing

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 (email)
  •  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
ActiveX (6) 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) uitools (20) Undocumented feature (187) Undocumented function (37) Undocumented property (20)
Recent Comments
  • Yair Altman (13 days 15 hours ago): @Veronica – you are using the new version of uitree, which uses HTML-based uifigures, and my post was about the Java-based uitree which uses legacy Matlab figures. For...
  • Veronica Taurino (13 days 15 hours ago): >> [txt1,txt2] ans = ‘abrakadabra’
  • Veronica Taurino (13 days 16 hours ago): Hello, I am just trying to change the uitree node name as you suggested: txt1 = 'abra'; txt2 = 'kadabra'; node.setName([txt1,txt2]); >> "Unrecognized method, property, or...
  • Yair Altman (16 days 16 hours ago): The version of JGraph that you downloaded uses a newer version of Java (11) than the one that Matlab supports (8). You need to either (1) find an earlier version of JGraph that...
  • mrv (16 days 20 hours ago): hello, I used MATLAB 2019b update9, I have add jgraphx.jar to javaclassapth, and restart matlab, but still got errors below: Warning: A Java exception occurred trying to load the...
  • xuejie wu (40 days 16 hours ago): Hi: I’m wondering if i can add my customized section or tab ?
  • Yair Altman (52 days 8 hours ago): @Sagar – use the view(az,el) function to rotate the 3D axes.
  • Sagar Chawla (52 days 8 hours ago): I want to know how to change the x-axis to the z-axis. I mean the position. Like if there is a 3d animated graph then how to change position of the axis. X-axis in place of...
  • Ren (52 days 9 hours ago): I noticed that xlsread will create a hidden and never-dying special server that always has priority when actxGetRunningServer is called. So this cause a problem that no matter how many...
  • Ben Abbott (55 days 23 hours ago): Thanks Yair, it was the second. I didn’t not include the drawnow ()
  • Yair Altman (56 days 2 hours ago): @Ben – it looks perfectly ok (with color gradient and all) on my R2022a… Perhaps you missed some of the steps (e.g. setting the ColorBinding to 'interpolated') or...
  • Ben Abbott (56 days 3 hours ago): The graded color is not working for me using R2021a. The plot “HG2 plot line color, transparency gradient” looks exactly like “Transparent HG2 plot...
  • Yair Altman (79 days 5 hours ago): Oliver – you probably forgot to update hMarkers.FaceColorType to ‘truecoloralpha‘: x=1:10; y=10*x; figure; hLine = plot(x,y,'o-'); drawnow...
  • Oliver (79 days 6 hours ago): This seems to have been disabled in the most recent version of Matlab (R2021b). When I use this method the hMarker.FaceColorData does change, but the markers are not made...
  • Yair Altman (98 days 4 hours ago): @Tim – the new uidatepicker() function only works with web-based figures (created using the uifigure() function or App Designer); it is not available on the legacy...
Contact us
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