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

UDD and Java

March 23, 2011 4 Comments

Once again I welcome Donn Shull, who concludes his series on Matlab’s undocumented UDD mechanism with a discussion of the UDD-Java relationship.

Introduction to the UDD-Java relationship

Over the course of this series we have mentioned connections between UDD and Java. In UDD Events and Listeners we described how in Matlab each Java object can have a UDD companion. In Hierarchical Systems with UDD we briefly noted that a UDD hierarchy may be passed to Java. This suggests that there is a two way relationship between between UDD and Java.
In this article we will use some undocumented built-in methods such as java and classhandle to explore the UDD-Java relationship. We have used built-in methods for UDD objects before. We have also mentioned the importance of studying code from The MathWorks. When you come across something that looks like it may be a UDD method you can check with the which command:

>> which java -all
C:\MATLAB\R2010b\toolbox\matlab\general\java.m
java is a built-in method                               % javahandle.com.mathworks.hg.peer.Echo method
java is a built-in method                               % ui.figure method
java is a built-in method                               % hg2utils.HGHandle method
java is a built-in method                               % JavaVisible method
java is a built-in method                               % hg.figure method
java is a built-in method                               % hg.GObject method
java is a built-in method                               % schema.class method
java is a built-in method                               % handle.handle method
java is a built-in method                               % schema.method method
C:\MATLAB\R2010b\toolbox\rptgen\rptgen\@sgmltag\java.m  % sgmltag method

>> which java -all C:\MATLAB\R2010b\toolbox\matlab\general\java.m java is a built-in method % javahandle.com.mathworks.hg.peer.Echo method java is a built-in method % ui.figure method java is a built-in method % hg2utils.HGHandle method java is a built-in method % JavaVisible method java is a built-in method % hg.figure method java is a built-in method % hg.GObject method java is a built-in method % schema.class method java is a built-in method % handle.handle method java is a built-in method % schema.method method C:\MATLAB\R2010b\toolbox\rptgen\rptgen\@sgmltag\java.m % sgmltag method

If you find schema.class in the comments for built-in methods, then the method is a general UDD method.

UDD javahandle companions for Java object

Whenever a Java class is instantiated in Matlab, it is possible to create a companion UDD object. The created companion can be in either the javahandle or the javahandle_withcallbacks package. The primary reason for creating the companion object is to avoid memory leaks when attaching a Matlab callback to a callback property. It makes sense in general to use the javahandle_withcallbacks package.

>> % creage a java instance and the companion UDD object
>> javaFrame = javax.swing.JFrame;
>> % dot notation
>> javaFrameUDD = javaFrame.handle('CallbackProperties');
>> % or Matlab notation
>> javaFrameUDD = handle(javaFrame,'CallbackProperties');

>> % creage a java instance and the companion UDD object >> javaFrame = javax.swing.JFrame; >> % dot notation >> javaFrameUDD = javaFrame.handle('CallbackProperties'); >> % or Matlab notation >> javaFrameUDD = handle(javaFrame,'CallbackProperties');

We can use the built-in classhandle method to inspect our UDD companion object. This can be used, for example, to obtain a list of the events that the Java class generates:

>> % use classhandle to list a java classes events
>> jch = javaFrame.handle.classhandle;
>> for index = 1:numel(jch.Events), disp(jch.Events(index).Name); end
MouseWheelMoved
MouseClicked
MouseEntered
MouseExited
MousePressed
MouseReleased
WindowGainedFocus
WindowLostFocus
WindowActivated
WindowClosed
WindowClosing
WindowDeactivated
WindowDeiconified
WindowIconified
WindowOpened
ComponentHidden
ComponentMoved
ComponentResized
ComponentShown
MouseDragged
MouseMoved
ComponentAdded
ComponentRemoved
AncestorMoved
AncestorResized
FocusGained
FocusLost
WindowStateChanged
HierarchyChanged
CaretPositionChanged
InputMethodTextChanged
PropertyChange
KeyPressed
KeyReleased
KeyTyped
>> % Use one of the object's callbacks
>> set(javaFrameUDD,'WindowGainedFocusCallback',@myCallbackFcn);

>> % use classhandle to list a java classes events >> jch = javaFrame.handle.classhandle; >> for index = 1:numel(jch.Events), disp(jch.Events(index).Name); end MouseWheelMoved MouseClicked MouseEntered MouseExited MousePressed MouseReleased WindowGainedFocus WindowLostFocus WindowActivated WindowClosed WindowClosing WindowDeactivated WindowDeiconified WindowIconified WindowOpened ComponentHidden ComponentMoved ComponentResized ComponentShown MouseDragged MouseMoved ComponentAdded ComponentRemoved AncestorMoved AncestorResized FocusGained FocusLost WindowStateChanged HierarchyChanged CaretPositionChanged InputMethodTextChanged PropertyChange KeyPressed KeyReleased KeyTyped >> % Use one of the object's callbacks >> set(javaFrameUDD,'WindowGainedFocusCallback',@myCallbackFcn);

