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
?
You can create a cellarray containing the identifier of the nodes that have been expanded.
The cellarray will be:
TreeNodeExpanded
callback that is called when the user expands a nodeTreeNodeCollapsed
callback that is called when the user collapes a nodeThen you can create two pushbutton:
The callback associated to the pushbutton that loads the cellarray with list of the expanded nodes:
The following is a possible implementation of the proposed procedure in an app.
The startupFcn
callback:
NodeData
property of each node to an integer values that will be used as index to acces to the cellarrayThe 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:
NodeData
propertyThe TreeNodeCollapsed
:
NodeData
propertyThe 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