JIDE Property Grids

I would like to welcome guest blogger Levente Hunyadi.

Matlab’s property inspector

We often wish to edit properties of heterogeneous objects using a common interface. Matlab’s property inspector, invoked with the built-in inspect function, answers this need. The inspector is based on a two-column table of property names and values. Properties and their values are populated automatically, and the user can edit values in-place. The inspector enables property categorization, sub-categorization and sorting, which help users find and modify properties easily. For each property, the inspector displays a matching edit control: editbox/combobox/checkbox etc. This simplifies property value editing and prevents illegal value entry. Matlab’s GUI builder, GUIDE, uses the inspector to let users edit GUI properties such as position, color etc. It is also used by other tools such as the Plot Editor.

Matlab's built-in property inspector

Matlab's built-in property inspector

The Matlab inspector can be embedded, with not-too-much effort, within Matlab GUI applications. Examples of this can be found in the FindJObj and UIInspect utilities.

FindJObj - embedded property inspector

FindJObj - embedded property inspector

Unfortunately, Matlab’s property inspector is limited to Handle Graphics, Java and COM objects, and cannot be used for structures or user-defined Matlab classes. We shall see below how to set up our own property grid, populate it with data, and subscribe to property change events. This is a rather procedural approach. It is usually more convenient to use a declarative approach in which a structure or Matlab class is passed to a function that automatically discovers its properties and their meta-information. The Property Grid utility at Matlab File Exchange provides these services.

A simple property grid

Matlab’s property inspector is based on a property grid control by JIDE Software. JIDE Grids is a collection of components that extend the standard Java Swing JTable component, and is included in each Matlab installation (/java/jarext/jide/jide-grids.jar under the Matlab root). In particular, JIDE Grids includes the PropertyTable class, which is a fully customizable property grid component. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

There are several related classes associated with the PropertyTable class. First, a PropertyTableModel encapsulates all properties that are visualized in the property grid. Each property derives from the Property abstract class, which features some common actions to properties, most notably to get and set property value. DefaultProperty is a default concrete subclass of Property. Finally, PropertyPane decorates a property grid with icons for changing category view to alphabetically sorted view as well as expanding and collapsing categories, and a description text box at the bottom that can be shown or hidden.

Here are the DefaultProperty fields and their respective roles:

FieldRole
NameInteral property name, not necessarily displayed, used as a key to identify the property.
DisplayNameA short property name shown in the left column of the property grid.
DescriptionA concise description of the property, shown at the bottom of the property pane, below the grid.
TypeThe Java type associated with the property, used to invoke the appropriate renderer or editor.
EditorContextAn editor context object. If set, both the type and the context are used to look up the renderer or editor to use. This lets, for instance, one flag value to display as a true/false label, while another as a checkbox.
CategoryA string specifying the property’s category, for grouping purposes.
EditableSpecifies whether the property value is modifiable or read-only.
ValueThe current property value, as a Java object.

Just as with any Java object, these fields may either be accessed with the Java get/set semantics (e.g. getName() or setName(name)), or the Matlab get/set semantics (e.g. get(prop,’Name’) or set(prop,’Name’,name)). When using the Matlab syntax, remember to wrap the Java object in a handle() call, to prevent a memory leak.

To use a property grid in Matlab, first construct a set of DefaultProperty objects. For each object, set at least the name, type and initial value. Next, add the properties to a table model. Finally, construct a property grid with the given table model and encapsulate in a property pane:

% Initialize JIDE's usage within Matlab
com.mathworks.mwswing.MJUtilities.initJIDE;
 
% Prepare the properties list
list = java.util.ArrayList();
prop1 = com.jidesoft.grid.DefaultProperty();
prop1.setName('stringProp');
prop1.setType(javaclass('char',1));
prop1.setValue('initial value');
prop1.setCategory('My Category');
prop1.setDisplayName('Editable string property');
prop1.setDescription('A concise description for my property.');
prop1.setEditable(true);
list.add(prop1);
 
prop2 = com.jidesoft.grid.DefaultProperty();
prop2.setName('flagProp');
prop2.setType(javaclass('logical'));
prop2.setValue(true);
prop2.setCategory('My Category');
prop2.setDisplayName('Read-only flag property');
prop2.setEditable(false);
list.add(prop2);
 
