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

Hierarchical Systems with UDD

March 2, 2011 10 Comments

Once again I welcome guest blogger Donn Shull, who continues his multi-part series about Matlab’s undocumented UDD objects.
We have looked at the tools for working with UDD classes, and created a simple UDD class. Today I shall show how to create a hierarchy of UDD objects.

Creating hierarchical structures with UDD objects

UDD is the foundation for both Handle Graphics (HG) and Simulink. Both are hierarchical systems. It stands to reason that UDD would offer support for hierarchical structures. It is straightforward to connect UDD objects together into searchable tree structures. All that is necessary is a collection of UDD objects that don’t have any methods or properties named 'connect', 'disconnect', 'up', 'down', 'left', 'right' or 'find'.
We illustrate the technique by creating a hierarchy of simple.objects as shown in the following diagram:

Sample UDD objects hierarchy
Sample UDD objects hierarchy

To begin we create five instances of the simple.object class from the previous article:

% Remember that simple.object accepts a name and a value
a = simple.object('a', 1);
b = simple.object('b', 1);
c = simple.object('c', 0);
d = simple.object('d', 1);
e = simple.object('e', 1);

% Remember that simple.object accepts a name and a value a = simple.object('a', 1); b = simple.object('b', 1); c = simple.object('c', 0); d = simple.object('d', 1); e = simple.object('e', 1);

To form the structure we use the connect method. We can use either dot notation or the Matlab syntax:

% Dot-notation examples:
a.connect(b, 'down');
b.connect(a, 'up');       % alternative to the above
% Matlab notation examples:
connect(a, b, 'down');
connect(b, a, 'up');      % alternative to the above

% Dot-notation examples: a.connect(b, 'down'); b.connect(a, 'up'); % alternative to the above % Matlab notation examples: connect(a, b, 'down'); connect(b, a, 'up'); % alternative to the above

Next, connect node c into our hierarchy. There are several options here: We can use ‘down’ to connect a to c. Or we could use ‘up’ to connect c to a. Similarly, we can use either ‘left’ or ‘right’ to connect b and c. Here’s one of the many possible ways to create our entire hierarchy:

b.connect(a, 'up');
c.connect(b, 'left');
d.connect(b, 'up');
e.connect(d, 'left');

b.connect(a, 'up'); c.connect(b, 'left'); d.connect(b, 'up'); e.connect(d, 'left');

Inspecting UDD hierarchy structures

We now have our structure and each object knows its connection to other objects. For example, we can inspect b’s connections as follows:

>> b.up
ans =
  Name: a
 Value: 1.000000
>> b.right
ans =
  Name: c
 Value: 0.000000
>> b.down
ans =
  Name: d
 Value: 1.000000

>> b.up ans = Name: a Value: 1.000000 >> b.right ans = Name: c Value: 0.000000 >> b.down ans = Name: d Value: 1.000000

We can search our structure by using an undocumented form of the built-in find command. When used with connected UDD structures, find can be used in the following form:

objectArray = find(startingNode, 'property', 'value', ...)

objectArray = find(startingNode, 'property', 'value', ...)

To search from the top of our hierarchy for objects of type simple.object we would use:

>> find(a, '-isa', 'simple.object')
ans =
        simple.object: 5-by-1    % a, b, c, d, e

>> find(a, '-isa', 'simple.object') ans = simple.object: 5-by-1 % a, b, c, d, e

Which returns all the objects in our structure, since all of them are simple.objects. If we repeat that command starting at b we would get:

>> find(b, '-isa', 'simple.object')
ans =
	simple.object: 3-by-1    % b, d, e

>> find(b, '-isa', 'simple.object') ans = simple.object: 3-by-1 % b, d, e

find searches the structure downward from the current node. Like many Matlab functions, find can be used with multiple property value pairs, so if we want to find simple.object objects in our structure with Value property =0, we would use the command:

>> find(a, '-isa', 'simple.object', 'Value', 0)
ans =
  Name: c
 Value: 0.000000

>> find(a, '-isa', 'simple.object', 'Value', 0) ans = Name: c Value: 0.000000

Visualizing a UDD hierarchy

Hierarchical structures are also known as tree structures. Matlab has an undocumented function for visualizing and working with trees namely uitree. Yair has described uitree in a series of articles. Rather than following the techniques in shown in Yair’s articles, we are going to use a different method that will allow us to introduce the following important techniques for working with UDD objects:

  • Subclassing, building your class on the foundation of a parent class
  • Overloading properties and methods of the superclass
  • Using meta-properties GetfFunction and SetFunction

