Search code examples
matlabuser-interfacetreeview

Get uitreenode expanded state


I have built a UI in Matlab, displaying a tree. I used the new UI components and want to save and restore the state of the expanded/collapsed nodes. Unfortunately I could not find a way to determine the current state of a tree node. Here's a simple example:

t = uitree(uigridlayout(uifigure, [1 1]));
p = uitreenode(t, 'Text', 'Parent');
uitreenode(p, 'Text', 'Child');

How can I determine the expanded state of the parent node p?


Solution

  • You can create a cellarray containing the identifier of the nodes that have been expanded.

    The cellarray will be:

    • set in the TreeNodeExpanded callback that is called when the user expands a node
    • reset in the TreeNodeCollapsed callback that is called when the user collapes a node

    Then you can create two pushbutton:

    • one to save the cellarray
    • one to load it and restore the node configuration

    The callback associated to the pushbutton that loads the cellarray with list of the expanded nodes:

    • collapses (with the collapse function) all the node to reset the status of the tree
    • loops through the cellarray and expands (with the expand function) the nodes whose identifier has been stored (and read) in the ".mat" file

    The following is a possible implementation of the proposed procedure in an app.

    The startupFcn callback:

    • identifies the nodes present in the app
    • creates a cellarray containing the identifiers of all the nodes of the tree
    • sets the NodeData property of each node to an integer values that will be used as index to acces to the cellarray

    The SaveTreeLeafstatusButtonPushed and LoadTreeLeafstatusButtonPushed callbacks simply save and load a ".mat" file whios name is hard written in the code; you can easily update then using the uigetfile and uiputfile functions.

    The TreeNodeExpanded callback:

    • gets the index of the expanded node from its NodeData property
    • retrieves the identifier of the node
    • sets the corresponding element of the cellarray that contains the identifier of the expanded nodes

    The TreeNodeCollapsed:

    • gets the index of the collapsed node from its NodeData property
    • reset the corresponding element of the cellarray that contains the identifier of the expanded nodes

    The comments in the code should describe the main step summarized above.

        classdef SAVE_EXPAND_TREE < matlab.apps.AppBase
    
       % Properties that correspond to app components
       properties (Access = public)
          save_expand_tree          matlab.ui.Figure
          Label                     matlab.ui.control.Label
          LoadTreeLeafstatusButton  matlab.ui.control.Button
          SaveTreeLeafstatusButton  matlab.ui.control.Button
          Tree                      matlab.ui.container.Tree
          Level0Node                matlab.ui.container.TreeNode
          Level_1_Node_1            matlab.ui.container.TreeNode
          Level_2_Node_1            matlab.ui.container.TreeNode
          Level_2_Node_2            matlab.ui.container.TreeNode
          Level_3_Node_1            matlab.ui.container.TreeNode
          Level_3_Node_2            matlab.ui.container.TreeNode
          Level_1_Node_2            matlab.ui.container.TreeNode
          Level_2_Node_3            matlab.ui.container.TreeNode
          Level_2_Node_4            matlab.ui.container.TreeNode
          Level_1_Node_3            matlab.ui.container.TreeNode
          Level_2_Node_5            matlab.ui.container.TreeNode
          Level_2_Node_6            matlab.ui.container.TreeNode
       end
    
       
       properties (Access = private)
          tree_leaf_status;    % Property in which to store the status of the tree leaves
          tree_leaf_obj_names; % Property in which tyo store the names of the tree objects
       end
       
    
       % Callbacks that handle component events
       methods (Access = private)
    
          % Code that executes after component creation
          function startupFcn(app)
             % Initialize the property in which to store the status of the tree leaves as an empty
             % cell array
             % Each element of the cellarray contains the name of a node of the tree
             % The NodeData property of each node contains an integer value. This is used as an index
             % to access the elements in the cellarray
             % Initilize the the cellarray containing the namens of the tree objects
             % Set the node idx in its NodeData property
             app_fields=fieldnames(app);
             cnt=0;
             for i=1:numel(app_fields)
                if(isa(app.(app_fields{i}),'matlab.ui.container.TreeNode'))
                   cnt=cnt+1;
                   app.(app_fields{i}).NodeData=cnt;
                   app.tree_leaf_obj_names{app.(app_fields{i}).NodeData}=app_fields{i};
                end
             end
          end
    
          % Node expanded function: Tree
          function TreeNodeExpanded(app, event)
             node = event.Node;
             % Set the element of the tree_leaf_status cellarray corresponding to the index stored in
             % the NodeData property of the node that has been expanded to the name of the node itself
    
             % Get the idx of the expanded node
             idx=node.NodeData;
             % Set the element of the tree_leaf_status cellarray to the name of the node object
             app.tree_leaf_status{idx}=app.tree_leaf_obj_names{idx};
          end
    
          % Node collapsed function: Tree
          function TreeNodeCollapsed(app, event)
             node = event.Node;
             % Get the idx of the collapsed node
             idx=node.NodeData;
             % Reset the lement of the tree_leaf_status cellarray
             app.tree_leaf_status{idx}='';
          end
    
          % Button pushed function: SaveTreeLeafstatusButton
          function SaveTreeLeafstatusButtonPushed(app, event)
             % Get the tree_leaf_status cellarray
             tmp_tree_leaf_status=app.tree_leaf_status;
             % Save the tree_leaf_status cellarray in a ".mat" file
             save('tmp_tree_leaf_status.mat','tmp_tree_leaf_status')
          end
    
          % Button pushed function: LoadTreeLeafstatusButton
          function LoadTreeLeafstatusButtonPushed(app, event)
             % Check if the ".mat" file exists
             if(exist("tmp_tree_leaf_status.mat","file"))
                create_gif('tree_leaf.gif',app.save_expand_tree,1.5,0)
                app.Label.Text='Loading tmp_tree_leaf_status.mat';
                create_gif('tree_leaf.gif',app.save_expand_tree,1.5,1)
                % Load the tree_leaf_status ".mat" file
                load('tmp_tree_leaf_status.mat')
                % Collapse all the leaf of the tree
                collapse(app.Tree,'All')
                app.Label.Text='All Tree leaf collapsed before restoring the loaded status';
                create_gif('tree_leaf.gif',app.save_expand_tree,1.5,1)
                % loop through the leaf of the tree and expand those saved in the ".mat" file
                for i=1:numel(app.tree_leaf_status)
                   tmp_tree_leaf_status{i};
                   if(~isempty(tmp_tree_leaf_status{i}))
                      app.Label.Text=['Expanding ' tmp_tree_leaf_status{i}];
                      expand(app.(tmp_tree_leaf_status{i}))
                      create_gif('tree_leaf.gif',app.save_expand_tree,1.5,1)
                   end
                end
             end
          end
       end
    
       % Component initialization
       methods (Access = private)
    
          % Create UIFigure and components
          function createComponents(app)
    
             % Create save_expand_tree and hide until all components are created
             app.save_expand_tree = uifigure('Visible', 'off');
             app.save_expand_tree.Position = [100 100 541 381];
             app.save_expand_tree.Name = 'Save & Restore Tree Leaft Status';
    
             % Create Tree
             app.Tree = uitree(app.save_expand_tree);
             app.Tree.NodeExpandedFcn = createCallbackFcn(app, @TreeNodeExpanded, true);
             app.Tree.NodeCollapsedFcn = createCallbackFcn(app, @TreeNodeCollapsed, true);
             app.Tree.Position = [22 105 279 277];
    
             % Create Level0Node
             app.Level0Node = uitreenode(app.Tree);
             app.Level0Node.Text = 'Level 0 Node';
    
             % Create Level_1_Node_1
             app.Level_1_Node_1 = uitreenode(app.Level0Node);
             app.Level_1_Node_1.Text = 'Level 1 Node 1';
    
             % Create Level_2_Node_1
             app.Level_2_Node_1 = uitreenode(app.Level_1_Node_1);
             app.Level_2_Node_1.Text = 'Level 2 Node 1';
    
             % Create Level_2_Node_2
             app.Level_2_Node_2 = uitreenode(app.Level_1_Node_1);
             app.Level_2_Node_2.Text = 'Level_2 Node 2';
    
             % Create Level_3_Node_1
             app.Level_3_Node_1 = uitreenode(app.Level_2_Node_2);
             app.Level_3_Node_1.Text = 'Level 3 Node 1';
    
             % Create Level_3_Node_2
             app.Level_3_Node_2 = uitreenode(app.Level_2_Node_2);
             app.Level_3_Node_2.Text = 'Level_3_Node_2';
    
             % Create Level_1_Node_2
             app.Level_1_Node_2 = uitreenode(app.Level0Node);
             app.Level_1_Node_2.Text = 'Level 1 Node 2';
    
             % Create Level_2_Node_3
             app.Level_2_Node_3 = uitreenode(app.Level_1_Node_2);
             app.Level_2_Node_3.Text = 'Level 2 Node 3';
    
             % Create Level_2_Node_4
             app.Level_2_Node_4 = uitreenode(app.Level_1_Node_2);
             app.Level_2_Node_4.Text = 'Level 2 Node 4';
    
             % Create Level_1_Node_3
             app.Level_1_Node_3 = uitreenode(app.Level0Node);
             app.Level_1_Node_3.Text = 'Level 1 Node 3';
    
             % Create Level_2_Node_5
             app.Level_2_Node_5 = uitreenode(app.Level_1_Node_3);
             app.Level_2_Node_5.Text = 'Level 2 Node 5';
    
             % Create Level_2_Node_6
             app.Level_2_Node_6 = uitreenode(app.Level_1_Node_3);
             app.Level_2_Node_6.Text = 'Level 2 Node 6';
    
             % Create SaveTreeLeafstatusButton
             app.SaveTreeLeafstatusButton = uibutton(app.save_expand_tree, 'push');
             app.SaveTreeLeafstatusButton.ButtonPushedFcn = createCallbackFcn(app, @SaveTreeLeafstatusButtonPushed, true);
             app.SaveTreeLeafstatusButton.Position = [339 289 165 33];
             app.SaveTreeLeafstatusButton.Text = 'Save Tree Leaf status';
    
             % Create LoadTreeLeafstatusButton
             app.LoadTreeLeafstatusButton = uibutton(app.save_expand_tree, 'push');
             app.LoadTreeLeafstatusButton.ButtonPushedFcn = createCallbackFcn(app, @LoadTreeLeafstatusButtonPushed, true);
             app.LoadTreeLeafstatusButton.Position = [339 219 165 33];
             app.LoadTreeLeafstatusButton.Text = 'Load Tree Leaf status';
    
             % Create Label
             app.Label = uilabel(app.save_expand_tree);
             app.Label.FontWeight = 'bold';
             app.Label.FontColor = [1 0 0];
             app.Label.Position = [22 30 482 59];
             app.Label.Text = '';
    
             % Show the figure after all components are created
             app.save_expand_tree.Visible = 'on';
          end
       end
    
       % App creation and deletion
       methods (Access = public)
    
          % Construct app
          function app = SAVE_EXPAND_TREE
    
             % Create UIFigure and components
             createComponents(app)
    
             % Register the app with App Designer
             registerApp(app, app.save_expand_tree)
    
             % Execute the startup function
             runStartupFcn(app, @startupFcn)
    
             if nargout == 0
                clear app
             end
          end
    
          % Code that executes before app deletion
          function delete(app)
    
             % Delete UIFigure when app is deleted
             delete(app.save_expand_tree)
          end
       end
    end
    

    enter image description here