% Prepare a properties table containing the list
model = com.jidesoft.grid.PropertyTableModel(list);
model.expandAll();
grid = com.jidesoft.grid.PropertyTable(model);
pane = com.jidesoft.grid.PropertyPane(grid);
 
% Display the properties pane onscreen
hFig = figure;
panel = uipanel(hFig);
javacomponent(pane, [0 0 200 200], panel);
 
% Wait for figure window to close & display the prop value
uiwait(hFig);
disp(prop1.getValue());

Here, com.mathworks.mwswing.MJUtilities.initJIDE is called to initialize JIDE’s usage within Matlab. Without this call, we may see a JIDE warning message in some Matlab releases. We only need to initJIDE once per Matlab session, although there is no harm in repeated calls.

javaclass is a function (included in the Property Grid utility, or directly downloadable from here) that returns a Java class for the corresponding Matlab type with the given dimension: javaclass(‘logical’) or javaclass(‘logical’,0) (a single logical flag value) returns a java.lang.Boolean class; javaclass(‘char’,1) (a character array) returns a java.lang.String class; javaclass(‘double’,2) (a matrix of double-precision floating point values) returns double[][].

javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. When the user closes the figure, prop.getValue() fetches and displays the new property value.

A simple user-defined property grid

A simple user-defined property grid

Next week’s article will show how to add more complex renderers and editors (display the flag value as a checkbox for example), define nested properties, and subscribe to property value change events. So stay tuned…

Related posts:

  1. Advanced JIDE Property Grids JIDE property grids can use complex cell renderer and editor components and can signal property change events asynchronously to Matlab callbacks...
  2. Using JIDE combo-boxes Matlab includes many custom JIDE combo-box controls that can be used in Matlab GUIs out of the box. ...
  3. 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. ...
  4. Property value change listeners HG handle property changes can be trapped in a user-defined callback. ...
  5. Plot LineSmoothing property LineSmoothing is a hidden and undocumented plot line property that creates anti-aliased (smooth unpixelized) lines in Matlab plots...
  6. Setting class property types Matlab's class properties have a simple and effective mechanism for setting their type....

Categories: Guest bloggers, GUI, Java, Medium risk of breaking in future versions, Undocumented feature

Tags: , , , , , , ,

Bookmark and SharePrint Print