Because the steps shown below will subclass an HG class, they will modify our simple.object class and probably make it unsuitable for general use. Yair has shown that uitree is ready made for displaying HG trees and we saw above that HG is a UDD system. We will use the technique from uitools.uibuttongroup to make our simple.object class a subclass of the HG class hg.uipanel. Modify the class definition file as follows:

% class definition
superPackage = findpackage('hg');
superClass = findclass(superPackage, 'uipanel');
simpleClass = schema.class(simplePackage, 'object',superClass);

% class definition superPackage = findpackage('hg'); superClass = findclass(superPackage, 'uipanel'); simpleClass = schema.class(simplePackage, 'object',superClass);

Now we can either issue the clear classes command or restart Matlab and then recreate our structure. The first thing that you will notice is that when we create the first simple.object that a figure is also created. This is expected and is the reason that this technique is not useful in general. We will however use this figure to display our structure with the following commands:

t = uitree('v0', 'root', a);  drawnow;
t.expand(t.getRoot);  drawnow;
t.expand(t.getRoot.getFirstChild);

t = uitree('v0', 'root', a); drawnow; t.expand(t.getRoot); drawnow; t.expand(t.getRoot.getFirstChild);

Simple structure presented in a Matlab uitree
Simple structure presented in a Matlab uitree

The label on each of our objects is ‘uipanel’ and this is probably not what we want. If we inspect our object or its hg.uipanel super-class (note: this would be a great time to use Yair’s uiinspect utility), we can see there is a Type property that has a value of ‘uipanel’. Unfortunately this property is read-only, so we cannot change it. We can however overload it by placing a schema.prop in our class definition named Type. This will allow us to overload or replace the parent’s Type property with our own definition:

p = schema.prop(simpleClass, 'Type', 'string');
p.FactoryValue = 'simple.object';

p = schema.prop(simpleClass, 'Type', 'string'); p.FactoryValue = 'simple.object';

Once again, issue the clear classes command or restart Matlab, then recreate our structure. Our tree now has each node labeled with the ‘simple.object’ label:

Corrected node names for our UDD structure
Corrected node names for our UDD structure

This is a little more descriptive but what would really be nice is if we could label each node with the value of the Name property. As luck would have it, we can do just that. When we add a property to a UDD class we are adding an object of type schema.prop. So our properties have their own properties and methods (so-called meta-data). We are going to set the GetFunction property of our Type property. GetFunction holds a handle of the function to be called whenever the property is accessed:

p = schema.prop(simpleClass, 'Type', 'string');
p.GetFunction = @getType;

p = schema.prop(simpleClass, 'Type', 'string'); p.GetFunction = @getType;

The prototype for the function that GetFunction references has three inputs and one output: The inputs are the handle of the object possessing the property, the value of that property, and the property object. The output is the value that will be supplied when the property is accessed. So our GetFunction can be written to supply the value of the Name property whenever the Type property value is being read:

function propVal = getType(self, value, prop)
   propVal = self.Name;
end

function propVal = getType(self, value, prop) propVal = self.Name; end

Alternately, as a single one-liner in the schema definition file:

p.GetFunction = @(self,value,prop) self.Name;

p.GetFunction = @(self,value,prop) self.Name;

Similarly, there is a corresponding SetFunction that enables us to intercept changes to a property’s value and possibly disallow invalid values.
With these changes when we recreate our uitree we obtain:

Overloaded property GetFunction
Overloaded property GetFunction

A Java class for UDD trees

We will have more to say about the relationship between UDD and Java in a future article. For now we simply note that the com.mathworks.jmi.bean.UDDObjectTreeModel class in the JMI package provides some UDD tree navigation helper functions. Methods include getChild, getChildCount, getIndexOfChild and getPathToRoot. The UDDObjectTreeModel constructor requires one argument, an instance of your UDD tree root node:

% Create a UDD tree-model instance
>> uddTreeModel = com.mathworks.jmi.bean.UDDObjectTreeModel(a);
% Get index of child e and its parent b:
>> childIndex = uddTreeModel.getIndexOfChild(b, e)
childIndex =
     1
% Get the root's first child (#0):
>> child0 = uddTreeModel.getChild(a, 0)
child0 =
  Name: b
 Value: 1.000000