If we do not wish to use callback properties, then we can create our UDD companion in the javahandle package and use handle.listener to respond to events.

javaFrame = javax.swing.JFrame;
javaFrameUDD = javaFrame.handle;
lis = handle.listener(javaFrameUDD,'WindowGainedFocus',@myCallbackFcn);

javaFrame = javax.swing.JFrame; javaFrameUDD = javaFrame.handle; lis = handle.listener(javaFrameUDD,'WindowGainedFocus',@myCallbackFcn);

Passing UDD objects to Java code

You can pass any UDD object to your Java classes in Matlab. Matlab will create a Java bean adapter for the UDD object. The bean adapter created is a subclass of com.MathWorks.jmi.bean.UDDObject. UDDObject implements the Java interfaces com.MathWorks.jmi.bean.DynamicProperties, com.MathWorks.jmi.bean.MTObject, com.MathWorks.jmi.bean.TreeObject, and com.mathworks.services.Browseable.
The generated bean adapter will have the methods of the parent class the methods of the UDD class, as well as set and get methods for the class properties. To understand how this works, let’s start with our simple.object and use the java method to inspect the bean adapter:

>> myObj = simple.object('myObj', 2);
>> % using dot notation with the java method
>> myObj.java.getClass
ans =
class objectBeanAdapter0
>> myObj.java.methods
Methods for class objectBeanAdapter0:
acquireReference                    createNullMatlabObjectListener      lastDown
addBelow                            createNullPropertyChangeListener    left
addBrowseableListener               dialog                              notify
addFirstBelow                       disp                                notifyAll
addLeft                             dispose                             objectBeanAdapter0
addMatlabObjectListener             equals                              releaseReference
addObjectPropertyChangeListener     findProperty                        removeBrowseableListener
addRight                            firstDown                           removeMatlabObjectListener
browseableCanHaveChildren           getChildAt                          removeObjectPropertyChangeListener
browseableChild                     getChildCount                       right
browseableChildCount                getClass                            setDirtyFlag
browseableChildFetchCount           getClassName                        setDynamicPropertyValue
browseableChildren                  getDynamicProperties                setName
browseableDataObject                getDynamicPropertyValue             setPropertyValue
browseableDisplayObject             getIndex                            setThreadSafetyCheckLevel
browseableHasChildren               getIndexOfChild                     setValue
browseableNChildren                 getName                             toString
browseableNextNSiblings             getNewInstance                      up
browseableNextSibling               getPropertyValue                    updateCache
browseableParent                    getValue                            updateChildCount
browseablePrevNSiblings             hashCode                            updateIndex
browseablePrevSibling               isDirty                             wait
checkThreadSafety                   isLeaf
clearDirtyFlag                      isObservable
compareTo                           isValid

>> myObj = simple.object('myObj', 2); >> % using dot notation with the java method >> myObj.java.getClass ans = class objectBeanAdapter0 >> myObj.java.methods Methods for class objectBeanAdapter0: acquireReference createNullMatlabObjectListener lastDown addBelow createNullPropertyChangeListener left addBrowseableListener dialog notify addFirstBelow disp notifyAll addLeft dispose objectBeanAdapter0 addMatlabObjectListener equals releaseReference addObjectPropertyChangeListener findProperty removeBrowseableListener addRight firstDown removeMatlabObjectListener browseableCanHaveChildren getChildAt removeObjectPropertyChangeListener browseableChild getChildCount right browseableChildCount getClass setDirtyFlag browseableChildFetchCount getClassName setDynamicPropertyValue browseableChildren getDynamicProperties setName browseableDataObject getDynamicPropertyValue setPropertyValue browseableDisplayObject getIndex setThreadSafetyCheckLevel browseableHasChildren getIndexOfChild setValue browseableNChildren getName toString browseableNextNSiblings getNewInstance up browseableNextSibling getPropertyValue updateCache browseableParent getValue updateChildCount browseablePrevNSiblings hashCode updateIndex browseablePrevSibling isDirty wait checkThreadSafety isLeaf clearDirtyFlag isObservable compareTo isValid

The parent class has added a large number of methods to the bean adapter for our original class. By looking at the list we can see our dialog and disp methods. There are also getName, setName, getValue, and setValue methods for our classes properties. The rest of the methods were inherited from the base UDDObject superclass. We can use any superclass method directly with the bean adapter object. For example:

>> myObj.java.getPropertyValue('Name')
ans =
myObj

>> myObj.java.getPropertyValue('Name') ans = myObj

Java interface class

To be able to use our UDD object in user-written Java code, we need a Java interface class for it. While we could manually write an interface file, UDD provides a very handy convenience method to automatically create the interface file. For this, we use the classhandle method again. The schema.class object obtained using classhandle has a method called createJavaInterface that takes two string arguments: the Java interface classname, and the folder in which to place the interface file. The steps to create and use this interface file are:

  1. Create and test your UDD class
  2. Create a Java interface file using schema.class‘s CreateJavaInterface
  3. Modify your UDD class definition file (schema.m) to reference the Java interface file
  4. Create the Java code that uses your class

For example, to create a Java interface file for the simple object we created above, use the following commands in Matlab:

classH = classhandle(myObj);
classH.createJavaInterface('simpleObjectInterface',pwd);

classH = classhandle(myObj); classH.createJavaInterface('simpleObjectInterface',pwd);

This will create the following simpleObjectInterface.java file in the current working directory:

public interface simpleObjectInterface
       extends com.mathworks.jmi.bean.TreeObject
{
    /* Properties */
    public java.lang.String getName();
    public void setName(java.lang.String value);
    public double getValue();
    public void setValue(double value);
    /* Methods */
    public void dialog();
    public void disp();
}

public interface simpleObjectInterface extends com.mathworks.jmi.bean.TreeObject { /* Properties */ public java.lang.String getName(); public void setName(java.lang.String value); public double getValue(); public void setValue(double value); /* Methods */ public void dialog(); public void disp(); }

The interface file contains set and get accessor methods for our UDD object properties, and Java prototypes for the UDD methods (in our case, dialog and disp).
The next step is to modify our class definition file (schema.m) to reference the Java interface file we have created. This modification provides the information that Matlab needs to create the bean adapter that implements the Java interface:

simpleClass = schema.class(simplePackage, 'object');
simpleClass.JavaInterfaces = { 'simpleObjectInterface' };

simpleClass = schema.class(simplePackage, 'object'); simpleClass.JavaInterfaces = { 'simpleObjectInterface' };

We can verify that the generated bean adapter implements the interface using Java Reflection techniques. As always when we have made changes to the class definition file, we need to use the clear classes command, and then recreate our objects:

>> myObj = simple.object('myObj', pi)
myObj =
  Name: myObj
 Value: 3.141593
>> myObjBean = java(myObj)
myObjBean =
  Name: myObj
 Value: 3.141593
>> interfaces = myObjBean.getClass.getInterfaces
interfaces =
java.lang.Class[]:
    [java.lang.Class]
>> interfaces(1)
ans =
interface simpleObjectInterface

>> myObj = simple.object('myObj', pi) myObj = Name: myObj Value: 3.141593 >> myObjBean = java(myObj) myObjBean = Name: myObj Value: 3.141593 >> interfaces = myObjBean.getClass.getInterfaces interfaces = java.lang.Class[]: [java.lang.Class] >> interfaces(1) ans = interface simpleObjectInterface

Using UDD in Java

Let’s create a simple Java class that illustrates passing a UDD object to Java. Here we will just have two methods: The first gets the Value property from a class instance and doubles it; the second launches the class instance dialog:

public class accessUDDClass
{
  double localValue;
  public void accessUDDClass() {
  }
  public void doubleValue(simpleObjectInterface UDDObj) {
    localValue = UDDObj.getValue();
    UDDObj.setValue(2*localValue);
  }
  public void launchDialog(simpleObjectInterface UDDObj) {
    UDDObj.dialog();
  }
}

public class accessUDDClass { double localValue; public void accessUDDClass() { } public void doubleValue(simpleObjectInterface UDDObj) { localValue = UDDObj.getValue(); UDDObj.setValue(2*localValue); } public void launchDialog(simpleObjectInterface UDDObj) { UDDObj.dialog(); } }

If we have set up the Java compiler and environment variables correctly, we can compile our interface and Java class files from inside Matlab using the system command (alternately, we can compile using any external Java compiler or IDE):

>> system('javac accessUDDClass.java simpleObjectInterface.java')
ans =
     0

>> system('javac accessUDDClass.java simpleObjectInterface.java') ans = 0

Now test our simple Java class with the UDD object created earlier:

>> javaObj = accessUDDClass
javaObj =
accessUDDClass@eb9b73
>> javaObj.doubleValue(myObj)  % pi => 2*pi
>> myObj
myObj =
  Name: myObj
 Value: 6.283185

>> javaObj = accessUDDClass javaObj = accessUDDClass@eb9b73 >> javaObj.doubleValue(myObj) % pi => 2*pi >> myObj myObj = Name: myObj Value: 6.283185

