Over the past few years I have shown numerous uses of Java components in Matlab, many of them built-into the Matlab environment and can be used as-is. I have been asked many times how I uncover these components and how I discover how to use them. The short answer is that this is indeed often not easy. The blog articles (and my book) only present “success stories“, i.e. cases where I was able to uncover the behavior, functionality and usage of such components; they do not present the numerous other cases where I have not been so successful.

Still, over the course of the past 10-15 years, I developed several tools that help me become more efficient in this work, and I’ve posted most of these on the File Exchange. I’ve already written here about the FindJObj utility, both as a means for uncovering the underlying Java reference of Matlab GUI controls, and as a means to visualize the GUI hierarchy of a specified window or container. I also wrote about my uiinspect utility, which analyzes the specified object in a compact and intuitive GUI window.

Today I wish to complete the picture by describing my checkClass utility. checkClass is more limited than uiinspect in the types of objects that it can analyze (almost only Java objects) and the information that it presents (for example, callbacks and properties are not listed separately). checkClass‘s main benefit is the fact that it is a very lightweight (230 lines of code), fast, GUI-less console application. checkClass highlights the differences between the analyzed class and its superclass, which is especially useful when investigating the functionality of objects. During the course of my work, I use checkClass for 95% of my investigations, and uiinspect/findjobj only for the remainder. For Java objects at least, a detailed console listing of the methods is quite enough, since properties are typically accessed via getPropName()/setPropName() accessor methods. The combination of checkClass and uiinspect can be very useful when investigating a new Java library or integrating a 3rd-party API.

Here is a sample output for the com.mathworks.mwswing.MJToggleButton class:

>> jButton = com.mathworks.mwswing.MJToggleButton;
>> checkClass(jButton)  % or: jButton.checkClass
Class com.mathworks.mwswing.MJToggleButton (uiinspect)
Superclass: javax.swing.JToggleButton
Methods in MJToggleButton missing in JToggleButton:
   hasFlyOverAppearance() : boolean
   isAutoMnemonicEnabled() : boolean
   isTextHidden() : boolean
Methods inherited & modified by MJToggleButton:
   getForeground() : java.awt.Color
   getParent() : java.awt.Container
   isFocusTraversable() : boolean
Interfaces in JToggleButton missing in MJToggleButton:
Interfaces in MJToggleButton missing in JToggleButton:

The interpretation is quite intuitive. For example, isTextHidden() is a class method that accepts no input args and returns a boolean result; setText() is a method that accepts a string and returns no result.

Each of the hyperlinks is linked to another checkClass on the specified class. This makes investigation of classes and their interconnections quite easy.

From this output, we learn that the MathWorks MJToggleButton class added the FlyOverAppearance and AutoMnemonicEnabled properties, together with their associated accessor methods. We also learn that MJToggleButton added a non-property method: hideText().

Finally, setFocusTraversable() was added as a setter method to the FocusTraversable property: the getter method isFocusTraversable() is already defined in the ancestor JToggleButton class (which is part of the standard Swing package) – MJToggleButton simply added a setter method.

Some classes (e.g., MJSlider) appear to be plain wrappers for their Swing ancestor:

>> checkClass('com.mathworks.mwswing.MJSlider') 
Class com.mathworks.mwswing.MJSlider (uiinspect)

Superclass: javax.swing.JSlider

Methods inherited & modified by MJSlider:

Interfaces in JSlider missing in MJSlider:

In other cases, MathWorks has extensively modified the base class functionality:

>> checkClass com.mathworks.mwswing.MJToolBar
Class com.mathworks.mwswing.MJToolBar (uiinspect)
Superclass: javax.swing.JToolBar
Methods in MJToolBar missing in JToolBar:
   addToggle(javax.swing.Action) : javax.swing.JToggleButton
   configure(com.mathworks.mwswing.ExtendedButton) (static)
   configureButton(com.mathworks.mwswing.MJButton) (static)
   configureButton(com.mathworks.mwswing.MJToggleButton) (static)
   configureButton(com.mathworks.mwswing.MJToggleButton, boolean) (static)
   createMacPressedIcon(javax.swing.Icon) : javax.swing.Icon (static)
   dispose(javax.swing.JToolBar) (static)
   getComponentExcludingMoreButton(int) : java.awt.Component
   getFlyOverBorder() : javax.swing.border.Border (static)
   getToggleFlyOverBorder() : javax.swing.border.Border (static)
   isFloating() : boolean
   isMarkedNonEssential(javax.swing.JComponent) : boolean (static)
   isMorePopupEnabled() : boolean
   isOnMoreMenu(java.awt.Component) : boolean
   markAsNonEssential(javax.swing.JComponent) (static)