% Get the path from node e to the root:
>> path2root = uddTreeModel.getPathToRoot(e)
path2root =
com.mathworks.jmi.bean.UDDObject[]:
    [simple_objectBeanAdapter2]      % <= a
    [simple_objectBeanAdapter2]      % <= b
    [simple_objectBeanAdapter2]      % <= e
>> path2root(3)
ans =
  Name: e
 Value: 1.000000

% Create a UDD tree-model instance >> uddTreeModel = com.mathworks.jmi.bean.UDDObjectTreeModel(a); % Get index of child e and its parent b: >> childIndex = uddTreeModel.getIndexOfChild(b, e) childIndex = 1 % Get the root's first child (#0): >> child0 = uddTreeModel.getChild(a, 0) child0 = Name: b Value: 1.000000 % Get the path from node e to the root: >> path2root = uddTreeModel.getPathToRoot(e) path2root = com.mathworks.jmi.bean.UDDObject[]: [simple_objectBeanAdapter2] % <= a [simple_objectBeanAdapter2] % <= b [simple_objectBeanAdapter2] % <= e >> path2root(3) ans = Name: e Value: 1.000000

We touched on a few of the things that you can do by modifying the properties of a schema.prop in this article. In the following article we will take a more detailed look at this essential class.

Related posts:

  1. Getting default HG property values – Matlab has documented how to modify default property values, but not how to get the full list of current defaults. This article explains how to do this. ...
  2. Introduction to UDD – UDD classes underlie many of Matlab's handle-graphics objects and functionality. This article introduces these classes....
  3. Creating a simple UDD class – This article explains how to create and test custom UDD packages, classes and objects...
  4. UDD Properties – UDD provides a very convenient way to add customizable properties to existing Matlab object handles...
  5. UDD Events and Listeners – UDD event listeners can be used to listen to property value changes and other important events of Matlab objects...
  6. Multi-column (grid) legend – This article explains how to use undocumented axes listeners for implementing multi-column plot legends...