This concludes the UDD series. I would like to thank Yair for his help in preparing and presenting this information.

Editor’s note

I would like to thank Donn for his enourmously detailed work on UDD, and for preparing it in easy-to-follow articles. I can personally attest to the huge time investment it has taken him. I trully believe he deserves a warm “thank you” from the Matlab community. Please visit Donn’s website, or add a short comment below.
In the following weeks, I return to the regular stuff that made this website famous: solving day-to-day Matlab problems using simple undocumented built-in Matlab gems.
– Yair

Related posts:

  1. Matlab callbacks for Java events – Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
  2. Accessing internal Java class members – Java inner classes and enumerations can be used in Matlab with a bit of tweaking. ...
  3. JMI – Java-to-Matlab Interface – JMI enables calling Matlab functions from within Java. This article explains JMI's core functionality....
  4. Extending a Java class with UDD – Java classes can easily be extended in Matlab, using pure Matlab code. ...
  5. MathWorks-solicited Java survey – MathWorks is soliciting user feedbacks about the use of Java components in Matlab programs. ...
  6. Static Java classpath hacks – Several hacks that facilitate using the static Java classpath in Matlab are explained. ...
Donn Shull Java Listener Undocumented feature Undocumented function
Print Print
« Previous
Next »
4 Responses
  1. Matt Whitaker March 24, 2011 at 11:51 Reply

    I totally agree Yair. I have been reading this series closely and have learned an immense amount of detail on these UDD objects.
    Bravo, Donn! Much appreciated

  2. julien April 6, 2011 at 00:18 Reply

    Thanks Donn for these excellent and well written articles !
    I have a question, maybe you could help me. My problem is simple, I would like to trigger a Matlab callback when the value of a property of a java object changes.
    I tried 2 things : First is to set ‘PropertyChangeCallback’ to the UDD companion of my java Object.

    J=handle(javax.swing.JLabel('Hello'),'CallbackProperties');
    set(J,'PropertyChangeCallback',@(h,e)disp('Property changed'));

    J=handle(javax.swing.JLabel('Hello'),'CallbackProperties'); set(J,'PropertyChangeCallback',@(h,e)disp('Property changed'));

    When I modify the “Text” property, it works perfectly well.

    >> J.setText('New Value');
    Property changed

    >> J.setText('New Value'); Property changed

    However, the callback does not trigger on every properties. For example,

    J.setAutoscrolls(true); % Does not trigger the Callback

    J.setAutoscrolls(true); % Does not trigger the Callback

    So, my second try was to use UDD property event mechanism.

    J=handle(javax.swing.JLabel('Hello'),'CallbackProperties');
    P=findprop(J,'Text');
    L=handle.listener(J,P,'PropertyPostSet',@(h,e)disp('UDD property changed'));

    J=handle(javax.swing.JLabel('Hello'),'CallbackProperties'); P=findprop(J,'Text'); L=handle.listener(J,P,'PropertyPostSet',@(h,e)disp('UDD property changed'));

    This works, but only when the property value is changed from the set method on the UDD object :

    >> J.setText('Again a new value'); % Java side : does not trigger listener callback
    >> set(J,'Text','Hello'); % This triggers the listener callback
    UDD property changed

    >> J.setText('Again a new value'); % Java side : does not trigger listener callback >> set(J,'Text','Hello'); % This triggers the listener callback UDD property changed

    What I would like is to be able to trigger the callback on all properties of java objects and from property changes which come from java side (j.setProperty syntax) or Matlab side (set(obj,’Property’,Value) syntax).

    Do you know how I could do that from Matlab side ?
    Thank you very much in advance for your help.

    • Donn April 6, 2011 at 10:49 Reply

      @julien – I do not have an answer for you. Perhaps a person with more knowledge of java can explain why ‘PropertyChange’ is only fired for a subset of JLabels properties. As for the ‘PropertyPostSet’ listener this looks like a bug to me. I suspect that the MATLAB notation changes the UDD peer and generates the ‘PropertyPostSet’ event and synchronizes the java objects property. When the java notation is used it may be that the java object is set and then the UDD object is synchronized. If that is the order of events then this may be related to MATLABs lack of support for asynchronous events in COM objects. Both the java peer mechanism and COM support are based on UDD. The MathWorks explicitly states with COM that asynchronous events are not supported.

      Sorry I can’t be of more help,

      Donn

      • julien April 6, 2011 at 12:24

        Thank you for your answer Donn ! Unfortunately, I will have to deal with Bound properties (JavaBeans) to be sure that the properties I want to monitore fire PropertyChange events…
        Thanks again for your articles,
        Best Regards

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