Methods inherited & modified by MJToolBar:
   add(javax.swing.Action) : javax.swing.JButton
   getMinimumSize() : java.awt.Dimension
   getPreferredSize() : java.awt.Dimension
Interfaces in JToolBar missing in MJToolBar:
Static fields in MJToolBar missing in JToolBar:
   MORE_BUTTON_NAME                  = 'MoreButton'
   NON_ESSENTIAL_PROPERTY_KEY        = 'NonEssentialComponent'
Sub-classes in MJToolBar missing in JToolBar:

In this example, we see that the MJToolBar class includes 3 variants for the configureButton() method, and 2 variants for the dispose() method, accepting a different number and/or type of input parameters.

Similarly, for the CheckBoxList class:

>> checkClass com.mathworks.mwswing.checkboxlist.CheckBoxList
Class com.mathworks.mwswing.checkboxlist.CheckBoxList (uiinspect)

Superclass: com.mathworks.mwswing.MJList
Superclass: javax.swing.JList
Methods in JList missing in CheckBoxList:
Methods in CheckBoxList missing in JList:
   constrainViewerToCellHeight() : boolean
   getCellPainter(java.lang.Integer) : java.awt.Component
   getCellPainter(java.lang.Object) : java.awt.Component
   getCellViewerOffset(java.lang.Integer) : java.awt.Dimension
   getCellViewerOffset(java.lang.Object) : java.awt.Dimension

Here we see that two superclass constructor variants (accepting an array of Objects or a single Vector object) have been replaced by a single constructor that accepts a List object (this is considered a bad programming practice, by the way).

In this case, CheckBoxList extends MJList which is also a Matlab class, which itself extends the standard Swing JList. By default, checkClass compares the specified class object versus the nearest ancestor class that is non-MathWorks. We can modify this behavior by specifying a different super-class level:

>> checkClass('com.mathworks.mwswing.checkboxlist.CheckBoxList', 1)  % compare CheckBoxList to com.mathworks.mwswing.MJList
>> checkClass('com.mathworks.mwswing.checkboxlist.CheckBoxList', 2)  % compare CheckBoxList to javax.swing.JList (=default behavior)
>> checkClass('com.mathworks.mwswing.checkboxlist.CheckBoxList', 3)  % compare CheckBoxList to javax.swing.JComponent (=JList's superclass)
>> checkClass('com.mathworks.mwswing.checkboxlist.CheckBoxList', 4)  % compare CheckBoxList to java.awt.Container (=JComponent's superclass)
% ...and so on (up to java.lang.Object, which is the base class for all Java objects)

checkClass can inspect both class name and class objects. For example:

checkClass('java.lang.String')   % class name
checkClass(javax.swing.JButton)  % class object
jButton = javax.swing.JButton('Click me!'); 
jButton.checkClass;  % class object
checkClass('com.mathworks.mwswing.MJToolBar')  % class-name
checkClass(com.mathworks.mwswing.MJToolBar)    % class object

Class methods can also be inspected using methodsview or preferably uiinspect; properties and callbacks can be inspected by using get, inspect, or again uiinspect. Users may also try to search the Matlab-supplied m-files for sample usage of these classes. For example, Matlab 7.2’s uisetfont.m uses com.mathworks.mwswing.MJButton. Note that different Matlab releases use internal classes differently. Therefore, searching the m-file code base of different Matlab releases may yield additional clues.

I encourage you to download the checkClass utility and explore its code, and I welcome your feedback.

p.s. – Anyone watching the TV series “The Americans” may have noticed that in the season finale (“Echo“), which aired on May 21, the code listing of the Echo program, is actually that of a GUIDE-created Matlab m-file (linear_array_gui), plus some non-Matlab code (Ada?). Matlab’s GUIDE wasn’t available in the mid-1980s, when the story purportedly takes place, back in the days of a 640KB IBM PC with a single floppy drive, but it’s a nice anachronism. In any case the combination of the Matlab and Ada code would never have run… :-)

Categories: Java, Medium risk of breaking in future versions

Tags: ,

Bookmark and SharePrint Print

Leave a Reply

Your email address will not be published. Required fields are marked *