Donn Shull Handle graphics JMI schema schema.prop uitools Undocumented feature
Print Print
« Previous
Next »
10 Responses
  1. Sebastian Hölz March 7, 2011 at 15:56 Reply

    Hi Donn, thanks for this interesting series of articles. It touches a field that I’m currently investigating, but where I can not find a suitable solution yet.

    Simple example:
    Suppose I create a UDD-subclass of HG-axes named mAxis and want to be able to restrict the user to certain xlims, e.g. only multiples of 10. How can I intercept a call like

    >> set(H, 'xlim', [11 20])   % Where H is a mAxis object

    >> set(H, 'xlim', [11 20]) % Where H is a mAxis object

    On the one hand side, if I make xlim a property of the class (using “schema.prop …” in the schema.m-file) and supply the according SetFunction, I can no longer pass the property to the “superclass”, i.e. the axis object.

    On the other hand Matlab will not let me specify a SetFunction in the mAxis.m, because the xlim property is protected.

    OK, maybe you can hint me to some solution.

    Cheers

    Sebastian

    • Donn Shull March 8, 2011 at 10:26 Reply

      @Sebastian – Normally you can overload a propertyof the superclass in a subclass. I think the problem in this case MATLAB will not allow you to set the type of your overloaded XLim property to axesXLimType and no other type will work. XLim does generate Events so you could try something like:

      lis = handle.listener(a, a.findprop('XLim'), 'PropertyPostSet', 'a.XLim = [11,20];')

      lis = handle.listener(a, a.findprop('XLim'), 'PropertyPostSet', 'a.XLim = [11,20];')

      To solve your problem.

      In the upcoming section on UDD events we will show how to placecode like this in a a class.

      Best Regards,

      Donn

      • Sebastian Hölz March 9, 2011 at 02:23

        Your example using ‘PropertyPostSet’ works. I thought that this would lead to a racing condition, but it doesn’t. I will work from here on …

        Thanks

        Sebastian

        PS to anyone, who wants to try something similar:

        1) Define property “PL” (-> PropListener) in schema.m file:

        p = schema.prop(MyClass, ‘PropListener’, ‘handle vector’);

        2) Specify ‘PropertyPostSet’ listener and nested function to handle the property change in the MyClass.m – file.

        function obj = MyClass(varargin)

        obj = MyPackage.MyClass;
        obj.PL=handle.listener(obj, obj.findprop(‘XLim’), ‘PropertyPostSet’,@MF);

        function MF(~, in)
        obj.xlim = round(in.NewValue);
        end

        end

        – The handle to the listener is saved in property “PL”, otherwise the function “MF” would not be called. This is similar to what is done in the “linkprop” command (s. Matlab documentation).

        – Since “MF” is specified as nested function, obj is still in scope and the new value (in.NewValue) can be checked, altered and passed to the object.

  2. Extending a Java class with UDD | Undocumented Matlab March 29, 2012 at 07:33 Reply

    […] In Hierarchical Systems with UDD we briefly noted that a UDD hierarchy may be passed to Java […]

  3. Matt S October 21, 2014 at 13:50 Reply

    Hi,

    I am trying to create a simple UDD class similar to this. The class is the same as simple.object with simple.object being a subclass of uipanel. I am trying to include a uicontrol slider on the panel during construction. When I open up Matlab, the first time I run the constructor, I always get the error: The class name ‘ScrollablePanel’ already exists. If I run it again, it works without error. Is there a way I can make it work the first time? If it helps, here is the constructor:

    function this = ScrollablePanel(varargin)
       this = uiStrider.ScrollablePanel;
       set(this,varargin{:});
       set(this,'SliderHandle',uicontrol('Parent',handle(this), 'Style','Slider','Units','Pixels'));
    end

    function this = ScrollablePanel(varargin) this = uiStrider.ScrollablePanel; set(this,varargin{:}); set(this,'SliderHandle',uicontrol('Parent',handle(this), 'Style','Slider','Units','Pixels')); end

    Thanks for doing this website. I use it all the time,
    Matt

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
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
  • Nicholas (6 days 13 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Nicholas (6 days 13 hours ago): Hi Yair, Thanks for the reply. I am on Windows 10. I also forgot to mention that this all works wonderfully out of the editor. It only fails once compiled. So, yes, I have tried a...
  • Yair Altman (6 days 20 hours ago): Nicholas – yes, I used it in a compiled Windows app using R2022b (no update). You didn’t specify the Matlab code location that threw the error so I can’t help...
  • Nicholas (7 days 16 hours ago): Hi Yair, Have you attempted your displayWebPage utility (or the LightweightHelpPanel in general) within a compiled application? It appears to fail in apps derived from both R2022b...
  • João Neves (10 days 21 hours ago): I am on matlab 2021a, this still works: url = struct(struct(struct(struct(hF ig).Controller).PlatformHost). CEF).URL; but the html document is empty. Is there still a way to do...
  • Yair Altman (13 days 20 hours ago): Perhaps the class() function could assist you. Or maybe just wrap different access methods in a try-catch so that if one method fails you could access the data using another...
  • Jeroen Boschma (13 days 22 hours ago): Never mind, the new UI components have an HTML panel available. Works for me…
  • Alexandre (13 days 23 hours ago): Hi, Is there a way to test if data dictionnatry entry are signal, simulink parameters, variables … I need to access their value, but the access method depends on the data...
  • Nicholas (14 days 14 hours ago): In case anyone is looking for more info on the toolbar: I ran into some problems creating a toolbar with the lightweight panel. Previously, the Browser Panel had an addToolbar...
  • Jeroen Boschma (17 days 21 hours ago): I do not seem to get the scrollbars (horizontal…) working in Matlab 2020b. Snippets of init-code (all based on Yair’s snippets on this site) handles.text_explorer...
  • Yair Altman (45 days 23 hours ago): m_map is a mapping tool, not even created by MathWorks and not part of the basic Matlab system. I have no idea why you think that the customizations to the builtin bar function...
  • chengji chen (46 days 5 hours ago): Hi, I have tried the method, but it didn’t work. I plot figure by m_map toolbox, the xticklabel will add to the yticklabel at the left-down corner, so I want to move down...
  • Yair Altman (53 days 22 hours ago): @Alexander – this is correct. Matlab stopped including sqlite4java in R2021b (it was still included in 21a). You can download the open-source sqlite4java project from...
  • Alexander Eder (59 days 18 hours ago): Unfortunately Matlab stopped shipping sqlite4java starting with R2021(b?)
  • K (66 days 5 hours ago): Is there a way to programmatically manage which figure gets placed where? Let’s say I have 5 figures docked, and I split it into 2 x 1, I want to place 3 specific figures on the...
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