16 Responses to JIDE Property Grids

  1. Jason McMains says:

    This is great! I love finding new ways to display information!

  2. Simon says:

    Hi,
    When executing the code I have a problem when initialising “prop1″ wth the DefaultProperty constructor:

    com.jidesoft.grid.DefaultProperty()
     ??? Undefined variable "com" or class "com.jidesoft.grid.DefaultProperty".

    I’m using Matlab R2007b, it might be linked to this?

    Thanks!

    • @Simon – which platform/OS/Java version are you using? i.e., what’s the output of ver in your Matlab Command Prompt?

    • Simon says:

      Hhi! Thanks for reactivity!

      here is what ‘ver’ gives me:

      ————————————————————————————-
      MATLAB Version 7.5.0.342 (R2007b)
      MATLAB License Number: 320981
      Operating System: Microsoft Windows XP Version 5.1 (Build 2600: Service Pack 3)
      Java VM Version: Java 1.6.0 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode
      ————————————————————————————-
      MATLAB Version 7.5 (R2007b)
      Data Acquisition Toolbox Version 2.11 (R2007b)
      Filter Design Toolbox Version 4.2 (R2007b)
      Fixed-Point Toolbox Version 2.1 (R2007b)
      MATLAB Compiler Version 4.7 (R2007b)
      Signal Processing Toolbox Version 6.8 (R2007b)
      XML Toolbox for Matlab Version 3.2.0

      Trademarks
      ——————
      MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, and xPC
      TargetBox are registered trademarks and SimBiology, SimEvents, and
      SimHydraulics are trademarks of The MathWorks, Inc. Other product or
      brand names are trademarks or registered trademarks of their respective
      holders.

    • Maarten van der Seijs says:

      Simon, I experienced the same with Matlab 2007b. Sadly enough, the DefaultProperty class is not included in the jide-grids.jar that comes with 2007b. There is a class Property, but this an abstract class and you cannot instantiate this without defining a concrete javaclass.

      As a rough solution, you may repace the jide .jar files in the folder ‘MATLABROOT\java\jarext\jide’ with the jar-files of for example Matlab 2008b (if you have it), this solves most of the problems. You can also include the jar files using the dynamic javaclasspath; this will add the DefaultProperty, but still gives errors.

      However, there should be a way to code the missing concrete classes in addition to the jide package of matlab 2007b. Personally, I would be very interested in such a solution. Perhaps someone with some more Java-skills can enlighten us? Meanwhile I have coded a property-inspector for matlab classes using the open-source package l2fprods, but I still have mixed feelings about its capabilities compared to the professional jide tools.

      A note to Yair and Levente: as you probably know, the class-structured PropertySheet and PropertyGrid products are not compatible with Matlab 2007b. I think the biggest (but solvable) problems lie in the method and property attributes, for example: replacing qualifiers like (Access = private) by (SetAccess = ‘private’) already solves most of the problems.

    • Thanks for the detailed comments, Maarten

  3. Jason says:

    Hi Yair,

    Can you explain where

    javaclass

    comes from? I tried

    which('javaclass')

    but it cannot find anything. I can’t seem to find this on your site in many places, nor is it a submission on the file exchange. I pasted the ver information below. Also, I did try this in R2009b with the same results.

    Thanks,
    Jason

    MATLAB Version 7.10.0.499 (R2010a)
    Operating System: Microsoft Windows XP Version 5.1 (Build 2600: Service Pack 3)
    Java VM Version: Java 1.6.0_12-b04 with Sun Microsystems Inc. Java HotSpot(TM) Client VM mixed mode

    • @Jason – as explained in the article, javaclass is a function that is included in the Property Grid utility, or directly downloadable from here. After downloading this Java class, you need to place it in your Java classpath (see javaclasspath).

    • Jason says:

      Hi Yair,

      My apologies. I thought the explanation for the example was all above the code itself. Leave it to a programmer to read a tutorial “serially”. :)

  4. Pingback: Date selection components | Undocumented Matlab

  5. Guillaume says:

    Hello,

    Thanks a lot for this incredibly helpful blog !

    I’ve got a question concerning this “homemade” Property inspector. I’ve been running your example with good results but now I would like my inspector to be resizable. Do you have any idea on how to achieve that ?

    Here is my way of doing right now ( adapted last lines of your example ) :

    % Display the properties pane onscreen
    hFig = figure('MenuBar','none',...
                  'Position',[200 200 200 300],...
                  'Name','My Property Inspector',...
                  'NumberTitle','off');
    panel = uipanel(hFig,'ResizeFcn',{@propResiz,pane});
    javacomponent(pane, [0 0 200 300], panel);
     
    % Wait for figure window to close & display the prop value
    uiwait(hFig);
    disp(prop1.getValue());
     
    function propResiz(src,eventdata,pane)
       pos = get(gcf,'Position');
       javacomponent(pane, [0 0 pos(3) pos(4)], src);
    end

    But I feel like there must be something better that I can’t see because of my lack of Java and javacomponent knowledge…

    Thanks,

    Guillaume

    • @Guillaume – use the second output argument returned from javacomponent and simply set its Units property to ‘normalized’ – it should then resize automatically with your figure, without the need for propResize at all:

      panel = uipanel(hFig);
      [hjPane, hcPane] = javacomponent(pane, [0 0 200 300], panel);
      set(hcPane,'Units','norm');

      If you do want to keep using ResizeFcn, then you need to fix your code: Each time you use javacomponent in your propResiz function, you are recreating the component container etc. Instead, create the Java pane just once and keep the container handle. Then simply set this container’s Position property in the propResiz function. Something like this:

      panel = uipanel(hFig);
      [hjPane, hcPane] = javacomponent(pane, [0 0 200 300], panel);
      set(panel,'ResizeFcn',{@propResiz,hcPane});
       
      function propResiz(src,eventdata,hcPane)
         pos = getpixelposition(gcf);  % ensure we get it in [pixels]
         set(hcPane, 'Position', [0 0 pos(3) pos(4)]);
      end

      Additional information on the javacomponent function can be found here.

  6. Pingback: uiinspect | Undocumented Matlab

  7. Pingback: propertiesGUI | Undocumented Matlab

  8. Pingback: treeTable | Undocumented Matlab

  9. Pingback: propertiesGUI | Undocumented Matlab

Leave a Reply

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

*

<pre lang="matlab">
a = magic(3);
sum(a)
</pre>