Semi-documented function – Undocumented Matlab https://undocumentedmatlab.com/blog_old Charting Matlab's unsupported hidden underbelly Tue, 29 Oct 2019 15:26:09 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.1 Sliders in Matlab GUI – part 2https://undocumentedmatlab.com/blog_old/sliders-in-matlab-gui-part-2 https://undocumentedmatlab.com/blog_old/sliders-in-matlab-gui-part-2#comments Thu, 05 Jul 2018 11:40:56 +0000 https://undocumentedmatlab.com/?p=7728 Related posts:
  1. Context-Sensitive Help Matlab has a hidden/unsupported built-in mechanism for easy implementation of context-sensitive help...
  2. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  3. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  4. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
]]>
Exactly 3 years ago I posted about various alternatives for embedding sliders in Matlab GUI. Today I will follow up on that post with a description of yet another undocumented builtin alternative – controllib.widget.Slider. A summary of the various alternatives can be seen in the following screenshot:

Slider alternatives in Matlab GUI

Slider alternatives in Matlab GUI

The controllib.widget.Slider component is a class in Matlab’s internal controllib package (last week I discussed a different utility function in this package, controllib.internal.util.hString2Char).

controllib.widget.Slider accepts 3 input arguments: containing figure handle, position in pixels, and data values. For example:

>> hSlider = controllib.widget.Slider(gcf, [10,10,100,50], 5:25)
hSlider = 
  Slider with properties:
 
        Data: [6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25]
       Index: 11
       Value: 15
    FontSize: 8
    Position: [10 10 100 50]

This creates an invisible axes at the specified figure location and displays graphic axes objects that provide the appearance of the slider. When you move the slider’s knob, or click its centerline or arrows (“Steppers”), the slider’s value changes accordingly.

You can attach a callback function to the slider as follows:

myCallback = @(h,e) disp(h.Value);  % as an example
addlistener(hSlider, 'ValueChanged', myCallback);

Note that controllib.widget.Slider is based on pure-Matlab code and fully-supported functionality. The Matlab source code is available (%matlabroot%/toolbox/shared/controllib/graphics/+controllib/+widget/Slider.m) and quite readable. So while it does not actually work with the new web-based uifigures, is should be relatively easy to adapt the code so that this component could be displayed in such uifigures.

Below is a script to recreate the screenshot above. Note the two alternative mechanisms for setting properties (Java setter-method notation, and HG set notation):

hFig = figure('Color','w');
 
% 1. controllib.widget.Slider
hSlider1 = controllib.widget.Slider(hFig, [10,10,100,50], 1:20);
hSlider1.Value = 12;
 
% 2. uicontrol
hSlider2 = uicontrol('style','slider', 'units','pixels', 'pos',[10,80,100,20], 'Min',0', 'Max',20, 'Value',12);
 
% 3. JScrollBar
jSlider3 = javaObjectEDT(javax.swing.JScrollBar);
jSlider3.setOrientation(jSlider3.HORIZONTAL);  % Java setter-method notation
set(jSlider3, 'VisibleAmount',1, 'Minimum',0, 'Maximum',20, 'Value',12);  % HG set notation
[hSlider3, hContainer3] = javacomponent(jSlider3, [10,130,100,20], hFig);
 
% 4. JSlider #1
jSlider4 = javaObjectEDT(javax.swing.JSlider(0,20,12))
jSlider4.setBackground(java.awt.Color.white);  % Java setter-method notation
set(jSlider4, 'MinorTickSpacing',1, 'MajorTickSpacing',4, 'SnapToTicks',true, 'PaintLabels',true);  % HG set notation
[hSlider4, hContainer4] = javacomponent(jSlider4, [10,180,100,30], hFig);
 
% 5. JSlider #2
jSlider5 = javaObjectEDT(javax.swing.JSlider(0,20,12))
jSlider5.setBackground(java.awt.Color.white);  % Java setter-method notation
jSlider5.setPaintTicks(true);
set(jSlider5, 'MinorTickSpacing',1, 'MajorTickSpacing',4, 'SnapToTicks',true, 'PaintLabels',true);  % HG set notation
[hSlider5, hContainer5] = javacomponent(jSlider5, [10,230,100,40], hFig);

For additional details regarding the other slider alternatives, please refer to my earlier post on this subject.

Have you ever used another interesting utility or class in Matlab’s builtin packages? If so, please tell us about it in a comment below.

]]>
https://undocumentedmatlab.com/blog_old/sliders-in-matlab-gui-part-2/feed 6
String/char compatibilityhttps://undocumentedmatlab.com/blog_old/string-char-compatibility https://undocumentedmatlab.com/blog_old/string-char-compatibility#comments Thu, 28 Jun 2018 12:57:59 +0000 https://undocumentedmatlab.com/?p=7710 Related posts:
  1. Undocumented mouse pointer functions Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....
  2. Matlab layout managers: uicontainer and relatives Matlab contains a few undocumented GUI layout managers, which greatly facilitate handling GUI components in dynamically-changing figures....
  3. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  4. uitree This article describes the undocumented Matlab uitree function, which displays data in a GUI tree component...
]]>
In numerous functions that I wrote over the years, some input arguments were expected to be strings in the old sense, i.e. char arrays for example, 'on' or 'off'. Matlab release R2016b introduced the concept of string objects, which can be created using the string function or [starting in R2017a] double quotes ("on").

The problem is that I have numerous functions that supported the old char-based strings but not the new string objects. If someone tries to enter a string object ("on") as input to a function that expects a char-array ('on'), in many cases Matlab will error. This by itself is very unfortunate – I would have liked everything to be fully backward-compatible. But unfortunately this is not the case: MathWorks did invest effort in making the new strings backward-compatible to some degree (for example, graphic object property names/values and many internal functions that now accept either form as input). However, backward compatibility of strings is not 100% perfect.

In such cases, the only solution is to make the function accept both forms (char-arrays and string objects), for example, by type-casting all such inputs as char-arrays using the builtin char function. If we do this at the top of our function, then the rest of the function can remain unchanged. For example:

function test(stage)
   if isa(stage,'string')      stage = char(stage);   end   % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays
 
   switch stage
      case 'stage 1', ...
      case 'stage 2', ...
      ...
   end
end

That was simple enough. But what if our function expects complex inputs (cell-arrays, structs etc.) that may contain strings in only some of their cells/fields?

Luckily, Matlab contains an internal utility function that can help us: controllib.internal.util.hString2Char. This function, whose Matlab source-code is available (%matlabroot%/toolbox/shared/controllib/general/+controllib/+internal/+util/hString2Char.m) recursively scans the input value and converts any string object into the corresponding char-array, leaving all other data-types unchanged. For example:

>> controllib.internal.util.hString2Char({123, 'char-array', "a string"})
ans =
  1×3 cell array
    {[123]}    {'char-array'}    {'a string'}
 
>> controllib.internal.util.hString2Char(struct('a',"another string", 'b',pi))
ans = 
  struct with fields:
    a: 'another string'
    b: 3.14159265358979

In order to keep our code working not just on recent releases (that support strings and controllib.internal.util.hString2Char) but also on older Matlab releases (where they did not exist), we simply wrap the call to hString2Char within a trycatch block. The adaptation of our function might then look as follows:

function test(varargin)
   try varargin = controllib.internal.util.hString2Char(varargin); catch, end   % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays
   ...
end

Note that controllib.internal.util.hString2Char is a semi-documented function: it contains a readable internal help section (accessible via help controllib.internal.util.hString2Char), but not a doc-page. Nor is this function mentioned anywhere in Matlab’s official documentation. I think that this is a pity, because it’s such a useful little helper function.

]]>
https://undocumentedmatlab.com/blog_old/string-char-compatibility/feed 16
Password & spinner controls in Matlab GUIhttps://undocumentedmatlab.com/blog_old/password-and-spinner-controls-in-matlab-gui https://undocumentedmatlab.com/blog_old/password-and-spinner-controls-in-matlab-gui#comments Wed, 14 Dec 2016 17:28:09 +0000 https://undocumentedmatlab.com/?p=6775 Related posts:
  1. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  2. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  3. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  4. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
]]>
I often include configuration panels in my programs, to enable the user to configure various program aspects, such as which emails should automatically be sent by the program to alert when certain conditions occur. Last week I presented such a configuration panel, which is mainly composed of standard documented Matlab controls (sub-panels, uitables and uicontrols). As promised, today’s post will discuss two undocumented controls that are often useful in similar configuration panels (not necessarily for emails): password fields and spinners.

Matlab GUI configuration panel including password and spinner controls (click to zoom-in)
Matlab GUI configuration panel including password and spinner controls (click to zoom-in)

Password fields are basically editboxes that hide the typed text with some generic echo character (such as * or a bullet); spinners are editboxes that only enable typing certain preconfigured values (e.g., numbers in a certain range). Both controls are part of the standard Java Swing package, on which the current (non-web-based) Matlab GUIs relies. In both cases, we can use the javacomponent function to place the built-in Swing component in our Matlab GUI.

Password field

The relevant Java Swing control for password fields is javax.swing.JPasswordField. JPasswordField is basically an editbox that hides any typed key with a * or bullet character.

Here’s a basic code snippet showing how to display a simple password field:

jPasswordField = javax.swing.JPasswordField('defaultPassword');  % default password arg is optional
jPasswordField = javaObjectEDT(jPasswordField);  % javaObjectEDT is optional but recommended to avoid timing-related GUI issues
jhPasswordField = javacomponent(jPasswordField, [10,10,70,20], gcf);

Password control

Password control

We can set/get the password string programmatically via the Text property; the displayed (echo) character can be set/get using the EchoChar property.

To attach a data-change callback, set jhPasswordField’s ActionPerformedCallback property.

Spinner control

detailed post on using spinners in Matlab GUI

The relevant Java Swing control for spinners is javax.swing.JSpinner. JSpinner is basically an editbox with two tiny adjacent up/down buttons that visually emulate a small round spinning knob. Spinners are similar in functionality to a combo-box (a.k.a. drop-down or pop-up menu), where a user can switch between several pre-selected values. They are often used when the list of possible values is too large to display in a combo-box menu. Like combo-boxes, spinners too can be editable (meaning that the user can type a value in the editbox) or not (the user can only “spin” the value using the up/down buttons).

JSpinner uses an internal data model. The default model is SpinnerNumberModel, which defines a min/max value (unlimited=[] by default) and step-size (1 by default). Additional predefined models are SpinnerListModel (which accepts a cell array of possible string values) and SpinnerDateModel (which defines a date range and step unit).

Here’s a basic code snippet showing how to display a simple numeric spinner for numbers between 20 and 35, with an initial value of 24 and increments of 0.1:

jModel = javax.swing.SpinnerNumberModel(24,20,35,0.1);
jSpinner = javax.swing.JSpinner(jModel);
jSpinner = javaObjectEDT(jSpinner);  % javaObjectEDT is optional but recommended to avoid timing-related GUI issues
jhSpinner = javacomponent(jSpinner, [10,10,70,20], gcf);

The spinner value can be set using the edit-box or by clicking on one of the tiny arrow buttons, or programmatically by setting the Value property. The spinner object also has related read-only properties NextValue and PreviousValue. The spinner’s model object has the corresponding Value (settable), NextValue (read-only) and PreviousValue (read-only) properties. In addition, the various models have specific properties. For example, SpinnerNumberModel has the settable Maximum, Minimum and StepSize properties.

To attach a data-change callback, set jhSpinner’s StateChangedCallback property.

I have created a small Matlab demo, SpinnerDemo, which demonstrates usage of JSpinner in Matlab figures. Each of the three predefined models (number, list, and date) is presented, and the spinner values are inter-connected via their callbacks. The Matlab code is modeled after the Java code that is used to document JSpinner in the official Java documentation. Readers are welcome to download this demo from the Matlab File Exchange and reuse its source code.

Matlab SpinnerDemo

Matlab SpinnerDemo

The nice thing about spinners is that you can set a custom display format without affecting the underlying data model. For example, the following code snippet update the spinner’s display format without affecting its underlying numeric data model:

formatStr = '$ #,##0.0 Bn';
jEditor = javaObject('javax.swing.JSpinner$NumberEditor', jhSpinner, formatStr);
jhSpinner.setEditor(jEditor);

Formatted spinner control

Formatted spinner control

For more information, refer to my detailed post on using spinners in Matlab GUI.

Caveat emptor

MathWorks’ new web-based GUI paradigm will most probably not directly support the Java components presented in today’s post, or more specifically the javacomponent function that enables placing them in Matlab GUIs. The new web-based GUI-building application (AppDesigner, aka AD) does contain a spinner, although it is [currently] limited to displaying numeric values (not dates/lists as in my SpinnerDemo). Password fields are not currently supported by AppDesigner at all, and it is unknown whether they will ever be.

All this means that users of Java controls who wish to transition to the new web-based GUIs will need to develop programmatic workarounds, that would presumably appear and behave less professional. It’s a tradeoff: AppDesigner does include features that improve GUI usability, not to mention the presumed future ability to post Matlab GUIs online (hopefully without requiring a monstrous Matlab Production Server license/installation).

In the past, MathWorks has posted a dedicated webpage to solicit user feedback on how they are using the figure’s JavaFrame property. MathWorks will presumably prepare a similar webpage to solicit user feedback on uses of the javacomponent function, so they could add the top items to AppDesigner, making the transition to web-based GUIs less painful. When such a survey page becomes live, I will post about it on this website so that you could tell MathWorks about your specific use-cases and help them prioritize their R&D efforts.

In any case, regardless of whether the functionality eventually makes it into AppDesigner, my hope is that when the time comes MathWorks will not pull the plug from non-web GUIs, and will still enable running them on desktops for backward compatibility (“legacy mode”). Users of existing GUIs will then not need to choose between upgrading their Matlab (and redeveloping their GUI as a web-based app) and running their existing programs. Instead, users will face the much less painful choice between keeping the existing Java-based programs and developing a web-based variant at some later time, separate from the choice of whether or not to upgrade Matlab. The increased revenue from license upgrades and SMS (maintenance plan) renewals might well offset the R&D effort that would be needed to keep supporting the old Java-based figures. The traumatic* release of HG2 in R2014b, where a less-than-perfect version was released with no legacy mode, resulting in significant user backlash/disappointment, is hopefully still fresh in the memory of decision makers and would hopefully not be repeated.

*well, traumatic for some at least. I really don’t wish to make this a debate on HG2’s release; I’d rather focus on making the transition to web-based GUIs as seamless as possible.

]]>
https://undocumentedmatlab.com/blog_old/password-and-spinner-controls-in-matlab-gui/feed 4
Viewing saved profiling resultshttps://undocumentedmatlab.com/blog_old/viewing-saved-profiling-results https://undocumentedmatlab.com/blog_old/viewing-saved-profiling-results#respond Wed, 18 May 2016 18:00:37 +0000 https://undocumentedmatlab.com/?p=6421 Related posts:
  1. Plot performance Undocumented inner plot mechanisms can significantly improve plotting performance ...
  2. Undocumented Profiler options part 2 Several undocumented features of the Matlab Profiler can make it much more useful - part 2 of series. ...
  3. Undocumented Profiler options part 3 An undocumented feature of the Matlab Profiler can report call history timeline - part 3 of series. ...
  4. Undocumented Profiler options part 4 Several undocumented features of the Matlab Profiler can make it much more useful - part 4 of series. ...
]]>
Many Matlab users know and utilize Matlab’s built-in Profiler tool to identify performance bottlenecks and code-coverage issues. Unfortunately, not many are aware of the Profiler’s programmatic interface. In past articles as well as my performance book I explained how we can use this programmatic interface to save profiling results and analyze it offline. In fact, I took this idea further and even created a utility (profile_history) that displays the function call timeline in a standalone Matlab GUI, something that is a sorely missed feature in the built-in profiler:

Function call timeline profiling (click for full-size image)
Function call timeline profiling (click for full-size image)

Today I will discuss a related undocumented feature of the Profiler: loading and viewing pre-saved profiling results.

Programmatic access to profiling results

Matlab’s syntax for returning the detailed profiling results in a data struct is clearly documented in the profile function’s doc page. Although the documentation does not explain the resulting struct and sub-struct fields, they have meaningful names and we can relatively easily infer what each of them means (I added a few annotation comments for clarity):

>> profile('on','-history')
>> surf(peaks); drawnow
>> profile('off')
>> profData = profile('info')
profData = 
      FunctionTable: [26x1 struct]
    FunctionHistory: [2x56 double]
     ClockPrecision: 4.10517962829241e-07
         ClockSpeed: 2501000000
               Name: 'MATLAB'
           Overhead: 0
 
>> profData.FunctionTable(1)
ans = 
          CompleteName: 'C:\Program Files\Matlab\R2016a\toolbox\matlab\specgraph\peaks.m>peaks'
          FunctionName: 'peaks'
              FileName: 'C:\Program Files\Matlab\R2016a\toolbox\matlab\specgraph\peaks.m'
                  Type: 'M-function'
              Children: [1x1 struct]
               Parents: [0x1 struct]
         ExecutedLines: [9x3 double]
           IsRecursive: 0
    TotalRecursiveTime: 0
           PartialData: 0
              NumCalls: 1
             TotalTime: 0.0191679078068094
 
>> profData.FunctionTable(1).Children
ans = 
        Index: 2   % index in profData.FunctionTable array
     NumCalls: 1
    TotalTime: 0.00136415141013509
 
>> profData.FunctionTable(1).ExecutedLines   % line number, number of calls, duration in secs
ans =
         43      1      0.000160102031282782
         44      1      2.29890096200918e-05
         45      1      0.00647592190637408
         56      1      0.0017093970724654
         57      1      0.00145036019621044
         58      1      0.000304193859437286
         60      1      4.39254290955326e-05
         62      1      3.44835144301377e-05
         63      1      0.000138755093778411
 
>> profData.FunctionHistory(:,1:5)
ans =
     0     0     1     1     0   % 0=enter, 1=exit
     1     2     2     1     6   % index in profData.FunctionHistory array

As we can see, this is pretty intuitive so far.

Loading and viewing saved profiling results

If we wish to save these results results in a file and later load and display them in the Profiler’s visualization browser, then we need to venture deeper into undocumented territory. It seems that while retrieving the profiling results (via profile(‘info’)) is fully documented, doing the natural complementary action (namely, loading this data into the viewer) is not. For the life of me I cannot understand the logic behind this decision, but that’s the way it is.

Luckily, the semi-documented built-in function profview does exactly what we need: profview accepts 2 input args (function name and the profData struct) and displays the resulting profiling info. The first input arg (function name) accepts either a string (e.g., 'peaks' or 'view>isAxesHandle'), or the numeric value 0 which signifies the home (top-level) page:

profView(0, profData);  % display profiling home (top-level) page
profview('peaks', profData);  % display a specific profiling page

I use the 0 input value much more frequently than the string inputs, because I often don’t know which functions exactly were profiled, and starting at the home page enables me to easily drill-down the profiling results interactively.

Loading saved profiling results from a different computer

Things get slightly complicated if we try to load saved profiling results from a different computer. If the other computer has exactly the same folder structure as our computer, and all our Matlab functions reside in exactly the same disk folders/path, then everything will work out of the box. The problem is that in general the other computer will have the functions in different folders. When we then try to load the profData on our computer, it will not find the associated Matlab functinos in order to display the line-by-line profiling results. We will only see the profiling data at the function level, not line level. This significantly reduces the usefulness of the profiling data. The Profiler page will display the following error message:

This file was modified during or after profiling. Function listing disabled.

We can solve this problem in either of two ways:

  1. Modify our profData to use the correct folder path on the local computer, rather than the other computer’s path (which is invalid on the local computer). For example:
    % Save the profData on computer #1:
    profData = profile('info');
    save('profData.mat', 'profData');
     
    % Load the profData on computer #2:
    fileData = load('profData.mat');
    profData = fileData.profData;
    path1 = 'N:\Users\Juan\programs\myProgram';
    path2 = 'C:\Yair\consulting\clients\Intel\code';
    for idx = 1 : numel(profData.FunctionTable)
       funcData = profData.FunctionTable(idx);
       funcData.FileName     = strrep(funcData.FileName,     path1, path2); 
       funcData.CompleteName = strrep(funcData.CompleteName, path1, path2);
       profData.FunctionTable(idx) = funcData;
    end
    % note: this loop can be vectorized if you wish
  2. As an alternative, we can modify Matlab’s profview.m function (%matlabroot%/toolbox/matlab/codetools/profview.m) to search for the function’s source code in the current Matlab path, if the specified direct path is not found (note that changing profview.m may require administrator priviledges). For example, the following is the code from R2016a’s profview.m file, line #506:
        % g894021 - Make sure the MATLAB code file still exists
        if ~exist(fullName, 'file')
            [~,fname,fext] = fileparts(fullName);  % Yair        fname = which([fname fext]);           % Yair        if isempty(fname)                      % Yair            mFileFlag = 0;
            else                                   % Yair            fullName = fname;                  % Yair        end                                    % Yair    end

These two workarounds complement each other: the first workaround does not require changing any installed Matlab code, and so is platform- and release-independent, but would require rerunning the code snippet for each and every profiling data file that we receive from external computers. On the other hand, the second workaround is a one-time operation that should work for multiple saved profiling results, although we would need to redo it whenever we install Matlab.

Additional profview customizations

Modifying the profview.m function can be used for different improvements as well.

For example, several years ago I explained how this function can be modified to display 1 ms timing resolutions, rather than the default 10 mS.

Another customization that I often do after I install Matlab is to change the default setting of truncating function lines longer than 40 characters – I typically modify this to 60 or 80 (depending on the computer monitor’s size…). All we need to do is to update the truncateDisplayName sub-function within profview.m as follows (taken from R2016a again, line #1762):

function shortFileName = truncateDisplayName(longFileName,maxNameLen)
%TRUNCATEDISPLAYNAME  Truncate the name if it gets too long
maxNameLen = max(60,maxNameLen);  % YairshortFileName = escapeHtml(longFileName);
if length(longFileName) > maxNameLen,
    shortFileName = char(com.mathworks.util.FileUtils.truncatePathname( ...
        shortFileName, maxNameLen));
end

You can see additional undocumented profiling features in the “Related posts” section below, as well as in Chapter 2 of my book “Accelerating MATLAB Performance“.

Do you have any other customization to the profiling results? If so, please share it in a comment.

]]>
https://undocumentedmatlab.com/blog_old/viewing-saved-profiling-results/feed 0
Editable combo-boxhttps://undocumentedmatlab.com/blog_old/editable-combo-box https://undocumentedmatlab.com/blog_old/editable-combo-box#comments Wed, 09 Oct 2013 15:38:55 +0000 https://undocumentedmatlab.com/?p=4246 Related posts:
  1. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
  2. Adding a context-menu to a uitree uitree is an undocumented Matlab function, which does not easily enable setting a context-menu. Here's how to do it....
  3. Customizing Matlab labels Matlab's text uicontrol is not very customizable, and does not support HTML or Tex formatting. This article shows how to display HTML labels in Matlab and some undocumented customizations...
  4. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
]]>
In previous articles, I explained how we can use findjobj to customize a Matlab uicontrol’s underlying Java control, thereby improving its appearance and functionality. My two previous articles on the Matlab editbox were a classic example of this mechanism. Unfortunately, this technique does not always work well, and an alternative mechanism needs to be used. One such case in point is the subject of today’s article.

Matlab combo-box (a.k.a. “popup-menu” or “drop-down”) controls are very simple controls that accept a list of strings from which a user can select. This is a very simple control that answers a wide range of use-cases. Unfortunately, it is quite limited. Among other limitations, we cannot modify the popup-panel’s appearance/functionality; we cannot select multiple items; and we cannot type-in a value in the control’s editbox. Today’s article will focus on the latter limitation, namely how to use an editable combo-box.

Trying to make Matlab’s standard combobox editable

We can indeed use findjobj to get a Matlab combo-box’s underlying Java control. This turns out to be a com.mathworks.hg.peer.ComboboxPeer$MLComboBox object, which extends the standard Java Swing JComboBox:

>> hCombo = uicontrol('Style','popup', 'String',{'a','b','c'});
>> jCombo = findjobj(hCombo)
jCombo =
	javahandle_withcallbacks.com.mathworks.hg.peer.ComboboxPeer$MLComboBox

This jCombo control has the Editable property that we can then try to override (the default value is false):

>> jCombo.setEditable(true);
>> jCombo.Editable = true;          % equivalent alternative
>> set(jCombo,'setEditable',true);  % equivalent alternative
Editable combo-box control

Editable combo-box control

The bad news is that the moment we enter some value (as in the screenshot here) that is not already a member of the pop-up panel (i.e., the cell-array in the String property), then the control disappears and a warning message is issued to the Matlab console:

Warning: popupmenu control requires that Value be an integer within String range
Control will not be rendered until all of its parameter values are valid
(Type "warning off MATLAB:hg:uicontrol:ParameterValuesMustBeValid" to suppress this warning.)

The reason for this behavior is that when the combo-box object detects that the text field’s content match none of the popup list items, it automatically sets jCombo‘s SelectedIndex to -1 and Matlab’s corresponding HG Value property to 0. At this point the Matlab implementation kicks in, hiding the uicontrol since it considers 0 an invalid value for the Value property. This is similar to the check being done to test for an empty HG String value (=no items):

>> set(hCombo, 'string', [])
popupmenu control requires a non-empty String
Control will not be rendered until all of its parameter values are valid.

We can clear these particular warnings via:

warning('off','MATLAB:hg:uicontrol:ParameterValuesMustBeValid')

but this does not prevent the control from being hidden – it just prevents the warning from showing on the Command Window.

We can dive deeper and try to modify the underlying data model and disassociate the Java control from HG, but let’s stop at this point since there is really no point considering the fact that there is a much simpler alternative.

Note: if you do decide to make the standard Matlab uicontrol editable, read here for a related customization that I posted several years ago.

The pure-Java alternative

Rather than customizing Matlab’s uicontrol, we can easily create an identical-looking control using the standard Java Swing JComboBox, which has none of these problems/limitations. We can create and display the component in one go using the semi-documented javacomponent function:

position = [10,100,90,20];  % pixels
hContainer = gcf;  % can be any uipanel or figure handle
options = {'a','b','c'};
model = javax.swing.DefaultComboBoxModel(options);
jCombo = javacomponent('javax.swing.JComboBox', position, hContainer);jCombo.setModel(model);jCombo.setEditable(true);

We can use a variant of javacomponent to create the component with the model in one go, replacing the highlighted lines above:

jCombo = javacomponent({'javax.swing.JComboBox',model}, position, hContainer);

Once we have the control ready, all we need to do is set its ActionPerformedCallback property to our Matlab callback function and we’re pretty-much set. We can get the currently-selected text using char(jCombo.getSelectedItem) and the selected list index (0-based) using jCombo.getSelectedIndex (which returns -1 if we entered a non-listed value, 0 for the first list item, 1 for the second etc.). More information can be found here.

Lesson learnt

In the past 20+ years of my professional life as engineer and development manager, my number one rule has always been:

DON’T FIX IT, IF IT AIN’T BROKE!

But sometimes, we should also remember an alternative version:
DON’T FIX IT, IF IT’S EASIER TO REPLACE!

Available report – “Advanced Customizations of Matlab Uicontrols”

Interested readers can find more information about these and other possible customizations in my report on “Advanced Customizations of Matlab Uicontrols“. This 90-page PDF report can be purchased here ($29, please allow 24 hours for delivery by email). The report explains how to customize Matlab’s uicontrols in ways that are simply not possible using documented Matlab properties. This includes treatment of push buttons, toggle buttons, radio buttons, checkboxes, editboxes, listboxes, popup menus (aka combo-boxes/drop-downs), sliders, labels, and tooltips. Much of the information in the report is also available in hard-copy format in chapter 6 of my Matlab-Java programming book.

]]>
https://undocumentedmatlab.com/blog_old/editable-combo-box/feed 20
Function definition meta-infohttps://undocumentedmatlab.com/blog_old/function-definition-meta-info https://undocumentedmatlab.com/blog_old/function-definition-meta-info#comments Wed, 04 Sep 2013 13:38:42 +0000 https://undocumentedmatlab.com/?p=4141 Related posts:
  1. Customizing print setup Matlab figures print-setup can be customized to automatically prepare the figure for printing in a specific configuration...
  2. Context-Sensitive Help Matlab has a hidden/unsupported built-in mechanism for easy implementation of context-sensitive help...
  3. Matlab DDE support Windows DDE is an unsupported and undocumented feature of Matlab, that can be used to improve the work-flow in the Windows environment...
  4. handle2struct, struct2handle & Matlab 8.0 This article explains how we can use a couple of undocumented functions in Matlab GUI, and what we can learn from this about Matlab's future....
]]>
Last week, Loren Shure posted an article explaining some documented ways to retrieve information about the type of Matlab functions. Loren basically showed how we can use a combination of the built-in nargin and exist functions to check whether a specified function-name is a regular m-file, a script filename, a class name or something else.

Today I will discuss several additional alternatives for retrieving information about a specified function:

The mtree() alternative

Reader Mark Brown has commented about an alternative, using the semi-documented built-in function mtree:

>> t = mtree('mtree.m','-file'); t.select(1).kind  % m-class file
ans =
CLASSDEF
 
>> t = mtree('profile.m','-file'); t.select(1).kind  % regular m-file function
ans =
FUNCTION
 
>> t = mtree('test.m','-file'); t.select(1).kind  % script file
ans =
EXPR

mtree contains numerous other goodies in its reported parse-tree, including information about who-calls-what-where, set/used info about variables and other information used in the lexical parsing of the m-file. mtree is a very sophisticated m-file function (or rather, a class), but is very heavily documented internally, and so it can definitely be read and followed. Unfortunately, much of the internal processing is carried out by opaque internal c-functions (mtreemex), but there is still plenty of processing left for the 3K+ lines of m-code. I plan to write an extensive article about this function one day.

Unlike many other internal m-files, which are much simpler, less well written and sparsely documented (if at all), but for which personal credit is included in a comment, mtree includes no personal credit although it appears to be very well written and documented. I have to congratulate the unknown author(s) for both their proficiency and humility. Addendum: This unknown author is now confirmed to have been Steve Johnson, author of the mlint set of tools and functionality.

For people worried about future compatibility, note that mtree has existed on the Matlab path (%matlabroot%\toolbox\matlab\codetools\@mtree\mtree.m) since 2006 (I think R2006a, but I’m not certain; it already had version 1.3 by R2007b; the latest version [R2013b] is 2.5). Considering the large investment in its code thus far, and the significant effort that it would take to create a replacement, I don’t see this function going away in the near future. Then again, there is no certainty about this, and it might well disappear without notice in some future Matlab release.

The getcallinfo() alternative

getcallinfo is another semi-documented internal function, which uses mtree to construct an m-file’s call-tree and reports the results in either a tabulated manner (if no output arg is request), or a struct array (as output arg):

>> getcallinfo('profile.m');
Name           Type             Starts Ends Length Full Name           
----           ----             ------ ---- ------ ---------           
profile        function             1   242    242 profile             
ParseInputs    subfunction        247   354     82 profile>ParseInputs 
ParseOption    nested-function    262   287     26 profile>ParseInputs/ParseOption
notifyUI       subfunction        356   370     15 profile>notifyUI    
 
>> s = getcallinfo('profile.m')
s = 
1x4 struct array with fields:
    type
    name
    fullname
    functionPrefix
    calls
    firstline
    lastline
    linemask
 
>> s(4).calls
ans = 
      fcnCalls: [1x1 struct]
    innerCalls: [1x1 struct]
      dotCalls: [1x1 struct]
       atCalls: [1x1 struct]
 
>> s(4).calls.fcnCalls
ans = 
    names: {'usejava'}
    lines: 359
 
>> s(4).calls.innerCalls
ans = 
    names: {1x0 cell}
    lines: [1x0 double]
 
>> s(4).calls.dotCalls
ans = 
    names: {'com.mathworks.mde.profiler.Profiler.start'  [1x40 char]  [1x41 char]}
    lines: [363 365 367]

Note: In order to use getcallinfo, we first need to fix a small internal bug in %matlabroot%/toolbox/matlab/codetools/getcallinfo.m, specifically within the displayStructure() sub-function. Modifying this file may require administrator privileges, and can be done in any text editor. The bug is that the keyword length is used as a variable in this function (line #136 in R2013b), and so cannot be used to reference the built-in function length(). We can either rename the variable (lines 136, 139, 145) or the function. It’s easiest to rename length() to numel() in line #147 (highlighted below):

130:   function displayStructure(strc)
           ...
136:       length = getString(message('MATLAB:codetools:reports:RptLength'));137:       fullName = getString(message('MATLAB:codetools:reports:RptFullName'));
138:       
139:       fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n',name,type,starts,ends,length,fullName);
140:       fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n', ...
               ...
145:           getDashesForString(length), ...
146:           getDashesForString(fullName));
147:       for n = 1:numel(strc)   % original code: n = 1:length(strc)               ...
152:       end
153:   end

The mlint() alternative

A few months ago, I wrote about mlint‘s undocumented interface and ability to report much internal information about the analyzed file. It is no surprise that one of the undocumented mlint options is -calls, which lists the calling-tree of an m-file. For example:

>> mlint profile.m -calls
M0 1 14 profile
E0 242 3 profile
U1 122 15 callstats
U1 131 11 ParseInputs
U1 133 10 MException
U1 134 5 throw
U1 161 8 lower
U1 164 9 notifyUI
U1 165 23 true
U1 169 23 false
U1 180 9 profreport
U1 183 13 usejava
U1 184 13 error
U1 184 19 message
U1 188 21 profile
U1 189 16 isempty
U1 192 17 profview
U1 236 9 warning
S0 248 7 ParseInputs
E0 354 3 ParseInputs
U1 260 1 error
U1 260 7 nargchk
U1 260 17 Inf
U1 260 21 nargin
N1 262 23 ParseOption
E1 287 7 ParseOption
U2 263 12 strcmp
...

In this report, the first character represents the function type:

  • M = main (top-level) function
  • S = sub-function
  • N = nested function
  • U = out-of-scope (external/built-in) function
  • A = anonymous function
  • E = end-of-function indication

The following numbers indicate the nesting level, line #, column # and function identifier (name). In essence, it’s the same information presented by getcallinfo, with two distinctions: getcallinfo‘s report is much more nicely formatted, and on the other hand getcallinfo does not include internal function-calls (maybe there’s an undocumented switch that I haven’t found for this).

In this regard, I wish to once again praise Urs Schwartz’s excellent farg and fdep utilities, which use this undocumented mlint syntax. They seem to out-perform and out-class the built-in depends function by a wide margin…

The which() alternative

The built-in which function can be used to report the file-path of m-file functions, or an indicate that the function is built-in (i.e., coded as a C/C++ function in one of the Matlab libraries):

>> str = which('perfTest')
str =
C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m
 
>> str = which('matlab.io.MatFile')
str =
C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\+matlab\+io\MatFile.m
 
>> str = which('sin')
str =
built-in (C:\Program Files\Matlab\R2013b\toolbox\matlab\elfun\@double\sin)
 
>> str = which('noSuchFunction')
str =
     ''

Note: a little-known option enables specifying sub-functions (although this does not work for nested functions for some unknown reason [bug? oversight?]):

>> str = which('nestedFuncName','in','MFileName');

The functions() alternative

Similar functionality can be achieved via the built-in functions, using function handles rather than function names:

>> functions(@perfTest)
ans = 
    function: 'perfTest'
        type: 'simple'
        file: 'C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m'
 
>> functions(@matfile)
ans = 
    function: 'matfile'
        type: 'simple'
        file: 'C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\matfile.m'
 
>> fType = functions(@(a)a+1)
fType = 
     function: '@(a)a+1'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}
 
>> functions(@transpose)
ans = 
    function: 'transpose'
        type: 'simple'
        file: ''

Unlike which, functions can also be used for both sub- and nested-functions:

% The following was called within the confines of a specific m-file function:
K>> fType = functions(@MFileName)
fType = 
    function: 'MFileName'
        type: 'simple'
        file: 'C:\Yair\MFileName.m'
 
K>> fType = functions(@subFunc)
fType = 
     function: 'subFunc'
         type: 'scopedfunction'
         file: 'C:\Yair\MFileName.m'
    parentage: {'subFunc'  'MFileName'}
 
K>> fType = functions(@nestedFunc)
fType = 
     function: 'MFileName/nestedFunc'
         type: 'nested'
         file: 'C:\Yair\MFileName.m'
    workspace: {[1x1 struct]}

Note that parentage and workspace are undocumented sub-fields of the returned struct: they are mentioned in the official doc page, but only in passing, without a format explanation. Also note that workspace is a cell array of a single element (contrary to the official doc – this is probably an internal bug), containing the actual workspace as a struct (fields = workspace variables). So it should be accessed as fType.workspace{1}.varName. Note that parentage and workspace are present only for certain types of function types.

Have you found any other nifty ways of retrieving function meta-info in run-time? Are you using such meta-info in an interesting manner? If so, please post a short comment below.

]]>
https://undocumentedmatlab.com/blog_old/function-definition-meta-info/feed 6
treeTablehttps://undocumentedmatlab.com/blog_old/treetable https://undocumentedmatlab.com/blog_old/treetable#comments Tue, 06 Aug 2013 07:10:20 +0000 https://undocumentedmatlab.com/?p=4062 Related posts:
  1. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  2. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  3. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  4. Plot-type selection components Several built-in components enable programmatic plot-type selection in Matlab GUI - this article explains how...
]]>
Since Matlab 7.0 (R14), Matlab has included a built-in GUI table control (uitable), at first as a semi-documented function and in release 7.6 (R2008a) as a fully-documented function. Useful as this control is, it lacks many features that are expected in modern GUIs, including sorting, filtering, cell-specific appearance and behavior, gridline customization etc. In past articles I have explained how uitable can be customized to achieve a more professional-looking table. I expanded on this in my book and my detailed uitable customization report.

Today I explain how a grouping hierarchy can be achieved in a table control that can be used in Matlab GUI. Such a control, which is a combination of a uitree and uitable, is typically called a tree-table. We can find numerous examples of it in everyday usage. I have encapsulated the functionality in a utility called treeTable on the Matlab File Exchange (#42946). The utility is provided with full source code and open-source license, and readers are welcome to use and modify it. A detailed explanation of the technicalities follows below, but if you’re just interested in having a sortable, rearrangeable, customizable, groupable table control, then all you need to do is download and use the utility.

treeTable utility

treeTable utility

headers = {'ID','Label','Logical1','Logical2','Selector','Numeric'};
data = {1,'M11',true, false,'One', 1011;  ...
        1,'M12',true, true, 'Two', 12;   ...
        1,'M13',false,false,'Many',13.4; ...
        2,'M21',true, false,'One', 21;  ...
        2,'M22',true, true, 'Two', 22;   ...
        3,'M31',true, true, 'Many',31;   ...
        3,'M32',false,true, 'One', -32;  ...
        3,'M33',false,false,'Two', 33; ...
        3,'M34',true, true, 'Many',34;  ...
};
selector = {'One','Two','Many'};
colTypes = {'label','label','char','logical',selector,'double'};
colEditable = {true, true, true, true, true}
icons = {fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/file_open.png'), ...
         fullfile(matlabroot,'/toolbox/matlab/icons/foldericon.gif'), ...
}
 
% Create the table in the current figure
jtable = treeTable('Container',gcf, 'Headers',headers, 'Data',data, ...
                   'ColumnTypes',colTypes, 'ColumnEditable',colEditable, ...
                   'IconFilenames',icons, 'Groupable',true, 'InteractiveGrouping',false);
 
% Collapse Row #6, sort descending column #5 (both are 0-based)
jtable.expandRow(5,false);  % 5=row #6; false=collapse
jtable.sortColumn(4,true,false);  % 4=column #5; true=primary; false=descending

The basic implementation concept

Unfortunately, uitable as-is cannot be customized to have groupable rows. It derives from JIDE’s SortableTable, rather than one of its groupable derived classes. On the other hand, uitree (don’t you agree that after a decade of this so-useful function being semi-documented it ought to be made official?) uses a different class hierarchy outside com.jidesoft.grid, and so it cannot be easily customized to display rows (as opposed to simple labels).

These limitations mean that we cannot use uitable or uitree and need to use a custom component. Luckily, such a component is available in all Matlab installations, on all platforms. It is part of the grid components package, on which Matlab GUI has relied for many years, 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). I discussed multiple JIDE controls in this blog over the years. You can find further details on JIDE Grids in the Developer Guide and the Javadoc documentation.

In fact, there are no less than three different components that we could use in our case: TreeTable, GroupTable and HierarchicalTable:

JIDE Grids class hierarchy (we normally use only one of the marked classes)

JIDE Grids class hierarchy (we normally use only one of the marked classes)

Note that we cannot use PropertyTable since that component is limited to only two columns. This is perfect for presenting property names and values, which is the reason it is used by Matlab’s inspect function and my generic propertiesGUI utility or Levente Hunyadi’s Property Grid utility. But in this case we wish to display a general multi-column table, so PropertyTable is a no-go.

TreeTable and GroupTable enable data rows that have similar type (class), whereas HierarchicalTable enables more flexibility, by allowing display of any component type (including full tables) in child rows. This flexibility comes with a price that customizing a HierarchicalTable is more difficult than TreeTable or GroupTable. These latter two components are quite similar; we use GroupTable, which extends TreeTable with the ability to automatically group rows that have the same value in a certain column.

Data model

The above-mentioned table classes all derive from SortableTable (which also underlies uitable). Unfortunately, something in the Matlab-Java interface breaks the ability of the JIDE table classes (or rather, their data model) to understand numeric values for what they are. As a result, sorting columns is done lexically, i.e. “123” < “34” < “9”. To fix this, I’ve included a custom Java table model (MultiClassTableModel) with the treeTable utility, which automatically infers the column type (class) based on the value in the top row (by overriding the getColumnClass() method).

Using this new class is pretty easy:

% Create the basic data-type-aware model using our data and headers
javaaddpath(fileparts(mfilename('fullpath')));  % add the Java class file to the dynamic java class-path
model = MultiClassTableModel(data, headers);  % data=2D cell or numeric array; headers=cell array of strings
 
% Wrap the standard model in a JIDE GroupTableModel
com.mathworks.mwswing.MJUtilities.initJIDE;  % initialize JIDE
model = com.jidesoft.grid.DefaultGroupTableModel(model);
model.addGroupColumn(0);  % make the first column the grouping column
model.groupAndRefresh;  % update the model data
 
% Use the generated model as the data-model of a JIDE GroupTable
jtable = eval('com.jidesoft.grid.GroupTable(model);');  % prevent JIDE alert by run-time (not load-time) evaluation
jtable = handle(javaObjectEDT(jtable), 'CallbackProperties');  % ensure that we're using EDT
 
% Enable multi-column sorting
jtable.setSortable(true);
 
% Present the tree-table within a scrollable viewport on-screen
scroll = javaObjectEDT(JScrollPane(jtable));
[jhscroll,hContainer] = javacomponent(scroll, tablePosition, hParent);
set(hContainer,'units', 'normalized','pos',[0,0,1,1]);  % this will resize the table whenever its container is resized

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.

javacomponent is the undocumented built-in Matlab function that adds Java Swing components to a Matlab figure, using the given dimensions and parent handle. I discussed it here.

Callbacks

There are two main callbacks that can be used with treeTable:

  • table data update – this can be set by uncommenting line #237 of treeTable.m:
    set(handle(getOriginalModel(jtable),'CallbackProperties'), 'TableChangedCallback', {@tableChangedCallback, jtable});

    which activates the sample tableChangedCallback() function (lines #684-694). Naturally, you can also set your own custom callback function.

    % Sample table-editing callback
    function tableChangedCallback(hModel,hEvent,jtable)
        % Get the modification data
        modifiedRow = get(hEvent,'FirstRow');
        modifiedCol = get(hEvent,'Column');
        label   = hModel.getValueAt(modifiedRow,1);
        newData = hModel.getValueAt(modifiedRow,modifiedCol);
     
        % Now do something useful with this info
        fprintf('Modified cell %d,%d (%s) to: %s\n', modifiedRow+1, modifiedCol+1, char(label), num2str(newData));
    end  % tableChangedCallback
  • row selection update – this is currently enabled in line #238 of treeTable.m:
    set(handle(jtable.getSelectionModel,'CallbackProperties'), 'ValueChangedCallback', {@selectionCallback, jtable});

    which activates the sample selectionCallback() function (lines #696-705). Naturally, you can also set your own custom callback function.

    % Sample table-selection callback
    function selectionCallback(hSelectionModel,hEvent,jtable)
        % Get the selection data
        MinSelectionIndex  = get(hSelectionModel,'MinSelectionIndex');
        MaxSelectionIndex  = get(hSelectionModel,'MaxSelectionIndex');
        LeadSelectionIndex = get(hSelectionModel,'LeadSelectionIndex');
     
        % Now do something useful with this info
        fprintf('Selected rows #%d-%d\n', MinSelectionIndex+1, MaxSelectionIndex+1);
    end  % selectionCallback

Some useful features of treeTable

treeTable with InteractiveGrouping, multi-column sorting, column rearranging

treeTable with interactive grouping, multi-column sorting, column rearranging

  • Sortable columns (including numeric columns)
  • Rearrangeable columns (drag headers left/right)
  • Auto-fit the table columns into the specified container width
  • Manually resize columns by dragging the column divider gridlines (not just the header dividers as in uitable)
  • Flat or groupable table, based on the specified Groupable parameter (default=true)
  • Ability to interactively group columns (just like Microsoft Outlook) using the InteractiveGrouping parameter (default=false)
  • Selector cells only show the drop-down arrow of the currently-selected cell (unlike uitable which shows it for all the column cells)
  • Selector cells enable editing, unlike uitable that only enables selecting among pre-defined values
  • Ability to attach user-defined icons for the leaf rows and the grouping rows (expanded/collapsed)
  • Easily attach custom cell editors or renderers to any table column (see my book and my detailed uitable customization report for details)

All of these features can be turned on/off using the control’s properties. Again, see my book or report for details (or ask me to do it for you…).

I remind readers that I will be visiting clients in Austria (Vienna, Salzburg) and Switzerland (Zurich) in August 18-29. If you live in the area, I will be happy to meet you to discuss how I could bring value to your needs, as consultant, contractor or trainer (more details).

]]>
https://undocumentedmatlab.com/blog_old/treetable/feed 85
Math libraries version info & upgradehttps://undocumentedmatlab.com/blog_old/math-libraries-version-info-upgrade https://undocumentedmatlab.com/blog_old/math-libraries-version-info-upgrade#comments Wed, 17 Jul 2013 18:00:36 +0000 https://undocumentedmatlab.com/?p=3998 Related posts:
  1. Handle Graphics Behavior HG behaviors are an important aspect of Matlab graphics that enable custom control of handle functionality. ...
  2. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  3. setPrompt – Setting the Matlab Desktop prompt The Matlab Desktop's Command-Window prompt can easily be modified using some undocumented features...
  4. Matlab DDE support Windows DDE is an unsupported and undocumented feature of Matlab, that can be used to improve the work-flow in the Windows environment...
]]>
version is a well-known Matlab function, which displays and returns information about the installed release:

>> [v,d] = version
v =
8.1.0.604 (R2013a)
d =
February 15, 2013
 
>> version('-java')
ans =
Java 1.6.0_17-b04 with Sun Microsystems Inc. Java HotSpot(TM) 64-Bit Server VM mixed mode

This is pretty boring stuff. But it starts to get interesting when we learn the undocumented fact that version can also report version information of the installed math libraries, starting in R2009b (Matlab 7.9):

FFTW logo
LAPACK logo

% R2013a (Matlab 8.1) on Win7 64b
>> version('-fftw')
ans =
FFTW-3.3.1-sse2-avx
 
>> version('-blas')
ans =
Intel(R) Math Kernel Library Version 10.3.11 Product Build 20120606 for Intel(R) 64 architecture applications
 
>> version('-lapack')
ans =
Intel(R) Math Kernel Library Version 10.3.11 Product Build 20120606 for Intel(R) 64 architecture applications
Linear Algebra PACKage Version 3.4.1

This information is sometimes useful, and is sometimes asked by users. Specific versions of BLAS, LAPACK and FFTW, which Matlab uses under its hood for all linear algebra and FFW computations, may exhibit idiosyncrasies that may be important in certain cases.

In versions up to R2013a, this information could also be retrieved using the internal.matlab.language.versionPlugins.* mex functions (e.g., internal.matlab.language.versionPlugins.blas, which runs the mex function %matlabroot%\toolbox\matlab\matfun\+internal\+matlab\+language\+versionPlugins\blas.mexw64). I’ll have a separate post (or series of posts) on Matlab’s internal.* functions, but at least with regards to version information they should NOT be relied upon. These interfaces (and their mex files) have changed their name and availability in some Matlab releases. Luckily, the version format that I showed above seems pretty stable and can be used as-is across multiple Matlab releases.

Here is a summary of the math libraries version in recent Matlab releases (Windows only):

Matlab releaseFFTWMKL (BLAS)LAPACK
R2009b SP1 (7.9.1)3.2.0-sse210.2.2 (2009-08-14)3.1.1
R2010a (7.10)3.2.2-sse210.2.2 (2009-08-14)3.2.1
R2010b (7.11)3.2.2-sse210.2.3 (2009-11-30)3.2.1
R2011a (7.12)3.2.2-sse210.2.6 (2010-07-28)3.2.2
R2011b (7.13)3.2.2-sse210.3.2 (2011-01-17)3.2.2
R2012a (7.14)3.2.2-sse210.3.5 (2011-07-20)3.3.1
R2012b (8.0)3.3.1-sse210.3.9 (2012-01-31)3.3.1
R2013a (8.1)3.3.1-sse2-avx10.3.11 (2012-06-06)3.4.1

Note that the LAPACK version is not always updated together with BLAS, although they are both part of Intel’s MKL (more on MKL below).

Addendum 2013-10-9: The undocumented -modules option of the version command provides the list of currently installed libraries:

>> version -modules
C:\Program Files\Matlab\R2013b\bin\win64\libut.dll Version < unknown >
C:\Program Files\Matlab\R2013b\bin\win64\libmwfl.dll Version < unknown >
C:\Program Files\Matlab\R2013b\bin\win64\libmx.dll Version 8.2.0.627
C:\Program Files\Matlab\R2013b\bin\win64\zlib1.dll Version < unknown >
...

[/Addendum]

Do you know of any other hidden version info anywhere in Matlab? If so, please post a comment below.

Upgrading library versions

It may well be possible for users to upgrade the internal libraries that Matlab uses to the latest version, assuming that backward compatibility is preserved in these libraries (which I suppose is the case). Naturally, you can only upgrade if you have a license for the upgraded library. For those interested, the libraries are located in %matlabroot%/bin/%arch%. For example: C:\Program Files\Matlab\R2013b\bin\win64\mkl.dll is Intel’s MKL (Math Kernel Library), which contains BLAS and LAPACK. Using this example, the latest official version of MKL is 11.0, which promises several important improvements over R2013a’s bundled version (10.3.11):

  • A fix for a bug in the svd routines
  • Improved performance
  • Improved support for Intel’s AVX2 instruction set (see related comment by Eric Sampson recently)
  • Improved functionality of MKL’s FFT implementation — Matlab’s *fft functions use FFTW, but in some cases MKL’s FFT implementation outperforms FFTW’s. You may wish to use MKL’s FFTW wrapper in such cases rather than calling MKL’s FFT routines directly.

Similarly, FFTW’s latest stable release is 3.3.3, offers advantages compared to R2013a’s bundled 3.3.1 version. Unfortunately, unlike MKL, FFTW is not bundled as a replaceable library file. I believe that FFTW is directly integrated in Matlab’s code. However, nothing prevents us from downloading the latest library and using it directly.

Warning! Needless to say, upgrading specific DLLs in Matlab can be extremely dangerous, and is entirely unsupported by MathWorks. Don’t come crying if Matlab starts to crash, or even worse – to return incorrect numerical results. If you design a car with upgraded libs, just let me know please, so that I’d know not to buy that model… I don’t often place such warnings on this blog. After all, this is a blog about undocumented / unsupported stuff. So when I do explicitly warn like this, you should take extra note. Upgrading Matlab’s math libs is purely an exercise for adventurous engineers who like to blow things up (oh, the sheer pleasure of charting undocumented waters!).

Addendum 2013-10-9: Amro’s comment below provides links to several articles that show how we can redirect Matlab to use a different BLAS/LAPACK library than the default (in MKL/ACML), by either setting the BLAS_VERSION environment variable or by updating the blas.spec and lapack.spec files in the libs folder. One user has reported that in his specific case this achieved a 30% speedup with no change to the code. Note that both of these options only apply to MKL/ACML, and not to other libraries – in those cases, AFAIK, only a direct replacement of the physical file will work. [/Addendum]

IPP library

If you have the Image Processing Toolbox (IPT), then you will also find Intel’s IPP (Integrated Performance Primitives) library (ippl.dll) in the same folder as mkl.dll. IPP is used by IPT for running some highly-optimized image-processing functions.

Intel logo Unfortunately, I could not find a parameter of version that returns the IPP version used by Matlab. However, we can get IPP’s version info using the ippl function, which is a semi-documented function in IPT (i.e., it has detailed help, but for some reason not an official doc page):

% R2013a (Matlab 8.1) on Win7 64b
>> [isIpplEnabled, ipplVersion] = ippl
isIpplEnabled =
     1                     % == true
ipplVersion = 
    'ippie9_t.lib 7.0 build 205.58 7.0.205.1054 e9   Apr 18 2011'

A few IPP-related aspects that you might find interesting in this regard:

  • Matlab currently (R2013a) uses IPPL 7.0 dated April 2011 – the latest version is 8.0 dated June 26, 2013 (only 3 weeks ago) includes significant performance boosts. Note that between 7.0 and 8.0 there was a 7.1 release that also had significant improvements, especially for modern CPUs. The 8.0 release changed some function names, so for compatibility with Matlab you might discover that you need to settle for the 7.1 DLL. This could still bring significant benefits.
  • Matlab currently limits IPP usage to uints, floats and (since R2012b) doubles, although (AFAIK) IPP also supports signed ints. For signed ints Matlab reverts to much slower functional processing, which seems a pity. I’m not 100% certain that these are indeed supported by IPP for the specific cases in which Matlab currently blocks them, but I think it’s worth a check – the performance boost could be worth the effort.
  • Matlab currently uses IPP only for some of the image-processing functions. It would make sense to use IPP much more widely, e.g. math, stats, convolution, FFT/FIR (I’m not sure it’s faster than FFTW, but it may be worth a check) and many others – IPP is much more versatile than an image processing toolkit (read here).

Even if we don’t upgrade the ippl.dll or mkl.dll version, we may still benefit by accessing them directly in Matlab and/or MEX code. They can be used in Matlab just like any other DLL. There are plenty of online resources that can help us program using the IPP/MKL functionalities, even on the Matlab CSSM newsgroup. It seems that quite a few Matlab users try to work directly with these libraries, sometimes perhaps not realizing that they are already pre-bundled within Matlab.

If you have successfully used one of these libraries directly in Matlab, and/or successfully upgraded the libs for some use, please share your experience by posting a comment below.

]]>
https://undocumentedmatlab.com/blog_old/math-libraries-version-info-upgrade/feed 7
Handle Graphics Behaviorhttps://undocumentedmatlab.com/blog_old/handle-graphics-behavior https://undocumentedmatlab.com/blog_old/handle-graphics-behavior#comments Wed, 06 Mar 2013 18:00:19 +0000 https://undocumentedmatlab.com/?p=3665 Related posts:
  1. Plot LimInclude properties The plot objects' XLimInclude, YLimInclude, ZLimInclude, ALimInclude and CLimInclude properties are an important feature, that has both functional and performance implications....
  2. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  3. Draggable plot data-tips Matlab's standard plot data-tips can be customized to enable dragging, without being limitted to be adjacent to their data-point. ...
  4. Customizing print setup Matlab figures print-setup can be customized to automatically prepare the figure for printing in a specific configuration...
]]>
Matlab’s Handle Graphics (HG) have been around for ages. Still, to this day it contains many hidden gems. Today I discuss HG’s Behavior property, which is a standard undocumented hidden property of all HG objects.

Behavior is not normally updated directly (although there is absolutely nothing to prevent this), but rather via the semi-documented built-in accessor functions hggetbehavior and hgaddbehavior. This manner of accessing Behavior is similar to its undocumented sibling property ApplicationData, which is accessed by the corresponding getappdata and setappdata functions.

Using HB behaviors

hggetbehavior with no input args displays a list of all pre-installed HG behaviors:

>> hggetbehavior
 
   Behavior Object Name         Target Handle
   --------------------------------------------
   'Plotedit'...................Any Graphics Object   
   'Print'......................Any Graphics Object   
   'Zoom'.......................Axes                  
   'Pan'........................Axes                  
   'Rotate3d'...................Axes                  
   'DataCursor'.................Axes and Axes Children
   'MCodeGeneration'............Axes and Axes Children
   'DataDescriptor'.............Axes and Axes Children
   'PlotTools'..................Any graphics object   
   'Linked'.....................Any graphics object   
   'Brush'......................Any graphics object

hggetbehavior can be passed a specific behavior name (or cell array of names), in which case it returns the relevant behavior object handle(s):

>> hBehavior = hggetbehavior(gca, 'Zoom')
hBehavior =
	graphics.zoombehavior
 
>> hBehavior = hggetbehavior(gca, {'Zoom', 'Pan'})
hBehavior =
	handle: 1-by-2

As the name indicates, the behavior object handle controls the behavior of the relevant action. For example, the behavior object for Zoom contains the following properties:

>> hBehavior = hggetbehavior(gca, 'Zoom');
>> get(hBehavior)
       Enable: 1        % settable: true/false
    Serialize: 1        % settable: true/false
         Name: 'Zoom'   % read-only
        Style: 'both'   % settable: 'horizontal', 'vertical' or 'both'

By setting the behavior’s properties, we can control whether the axes will have horizontal, vertical, 2D or no zooming enabled, regardless of whether or not the toolbar/menu-bar zoom item is selected:

hBehavior.Enable = false;         % or: set(hBehavior,'Enable',false)
hBehavior.Style  = 'horizontal';  % or: set(hBehavior,'Style','horizontal')

This mechanism is used internally by Matlab to disable zoom/pan/rotate3d (see %matlabroot%/toolbox/matlab/graphics/@graphics/@zoom/setAllowAxesZoom.m and similarly setAllowAxesPan, setAllowAxesRotate).

At this point, some readers may jump saying that we can already do this via the zoom object handle that is returned by the zoom function (where the Style property was renamed Motion, but never mind). However, I am just trying to show the general usage. Not all behaviors have similar documented customizable mechanisms. In fact, using behaviors we can control specific behaviors for separate HG handles in the same figure/axes.

For example, we can set a different callback function to different HG handles for displaying a plot data-tip (a.k.a. data cursor). I have explained in the past how to programmatically control data-tips, but doing so relies on the figure datacursormode, which is figure-wide. If we want to display different data-tips for different plot handles, we would need to add logic into our custom update function that would change the returned string based on the clicked handle. Using HG behavior we can achieve the same goal much easier:

% Use dataCursorLineFcn() for the line data-tip
bh = hggetbehavior(hLine,'DataCursor');
set(bh,'UpdateFcn',@dataCursorLineFcn);
 
% Use dataCursorAnnotationFcn() for the annotation data-tip
bh = hggetbehavior(hAnnotation,'DataCursor');
set(bh,'UpdateFcn',{@dataCursorAnnotationFcn,extraData});

Note: there is also the related semi-documented function hgbehaviorfactory, which is used internally by hggetbehavior and hgaddbehavior. I do not see any need for using hgbehaviorfactory directly, only hggetbehavior and hgaddbehavior.

Custom behaviors

The standard behavior objects are UDD schema objects (i.e., the old object-oriented mechanism in MATLAB). They are generally located in a separate folder beneath %matlabroot%/toolbox/matlab/graphics/@graphics/. For example, the Zoom behavior object is located in %matlabroot%/toolbox/matlab/graphics/@graphics/@zoombehavior/. These behavior object folders generally contain a schema.m file (that defines the behavior object class and its properties), and a dosupport.m function that returns a logical flag indicating whether or not the behavior is supported for the specified handle. These are pretty standard functions, here is an example:

% Zoom behavior's schema.m:
function schema
% Copyright 2003-2006 The MathWorks, Inc.
 
pk = findpackage('graphics');
cls = schema.class(pk,'zoombehavior');
 
p = schema.prop(cls,'Enable','bool');
p.FactoryValue = true;
 
p = schema.prop(cls,'Serialize','MATLAB array');
p.FactoryValue = true;
p.AccessFlags.Serialize = 'off';
 
p = schema.prop(cls,'Name','string');
p.AccessFlags.PublicSet = 'off';
p.AccessFlags.PublicGet = 'on';
p.FactoryValue = 'Zoom';
p.AccessFlags.Serialize = 'off';
 
% Enumeration Style Type
if (isempty(findtype('StyleChoice')))
    schema.EnumType('StyleChoice',{'horizontal','vertical','both'});
end
p = schema.prop(cls,'Style','StyleChoice');
p.FactoryValue = 'both';
% Zoom behavior's dosupport.m:
function [ret] = dosupport(~,hTarget)
% Copyright 2003-2009 The MathWorks, Inc.
 
% axes 
ret = ishghandle(hTarget,'axes');

All behaviors must define the Name property, and most behaviors also define the Serialize and Enable properties. In addition, different behaviors define other properties. For example, the DataCursor behavior defines the CreateNewDatatip flag and no less than 7 callbacks:

function schema
% Copyright 2003-2008 The MathWorks, Inc.
 
pk = findpackage('graphics');
cls = schema.class(pk,'datacursorbehavior');
 
p = schema.prop(cls,'Name','string');
p.AccessFlags.PublicSet = 'off';
p.AccessFlags.PublicGet = 'on';
p.FactoryValue = 'DataCursor';
 
schema.prop(cls,'StartDragFcn','MATLAB callback');
schema.prop(cls,'EndDragFcn','MATLAB callback');
schema.prop(cls,'UpdateFcn','MATLAB callback');
schema.prop(cls,'CreateFcn','MATLAB callback');
schema.prop(cls,'StartCreateFcn','MATLAB callback');
schema.prop(cls,'UpdateDataCursorFcn','MATLAB callback');
schema.prop(cls,'MoveDataCursorFcn','MATLAB callback');
 
p = schema.prop(cls,'CreateNewDatatip','bool');
p.FactoryValue = false;
p.Description = 'True will create a new datatip for every mouse click';
p = schema.prop(cls,'Enable','bool');
p.FactoryValue = true;
 
p = schema.prop(cls,'Serialize','MATLAB array');
p.FactoryValue = true;
p.AccessFlags.Serialize = 'off';

Why am I telling you all this? Because in addition to the standard behavior objects we can also specify custom behaviors to HG handles. All we need to do is mimic one of the standard behavior object classes in a user-defined class, and then use hgaddbehavior to add the behavior to an HG handle. Behaviors are differentiated by their Name property, so we can either use a new name for the new behavior, or override a standard behavior by reusing its name.

hgaddbehavior(hLine,myNewBehaviorObject)

If you wish the behavior to be serialized (saved) to disk when saving the figure, you should add the Serialize property to the class and set it to true, then use hgaddbehavior to add the behavior to the relevant HG handle. The Serialize property is searched-for by the hgsaveStructDbl function when saving figures (I described hgsaveStructDbl here). All the standard behaviors except DataDescriptor have the Serialize property (I don’t know why DataDescriptor doesn’t).

Just for the record, you can also use MCOS (not just UDD) class objects for the custom behavior, as mentioned by the internal comment within the hgbehaviorfactory function. Most standard behaviors use UDD schema classes; an example of an MCOS behavior is PlotEdit that is found at %matlabroot%/toolbox/matlab/graphics/+graphics/+internal/@PlotEditBehavor/PlotEditBehavor.m.

ishghandle‘s undocumented type input arg

Note that the Zoom behavior’s dosupport function uses an undocumented format of the built-in ishghandle function, namely accepting a second parameter that specifies a specific handle type, which presumably needs to correspond to the handle’s Type property:

ret = ishghandle(hTarget,'axes');

The hasbehavior function

Another semi-documented built-in function called hasbehavior is located right next to hggetbehavior and hgaddbehavior in the %matlabroot%/toolbox/matlab/graphics/ folder.

Despite its name, and the internal comments that specifically mention HG behaviors, this function is entirely independent of the HG behavior mechanism described above, and in fact makes use of the ApplicationData property rather than Behavior. I have no idea why this is so. It may be a design oversight or some half-baked attempt by a Mathworker apprentice to emulate the behavior mechanism. Even the function name is misleading: in fact, hasbehavior not only checks whether a handle has some “behavior” (in the 2-input args format) but also sets this flag (in the 3-input args format).

hasbehavior is used internally by the legend mechanism, to determine whether or not an HG object (line, scatter group, patch, annotation etc.) should be added to the legend. This can be very important for plot performance, since the legend would not need to be updated whenever these objects are modified in some manner:

hLines = plot(rand(3,3));
hasbehavior(hLines(1), 'legend', false);   % line will not be in legend
hasbehavior(hLines(2), 'legend', true);    % line will be in legend

(for anyone interested, the relevant code that checks this flag is located in %matlabroot%/toolbox/matlab/scribe/private/islegendable.m)

hasbehavior works by using a dedicated field in the handle’s ApplicationData struct with a logical flag value (true/false). The relevant field is called [name,'_hgbehavior'], where name is the name of the so-called “behavior”. In the example above, it creates a field called “legend_hgbehavior”.

Do you know of any neat uses for HG behaviors? If so, please post a comment below.

]]>
https://undocumentedmatlab.com/blog_old/handle-graphics-behavior/feed 5
Customizing menu items part 1https://undocumentedmatlab.com/blog_old/customizing-menu-items-part-1 https://undocumentedmatlab.com/blog_old/customizing-menu-items-part-1#comments Wed, 25 Apr 2012 18:14:08 +0000 https://undocumentedmatlab.com/?p=2897 Related posts:
  1. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  2. Context-Sensitive Help Matlab has a hidden/unsupported built-in mechanism for easy implementation of context-sensitive help...
  3. Undocumented mouse pointer functions Matlab contains several well-documented functions and properties for the mouse pointer. However, some very-useful functions have remained undocumented and unsupported. This post details their usage....
  4. Matlab layout managers: uicontainer and relatives Matlab contains a few undocumented GUI layout managers, which greatly facilitate handling GUI components in dynamically-changing figures....
]]>
Over the past years, I have not posted articles dealing with menu items. I have shown how to directly access menu items’ hidden handles, but not much more than that. A year ago I promised a mini-series on menu customizations, and it’s time to keep my promise. In today’s article, the first in the mini-series, I will present several undocumented menu customization topics that rely on pure-Matlab (i.e, no Java today). The next article in this series will focus on Java-based customizations.

Invoking menu item callbacks

As noted above, a figure window’s menu items can be directly accessed. Once we access a menu item’s handle, we can extract its Callback property and directly invoke it (for example, using the semi-documented hgfeval function). Note that menu callbacks are kept in Callback, while toolbar callbacks are kept in ClickedCallback.

Menu callbacks generally use internal semi-documented functions (i.e., having a readable help section but no doc, online help, or official support), which are part of Matlab’s uitools folder. These functions are specific to each top-level menu tree: filemenufcn, editmenufcn, viewmenufcn, insertmenufcn, toolsmenufcn, desktopmenufcn, winmenu, and helpmenufcn implement the figure’s eight respective top-level menu trees’ callbacks. These functions accept an optional figure handle (otherwise, gcbf is assumed), followed by a string specifying the specific menu item whose action needs to be run. webmenufcn implements the Help menu’s Web Resources sub-menu callbacks in a similar manner.

Use of these functions makes it easy to invoke a menu action directly from our Matlab code: instead of accessing the relevant menu item and invoking its Callback, we simply find out the menu item string in advance and use it directly. For example,

filemenufcn FileClose;
editmenufcn(hFig,'EditPaste');

uimenufcn is a related fully-undocumented (built-in) function, available since Matlab R11 (late 1990s). It accepts a figure handle (or the zero [0] handle to indicate the desktop) and action name. For example, the fully-documented commandwindow function uses the following code to bring the Command Window into focus:

uimenufcn(0, 'WindowCommandWindow');

Customizing menus via uitools

makemenu is another semi-documented uitool function that enables easy creation of hierarchical menu trees with separators and accelerators. It is a simple and effective wrapper for uimenu. makemenu is a useful function that has been made obsolete (grandfathered) without any known replacement.

makemenu accepts four parameters: a figure handle, a char matrix of labels (‘>’ indicating sub item, ‘>>’ indicating sub-sub items etc.; ‘&’ indicating keyboard shortcut; ‘^x’ indicating an accelerator key; ‘-‘ indicating a separator line), a char matrix of callbacks, and an optional char matrix of tags (empty by default). makemenu makes use of another semi-documented grandfathered function, menulabel, to parse the specified label components. makemenu returns an array of handles of the created uimenu items:

labels = str2mat('&File', ...    % File top menu
           '>&New^n', ...           % File=>New
           '>&Open', ...            % File=>Open
           '>>Open &document^d', ...    % File=>Open=>doc
           '>>Open &graph^g', ...       % File=>Open=>graph
           '>-------', ...          % File=>separator line
           '>&Save^s', ...          % File=>Save
           '&Edit', ...		% Edit top menu
           '&View', ...		% View top menu
           '>&Axis^a', ...          % View=>Axis
           '>&Selection region^r'); % View=>Selection
calls = str2mat('', ...		% no action: File top menu
           'disp(''New'')', ...
           '', ...			% no action: Open sub-menu
           'disp(''Open doc'')', ...
           'disp(''Open graph'')', ...
           '', ...			% no action: Separator
           'disp(''Save'')', ...
           '', ...			% no action: Edit top menu
           '', ...			% no action: View top menu
           'disp(''View axis'')', ...
           'disp(''View selection region'')');
handles = makemenu(hFig, labels, calls);
set(hFig,'menuBar','none');

A simple figure menu

A simple figure menu

Customizing menus via HTML

Since menu items share the same HTML/CSS support feature as all Java Swing labels, we can specify font size/face/color, bold, italic, underline, superscript/subscript, and practically any HTML formatting.

Note that some features, such as the font or foreground/background colors, have specific properties that we can set using the Java handle, instead of using HTML. The benefit of using HTML is that it enables setting all the formatting in a single property. HTML does not require using Java – just pure Matlab (see the following example).

Multi-line menu items can easily be done with HTML: simply include a <br> element in the label – the menu item will split into two lines and automatically resize vertically when displayed:

txt1 = '<html><b><u><i>Save</i></u>';
txt2 = '<font color="red"><sup>this file</sup></font></b></html>';
txt3 = '<br />this file as...';
set(findall(hFig,'tag','figMenuFileSave'),   'Label',[txt1,txt2]);
set(findall(hFig,'tag','figMenuFileSaveAs'), 'Label',[txt1,txt3]);

A multi-line HTML-rendered menu item

A multi-line HTML-rendered menu item

set(hMenuItem, 'Label',['<html>&2: C:\My Documents\doc.txt<br />'
   '<font size="-1" face="Courier New" color="red">&nbsp;&nbsp; '
   'Date: 15-Jun-2011 13:23:45<br />&nbsp;&nbsp; Size: 123 KB</font></html>']);

HTML-rendered menu items

HTML-rendered menu items

Much more complex customizations can be achieved using Java. So stay tuned to part 2 of this mini-series…

Note: Menu customization is explored in depth in section 4.6 of my book.

]]>
https://undocumentedmatlab.com/blog_old/customizing-menu-items-part-1/feed 10
Common javacomponent problemshttps://undocumentedmatlab.com/blog_old/common-javacomponent-problems https://undocumentedmatlab.com/blog_old/common-javacomponent-problems#comments Wed, 07 Dec 2011 18:00:38 +0000 https://undocumentedmatlab.com/?p=2607 Related posts:
  1. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  2. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  3. The javacomponent function Matlab's built-in javacomponent function can be used to display Java components in Matlab application - this article details its usages and limitations...
  4. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
]]>
The javacomponent function, which I described here last year, is a very important built-in Matlab function that enables placing Java components in Matlab figure GUI. Using javacomponent is pretty straight-forward. However, there are a few quirks that users should be aware of. In today’s article I’ll try to highlight some of them and discuss workarounds.

Figure visibility

Java components can only be placed onscreen when their containing Matlab figure has been made visible. This means that calls to javacomponent cannot be placed at the GUIDE-created *_OpeningFcn() function, because that function is invoked before the figure window is made visible.

Of course, we can always force the figure to become visible by setting the figure’s Visible property to 'on' in this function, before calling our javacomponents. But IMHO, a better option would be to simply place the javacomponents in the corresponding GUIDE-created *_OutputFcn() function, which is invoked after the figure window is made visible.

Auto-hiding with parent container

Java components are not automatically hidden with their ancestor container panel. This is also the root cause of the failure of Java components to disappear when switching tabs in a uitab.

One simple workaround for this that I often use is to link the Visible properties of the javacomponent container and the parent container:

jButton = javax.swing.JButton('click me!');
[jhButton, hContainer] = javacomponent(jButton, [100,100,60,30], hParent);
setappdata(hParent, 'linked_props__', linkprop([hParent,hContainer],'Visible'));

This has indeed been fixed in R2010b. If you ask me, this should have been standard behavior of javacomponent since the very beginning…

Although there is no need for the workaround in R2010b onward, I usually keep the workaround because it doesn’t hurt and enables backward compatibility for users who may have an older Matlab release.

Possible parent container types

javacomponent accepts parent handles that are figures, toolbars, uipanels, or uicontainers (some of these are not documented as possible parents in some Matlab releases, but they are). Since R2008a, parents of type uisplittool and uitogglesplittool can also be used. Unfortunately, frames are not uicontainers and, therefore, cannot be used as javacomponent parents.

Note: Due to a bug in R2007a, javacomponents cannot be added to uicontainers, since javacomponent.m checks if isa(hParent,'uicontainer') (and similarly for 'uiflowcontainer', 'uigridcontainer'), instead of isa(hParent,'hg.uicontainer') (and similarly for the others). If we modify javacomponent.m accordingly (add “hg.” in lines 98-100), this bug will be fixed. Since R2007b, isa(…,'hg.uicontainer') is equivalent to isa(…,'uicontainer'), so this fix is unnecessary.

Input parameters

Unlike many other Matlab functions, javacomponent does not accept optional parameter-value (P-V) pairs. If we want to customize the appearance of the Java component, it is better to create it , customize it, and only then to present it onscreen using javacomponent. If we first present the component and then customize it, there might be all sorts of undesirable flicker effects while the component is changing its properties.

One of the parameters that unfortunately cannot be customized before calling javacomponent is the component’s position onscreen. javacomponent only accepts a position vector in pixel units. To modify the component to use normalized units, we need to modify the container’s properties:

jButton = javax.swing.JButton('click me!');
[jhButton, hContainer] = javacomponent(jButton, [100,100,60,30], gcf);
set(hContainer, 'Units','norm');

Similarly, we can set the container’s UserData and ApplicationData only after the call to javacomponent.

Background color

The default background color of javacomponents is a slightly different shade of gray than the default uicontrol background color. Please refer to my recent article for a detailed discussion of this issue.

Vertical alignment

Java components are slightly mis-aligned vertically with combo-box (Style=’popup’) uicontrols, even when positioned using the same Y position. This is actually due to an apparent bug in Matlab’s implementation of the combo-box uicontrol, and not in the Java component’s: Apparently, the Matlab control does not obey its specified height and uses some other default height.

If we place javacomponents side-by-side with a regular Matlab popup uicontrols and give them all the same Y position, we can see this mis-alignment. It is only a few pixels, but the effect is visible and disturbing. To fix it, we need to add a small offset to the javacomponent‘s container’s Position property to make both the initial Y position slightly lower, and the height value slightly higher than the values for the corresponding Matlab combo-box control.

Callbacks

Unlike Matlab uicontrol callbacks, Java callbacks are activated even when the affected value does not change. Therefore, setting a value in the component’s callback could well cause an infinite loop of invoked callbacks.

Matlab programmers often use the practice of modifying component value within the callback function, as a means of fixing user-entered values to be within a certain data range, or in order to format the displayed value. This is relatively harmless in Matlab (if done correctly) since updating a Matlab uicontrol‘s value to the current value does not retrigger the callback. But since this is not the case with Java callbacks, users should beware not to use the same practice there. In cases where this cannot be avoided, users should at least implement some sort of callback re-entrancy prevention logic.

EDT

Java components typically need to use the independent Java Event processing Thread (EDT). EDT is very important for Matlab GUI, as explained in this article. Failure to use EDT properly in Matlab can lead to unexpected GUI behavior and even Matlab hangs or crashes.

If the javacomponent function is called in a very specific syntax format where the first input arg is a string (the name of the Java class to be created), then the newly-created component is placed on the EDT. However, this is not the normal manner in which javacomponent is used: A much more typical use-case is where javacomponent is passed a reference handle to a previously-created Java component. In such cases, it is the user’s responsibility to place the component on the EDT. Until R2008a this should be done using the awtcreate function; since R2008b, we can use the much simpler javaObjectEDT function (javaObjectEDT actually existed since R2008a, but was buggy on that release so I suggest using it only starting in R2008b; it became documented starting in R2009a). In fact, modern javacomponent saves us the trouble, by automatically using javaObjectEDT to auto-delegate the component onto the EDT, even if we happen to have created it on the MT.

The paragraph above may lead us to believe that we only need to worry about EDT in R2008a and earlier. Unfortunately, this is not the case. Modern GUI requires using many sub-components, that are attached to their main component (e.g., CellRenderers and CellEditors). javacomponent only bothers to place the main component on the EDT – not any of the sub-components. We need to handle these separately. Liberally auto-delegating components to the EDT seems like a safe and painless habit to have.

]]>
https://undocumentedmatlab.com/blog_old/common-javacomponent-problems/feed 28
Types of undocumented Matlab aspectshttps://undocumentedmatlab.com/blog_old/types-of-undocumented-matlab-aspects https://undocumentedmatlab.com/blog_old/types-of-undocumented-matlab-aspects#respond Thu, 24 Nov 2011 18:00:36 +0000 https://undocumentedmatlab.com/?p=2534 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. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  3. Matlab’s HG2 mechanism HG2 is presumably the next generation of Matlab graphics. This article tries to explore its features....
  4. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
]]>
Why are there so many undocumented aspects in Matlab?

This is a great question, recently asked by a reader of this blog, so I wanted to expand on it in next week’s article. Before specifying the different reasons, let’s map the nature of undocumented aspects that we find in Matlab.

The term undocumented/unsupported (as opposed to mis-documentated or deprecated) actually refers to quite a large number of different types.
In the following list, the hyperlinks on the list-item titles lead to a list of corresponding articles on this website:

  • Undocumented functions
    Matlab functions which appears nowhere in the documentation, are usually built-in functions (do not have an m-file) and can only be inferred from online CSSM posts or usage within one of the Matlab m-functions installed with Matlab (the latter being the usual case). None of these functions is officially supported by MathWorks. MEX is an important source for such functions.

  • Semi-documented functions
    Matlab functionality which exists in Matlab m-functions installed with Matlab, but have their main comment separated from the H1 comment line, thereby hiding it from normal view (via Matlab’s help function). The H1 comment line itself is simply a standard warning that this function is not officially supported and may change in some future version. To see the actual help comment, simply edit the function (using Matlab’s edit function or any text editor) and place a comment sign (%) at the empty line between the H1 comment and the actual help section. The entire help section will then onward be visible via the help function:

            function [tree, container] = uitree(varargin)
            % WARNING: This feature is not supported in MATLAB
            % and the API and functionality may change in a future release.
    fix =>  %
            % UITREE creates a uitree component with hierarchical data in a figure window.
            %   UITREE creates an empty uitree object with default property values in
            %   a figure window.
            %...

    These functions are not documented in the full documentation (via Matlab’s doc function, or online). The odd thing is that some of these functions may appear in the category help output (for example, help(‘uitools’)), and in some cases may even have a fully-visible help section (e.g., help(‘setptr’)), but do not have any online help documentation (docsearch(‘setptr’) fails, and doc(‘setptr’) simply displays the readable help text).

    All these functions are officially unsupported by MathWorks, even when having a readable help section. The rule of thumb appears to be that a Matlab function is supported only if it has online documentation. Note, however, that in some rare cases a documentation discrepancy may be due to a MathWorks documentation error, not to unsupportability…

  • Helper functions
    Many fully-supported Matlab functions use helper functions that have a specific use in the main (documented) function(s). Often, these helper functions are tightly-coupled to their documented parents and are useless as stand-alone functions. But quite a few of them have quite useful stand-alone use, as I’ve already shown in some past articles.

  • Undocumented features and properties
    Features of otherwise-documented Matlab functions, which appear nowhere in the official documentation. You guessed it – these are also not supported by MathWorks… Like undocumented functions, you can only infer such features by the occasional CSSM post or a reference somewhere in Matlab’s m-code.

  • Semi-documented features
    Features of otherwise-documented Matlab functions, which are documented in a separate section beneath the main help section, and nowhere else (not in the full doc not the online documentation). If you did not know in advance that these features existed, you could only learn of them by manually looking at Matlab’s m-files (which is what I do in most cases…).

  • Undocumented properties
    Many Matlab objects have internal properties, which can be retrieved (via Matlab’s get function) and/or set (via the set function) programmatically. All these properties are fully documented. Many objects also possess hidden properties, some of which are very interesting and useful, but which are undocumented and (oh yes) unsupported. Like undocumented features, they can only be inferred from CSSM or existing code. In a recent article I described my getundoc utility, which lists these undocumented properties of specified objects.

  • Internal Matlab classes
    Matlab uses a vast array of specialized Java classes to handle everything from algorithms to GUI. These classes are (of course) undocumented/unsupported. They can often be accessed directly from the Matlab Command Window or user m-files. GUI classes can be inferred by inspecting the figure frame’s Java components, and non-GUI classes can often be inferred from references in Matlab’s m-files.

  • Matlab-Java integration
    Matlab’s GUI interface, as well as the Java-to-Matlab interface (JMI) is fully undocumented and unsupported. In addition to JMI, there are other mechanisms to run Matlab code from within Java (namely JMI, COM and DDE) – these are all unsupported and by-and-large undocumented.

  • Matlab’s UDD mechanism
    UDD (Unified Data Definition?) is used extensively in Matlab as the internal object-oriented mechanism for describing object properties and functionalities. We can use UDD for a wide variety of uses. UDD was described in a series of articles here in early 2011.

Next week I will list the reasons that cause MathWorks to decide whether a particular feature or property should be documented or not.

]]>
https://undocumentedmatlab.com/blog_old/types-of-undocumented-matlab-aspects/feed 0
Javacomponent background colorhttps://undocumentedmatlab.com/blog_old/javacomponent-background-color https://undocumentedmatlab.com/blog_old/javacomponent-background-color#comments Wed, 12 Oct 2011 14:39:43 +0000 https://undocumentedmatlab.com/?p=2459 Related posts:
  1. Borderless button used for plot properties A borderless button can be used to add unobtrusive functionality to plot axes...
  2. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  3. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  4. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
]]>
In this website, I have often shown how Matlab application functionality can be significantly enhanced by including Java components in the Matlab GUI, using the built-in semi-documented javacomponent function (which I described here last year).

Using java components in Matlab is simple and easy, but there are a few annoying catches. One of these is the fact that the default Matlab figure background color ([0.8, 0.8, 0.8]) is a different shade of gray than the default uicontrol background color ([0.9255, 0.9137, 0.847]). javacomponents use the same background color as uicontrols.

hPanel = uipanel('units','pixe', 'pos',[30,30,200,100], 'title','Matlab uipanel');
jLabel = javax.swing.JLabel('Java Label');
[jhlabel,jContainer]=javacomponent(jLabel, [250,50,100,50], gcf);

Javacomponents use different default background color than figures

Javacomponents use different default background color than figures

While Matlab users are familiar with updating Matlab colors, doing so with Java colors is a bit different. We have two basic ways to align the javacomponent background color with the figure’s: either change the figure’s Color property to the Java component’s bgcolor, or vice versa:

Changing the javacomponent‘s background color to the figure color

% Fix the Java component:
% Variant #1
bgcolor = get(gcf, 'Color');
jLabel.setBackground(java.awt.Color(bgcolor(1),bgcolor(2),bgcolor(3)));
 
% Variant #2
bgcolor = num2cell(get(gcf, 'Color'));
jLabel.setBackground(java.awt.Color(bgcolor{:}));
 
% Fix the Matlab panel uicontrol
set(hPanel, 'BackgroundColor', get(gcf,'Color'));

controls with fixed background colors

controls with fixed background colors

Changing the figure’s color to the javacomponent‘s background color

bgcolor = jLabel.getBackground.getComponents([]);
set(gcf, 'Color', bgcolor(1:3));

figure with modified color to match the controls

figure with modified color to match the controls

Look at the list of related posts below for other articles related to colors in Matlab.

]]>
https://undocumentedmatlab.com/blog_old/javacomponent-background-color/feed 3
Bug and workaround in timeseries plothttps://undocumentedmatlab.com/blog_old/bug-and-workaround-in-timeseries-plot https://undocumentedmatlab.com/blog_old/bug-and-workaround-in-timeseries-plot#comments Wed, 07 Sep 2011 18:41:33 +0000 https://undocumentedmatlab.com/?p=2428 Related posts:
  1. Matlab layout managers: uicontainer and relatives Matlab contains a few undocumented GUI layout managers, which greatly facilitate handling GUI components in dynamically-changing figures....
  2. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  3. uitree This article describes the undocumented Matlab uitree function, which displays data in a GUI tree component...
  4. handle2struct, struct2handle & Matlab 8.0 This article explains how we can use a couple of undocumented functions in Matlab GUI, and what we can learn from this about Matlab's future....
]]>
I was about to write on something completely different today, when I discovered the following internal Matlab bug (and workaround) that I thought could be useful to some readers, so I changed my plans and the original article will see light next week (or the next, or whenever…).

The bug

Try the following code snippet:

today = fix(now);
ts = timeseries(rand(1,201), datestr(today-200:today));
figure;
hPanel = uipanel('units','norm','pos',[.2,.2,.5,.5]);
hAxes = axes('Parent',hPanel, 'units','norm');
plot(ts, 'Parent',hAxes);

As you can see, the plot’s x-tick labels are all bunched together:

Timeseries plot bug (note x tick labels)

Timeseries plot bug (note x tick labels)

The workaround

I debugged the problem and traced it to line #317 of …\R2011b\toolbox\matlab\timeseries\@timeseries\plot.m (in the R2011b installation):

axpos = hgconvertunits(f,get(ax,'Position'),get(ax,'Units'),'normalized',f);

This line uses hgconvertunits to get the figure-based normalized units of the axes. hgconvertunits is an internal semi-documented helper function that convert a Handle-Graphics position vector in one set of units into another position vector in other units based on some other reference HG object. For example, it can tell me what the position of an internal control is in normalized figure units, even if the control is deeply nested within multiple panels. Which is exactly what it tries to do in this case.

Unfortunately, hgconvertunits apparently has a bug that causes it to return the parent-based normalized position values rather than the figure-based ones in this particular case. This causes the function to think that the axes is much bigger than it really is, and therefore it uses more x-tick labels than it should.

This hgconvertunits bug may very possibly affect numerous other Matlab functions that use this built-in function. The correct fix is to fix the hgconvertunits function. However, since this is an non-modifiable internal function, I found the following workaround for the timeseries plot only, by replacing the above line with the following:

axpos = hgconvertunits(f,getpixelposition(ax,f),'pixel','normalized',f);

Timeseries plot fix (note x tick labels)

Timeseries plot fix (note x tick labels)

Now the x-tick labels appear nicely, including during resize and zooming.

This problem occurs on R2011b. I was able to recreate the same problem and use the same fix back to R2010b. I do not know how far earlier the bug goes…

I reported the problem today (1-FEM0L7 for anyone interested). If I learn of a patch for hgconvertunits I will post an addendum on this page.

]]>
https://undocumentedmatlab.com/blog_old/bug-and-workaround-in-timeseries-plot/feed 4
Uitable sortinghttps://undocumentedmatlab.com/blog_old/uitable-sorting https://undocumentedmatlab.com/blog_old/uitable-sorting#comments Tue, 26 Jul 2011 18:00:01 +0000 https://undocumentedmatlab.com/?p=2391 Related posts:
  1. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  2. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
  3. treeTable A description of a sortable, groupable tree-table control that can be used in Matlab is provided. ...
  4. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
]]>
uitable is probably the most complex basic GUI controls available in Matlab. It displays data in a table within a figure, with settable properties as with any other Matlab Handle-Graphics (HG) control. After many years in which the uitable was available but semi-documented and not officially supported in Matlab, it finally became fully documented and supported in R2008a (aka Matlab 7.6). At that time its internal implementation has changed from a MathWorks-developed Java table to a JIDE-based Java table (another JIDE-derived table was described here last year). Since R2008a, both versions of uitable are available – the old version is available by adding the ‘v0’ input arg.

Matlab’s uitable exposes only a very limited subset of functionalities and properties to the user. Numerous other functionalities are available by accessing the underlying Java table and hidden Matlab properties. Today I will describe a very common need in GUI tables, that for some unknown reason is missing in Matlab’s uitable: Sorting table data columns.

Last week I explained how we can modify table headers of an ActiveX table control to display sorting icons. In that case, sorting was built-in the control, and the question was just how to display the sorting arrow icon. Unfortunately, Matlab’s uitable does not have sorting built-in, although it’s quite easy to add it, as I shall now show.

Old uitable sorting

The old uitable is the default control used until R2007b, or that can be selected with the ‘v0’ input arg since R2008a. It was based on an internal MathWorks extension of the standard Java Swing JTable – a class called com.mathworks.widgets.spreadsheet.SpreadsheetTable.

Users will normally try to sort columns by clicking the header. This has been a deficiency of JTable for ages. To solve this for the old (pre-R2008a) uitable, download one of several available JTable sorter classes, or my TableSorter class (available here). Add the TableSorter.jar file to your static java classpath (via edit('classpath.txt')) or your dynamic classpath (javaaddpath('TableSorter.jar')).

% Display the uitable and get its underlying Java object handle
[mtable,hcontainer] = uitable('v0', gcf, magic(3), {'A', 'B', 'C'});   % discard the 'v0' in R2007b and earlier
jtable = mtable.getTable;   % or: get(mtable,'table');
 
% We want to use sorter, not data model...
% Unfortunately, UitablePeer expects DefaultTableModel not TableSorter so we need a modified UitablePeer class
% But UitablePeer is a Matlab class, so use a modified TableSorter & attach it to the Model
if ~isempty(which('TableSorter'))
   % Add TableSorter as TableModel listener
   sorter = TableSorter(jtable.getModel());
   jtable.setModel(sorter);
   sorter.setTableHeader(jtable.getTableHeader());
 
   % Set the header tooltip (with sorting instructions)
   jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to sort up; <b>Shift-click</b> to sort down<br />&nbsp;...</html>');
 
else
   % Set the header tooltip (no sorting instructions...)
   jtable.getTableHeader.setToolTipText('<html>&nbsp;<b>Click</b> to select entire column<br />&nbsp;<b>Ctrl-click</b> (or <b>Shift-click</b>) to select multiple columns&nbsp;</html>');
end

Sorted uitable - old version

Sorted uitable - old version

New uitable sorting

The new uitable is based on JIDE’s com.jidesoft.grid.SortableTable and so has built-in sorting support – all you need to do is to turn it on. First get the underlying Java object using my FindJObj utility:

% Display the uitable and get its underlying Java object handle
mtable = uitable(gcf, 'Data',magic(3), 'ColumnName',{'A', 'B', 'C'});
jscrollpane = findjobj(mtable);
jtable = jscrollpane.getViewport.getView;
 
% Now turn the JIDE sorting on
jtable.setSortable(true);		% or: set(jtable,'Sortable','on');
jtable.setAutoResort(true);
jtable.setMultiColumnSortable(true);
jtable.setPreserveSelectionsAfterSorting(true);

Note: the Matlab mtable handle has a hidden Sortable property, but it has no effect – use the Java property mentioned above instead. I assume that the hidden Sortable property was meant to implement the sorting behavior in R2008a, but MathWorks never got around to actually implement it, and so it remains this way to this day.

A more detailed report

I have prepared a 45-page PDF report about using and customizing Matlab’s uitable, which greatly expands on the above. This report is available for $25 here (please allow up to 48 hours for email delivery). The report includes the following (more details here):

  • comparison of the old vs. the new uitable implementations
  • description of the uitable properties and callbacks
  • alternatives to uitable using a variety of technologies
  • updating a specific cell’s value
  • setting background and foreground colors for a cell or column
  • using dedicated cell renderer and editor components
  • HTML processing
  • setting dynamic cell-specific tooltip
  • setting dynamic cell-specific drop-down selection options
  • using a color-selection drop-down for cells
  • customizing scrollbars
  • customizing column widths and resizing
  • customizing selection behavior
  • data sorting (expansion of today’s article)
  • data filtering (similar to Excel’s data filtering control)
  • merging table cells
  • programmatically adding/removing rows
  • numerous links to online resources
  • overview of the JIDE grids package, which contains numerous extremely useful GUI controls and components
]]>
https://undocumentedmatlab.com/blog_old/uitable-sorting/feed 46
Borderless button used for plot propertieshttps://undocumentedmatlab.com/blog_old/borderless-button-used-for-plot-properties https://undocumentedmatlab.com/blog_old/borderless-button-used-for-plot-properties#comments Wed, 11 May 2011 17:28:35 +0000 https://undocumentedmatlab.com/?p=2307 Related posts:
  1. Matlab and the Event Dispatch Thread (EDT) The Java Swing Event Dispatch Thread (EDT) is very important for Matlab GUI timings. This article explains the potential pitfalls and their avoidance using undocumented Matlab functionality....
  2. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  3. Javacomponent background color This article explains how to align Java component background color with a Matlab color....
  4. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
]]>
A couple of days ago, a reader of this blog has posted a comment asking for advise in enabling the user to dynamically set plot properties. While this can be done using the built-in inspect function, the reader correctly noted that this presents a list of numerous properties, most of which may not be very interesting for the casual user. So I wanted to use the opportunity to show an alternative mechanism that I have used in one of my applications and I think answers the need. It relies on a border-less button that is located right next to the plot axis origin, and when clicked, presents a simple plot line-style modification dialog window.

We start by creating a simple Java button (a com.mathworks.mwswing.MJButton in this case) with the simple text ‘+’. The benefit of using com.mathworks.mwswing.MJButton rather than the standard javax.swing.JButton, which MJButton extends, is that MJButton added a FlyOverAppearance property to the standard JButton. This is a very handy feature that enables to present a border-less button, except upon mouse hove, in which case a shadow border is displayed. This is exactly the effect used to highlight toolbar buttons upon mouse hover. To emphasize the button’s action, we set a HAND_CURSOR cursor whenever the mouse hovers over the button.

This button is then displayed onscreen using the built-in semi-documented javacomponent function, at the axes origin position. We set the button’s callback property to uisetlineprops, which was adapted from a File Exchange submission by the same name:

axesPos = get(hAxes,'pos');
btLinePropsCbStr = ['uisetlineprops(findall(' num2str(hAxes,99) ',''type'',''line''))'];
btLinePropsPos = [axesPos(1:2)+0.003,0.03,0.03];
 
% Note: all the following code is just to have a specific cursor
% ^^^^ (HAND_CURSOR) when hovering over the button...
btLineprops = com.mathworks.mwswing.MJButton('+');
btLineprops.setBorder([]);
btLineprops.setBackground(java.awt.Color.white);
btLineprops.setCursor(java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
btLineprops.setFlyOverAppearance(true);
btLineprops.setToolTipText('Modify properties of plot lines');
[dummy,btContainer] = javacomponent(btLineprops,[0 0 1 1],hFig); %#ok
set(btLineprops, 'ActionPerformedCallback',btLinePropsCbStr);
set(btContainer, 'Units','Norm', 'Position',btLinePropsPos);

A borderless button used to modify plot properties

A borderless button used to modify plot properties

The benefit of using this simple trick is that the ‘+’ button is unobtrusive, and yet highly accessible. Of course, similar button can be used for a wide variety of callback functionalities, limited only by your imagination!

]]>
https://undocumentedmatlab.com/blog_old/borderless-button-used-for-plot-properties/feed 16
An interesting uitree utilityhttps://undocumentedmatlab.com/blog_old/interesting-uitree-utility https://undocumentedmatlab.com/blog_old/interesting-uitree-utility#comments Wed, 30 Mar 2011 18:00:59 +0000 https://undocumentedmatlab.com/?p=2218 Related posts:
  1. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  2. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  3. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  4. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
]]>
“uitree” is consistently one of the most-popular search terms on this site, together with “uitable” and “uitab”. I also receive frequent questions about tree components in Matlab.

I already wrote a series of articles on Matlab’s built-in semi-documented uitree (starting here), and I am on a constant lookout for additional interesting angles on uitree to post here. Brett Shoelson’s recent review of 2005’s Pick-of-the-Week utilities, provided me with such an opportunity.

One of 2005’s featured utilities, Structure Explorer by Hassan Lahdili, originally written using Microsoft’s TreeView ActiveX control, was apparently rewritten using Matlab’s Java-based uitree. This enables the utility to run on non-Windows platforms and have a more consistent look-and-feel with Matlab’s Java-based GUI:

Hassan Lahdili's Structure Explorer (click to enlarge)

Hassan Lahdili's Structure Explorer (click to enlarge)

Hassan’s ExploreStruct utility, in addition to being useful as-is, provides a very useful learning tool for uitree integration in Matlab GUI. This utility uses custom icons for different node types, custom callbacks for node expansion (NodeWillExpandCallback) and node selection (NodeSelectedCallback), and tree context (right-click) menu.

Unfortunately, it appears that the ExploreStruct utility has not been updated for compatibility with the latest Matlab releases. This causes numerous warning messages about not using ‘v0’ when calling uitree and uitreenode. I also had to add a call to drawnow following the uitree‘s creation in line #30, otherwise the tree did not appear (due to EDT issues). Also, I had to comment out line #83 (set(root,’UIContextMenu’, cmenu);) which caused an error (“There is no ‘UIContextMenu’ property in the ‘com.mathworks.hg.peer.UITreeNode’ class”) – the tree’s context-menu actually works even without this line.

Finally, I had to fix line #182 so that the node icons will appear correctly:

%pth = [matlabroot, '\work\exp_struct_icons\'];  %old
pth = [fileparts(which(mfilename)) '\exp_struct_icons\'];  %new

ExploreStruct is not documented and does not have extensive error-checking that I would like to see in real-world applications. But it is relatively easy to read and understand due to its use of internal functions and meaningful variable names.

Altogether, aside from the minor nuances mentioned above, I believe that readers who are interested in implementing custom tree objects in their Matlab GUI can learn a lot from this utility, and you can easily adapt its code for your own needs (or if you can’t, I am always willing to help).

]]>
https://undocumentedmatlab.com/blog_old/interesting-uitree-utility/feed 5
handle2struct, struct2handle & Matlab 8.0https://undocumentedmatlab.com/blog_old/handle2struct-struct2handle-and-matlab-8 https://undocumentedmatlab.com/blog_old/handle2struct-struct2handle-and-matlab-8#comments Wed, 29 Dec 2010 18:00:56 +0000 https://undocumentedmatlab.com/?p=2023 Related posts:
  1. getundoc – get undocumented object properties getundoc is a very simple utility that displays the hidden (undocumented) properties of a specified handle object....
  2. Customizing axes part 4 – additional properties Matlab HG2 axes can be customized in many different ways. This article explains some of the undocumented aspects. ...
  3. Plot line transparency and color gradient Static and interpolated (gradient) colors and transparency can be set for plot lines in HG2. ...
  4. Plot markers transparency and color gradient Matlab plot-line markers can be customized to have transparency and color gradients. ...
]]>
Last week I explained that FIG files are simply MAT files in disguise. Today, we look under the hood of Matlab’s hgsave function, which is used to save FIG files. We shall see that this is both useful and illuminating vis-a-vis Matlab’s future.

handle2struct

Under the hood, hgsave uses the semi-documented built-in handle2struct function to convert the figure handle into a Matlab struct that is then stored with a simple save (the same function that saves MAT files) function call.

The fact that handle2struct is semi-documented means that the function is explained in a help comment (which can be seen via the help command), that is nonetheless not part of the official doc sections. It is an unsupported feature originally intended only for internal Matlab use (which of course doesn’t mean we can’t use it).

handle2struct merits a dedicated mention, since I can envision several use-cases for storing only a specific GUI handle (for example, a uipanel, a specific graph, or a set of GUI controls’ state). In this case, all we need to do is to call handle2struct with the requested parent handle, then save the returned structure. So simple, so powerful. handle2struct automatically returns all the non-default property information, recursively in all the handle’s children.

Note that features that are not properties of displayed handles (camera position, 3D rotation/pan/zoom states, annotations, axes-linking etc.) are not processed by handle2struct. For storing the states of these features, you need to use some specific handling – see the code within %matlabroot%\toolbox\matlab\graphics\private\hgsaveStructDbl.m for details. Basically, hgsaveStructDbl.m reads the state of all these features and temporarily stores them in the base handle’s ApplicationData property; handle2struct then reads them as any other regular handle property data, and then hgsaveStructDbl.m clears the temporary data from the handle’s ApplicationData. We can use the same trick for any other application state, of course.

struct2handle

handle2struct has a reverse function – the semi-documented struct2handle. I use it for creating dynamic preference panels: As in Matlab’s Preferences window, I have a list of preference topics and a set of corresponding options panels. In my case, it was easy to design each panel as a separate FIG file using GUIDE. In run-time, I simply load the relevant panel from its FIG file as described above, and place it onscreen in a dedicated uipanel using struct2handle. This enables very easy maintenance of preference panels, without sacrificing any functionality.

Matlab's preferences panels

Matlab's preferences panels

Figure menus and toolbars are not normally stored by hgsave, unless you use the optional ‘all’ parameter (and correspondingly in hgload, if you choose to use it). handle2struct and handle2struct accept the same optional ‘all’ parameter as hgsave and hgload. Unfortunately, a warning message indicates that this option will be discontinued in some future Matlab version.

Which brings us to our final topic for today:

Matlab 8: Boldly going where no FIG has gone before…

Remember my post earlier this year about the new HG2 mechanism? I speculated that when MathWorks decides to release HG2, it will define this as a major Matlab release and label it Matlab 8.0.

The source code in hgsave.m appears to confirm my speculation. Here is the relevant code section (slightly edited for clarity), which speaks for itself:

% Decide which save code path to use
if ~feature('HGUsingMatlabClasses')   % <== existing HG
    % Warn if user passed in 'all' flag
    if SaveAll
        warning( 'MATLAB:hgsave:DeprecatedOption', ...
            'The ''all'' option to hgsave will be removed in a future release.');
    end
    hgS = hgsaveStructDbl(h, SaveAll);
    SaveVer = '070000';
    SaveOldFig = true;
 
else   % <== HG2
 
    % Warn if user passed in 'all' flag
    if SaveAll
        warning( 'MATLAB:hgsave:DeprecatedOption', ...
            'The ''all'' option to hgsave has been removed.');
    end
    if SaveOldFig
        hgS = hgsaveStructClass(h);
        SaveVer = '080000';
    else
        hgO = hgsaveObject(h);
        SaveVer = '080000';
    end
end
 
% Revision encoded as 2 digits for major revision,
% 2 digits for minor revision, and 2 digits for
% patch revision.  This is the minimum revision
% required to fully support the file format.
% e.g. 070000 means 7.0.0

As can be seen, when Matlab starts using HG2 (perhaps in 2011?), the top-level structure node will be called “hgS_080000”, indicating Matlab 8.0. QED.

As a side-note, note that in HG2/Matlab8, although the comment about using ‘all’ indicates that it has been removed, in practice it is still accepted (although not being used). This will enable your code to be backward-compatible whenever HG2 launches, and future-compatible today.

Have you used handle2struct or struct2handle? If so, please share your experience in a comment.

Let the upcoming 2011 be a year filled with revelations, announcements and fulfillment! Happy New Year everybody!

]]>
https://undocumentedmatlab.com/blog_old/handle2struct-struct2handle-and-matlab-8/feed 11
Matlab callbacks for Java eventshttps://undocumentedmatlab.com/blog_old/matlab-callbacks-for-java-events https://undocumentedmatlab.com/blog_old/matlab-callbacks-for-java-events#comments Tue, 30 Nov 2010 22:09:35 +0000 https://undocumentedmatlab.com/?p=1987 Related posts:
  1. setPrompt – Setting the Matlab Desktop prompt The Matlab Desktop's Command-Window prompt can easily be modified using some undocumented features...
  2. UDD and Java UDD provides built-in convenience methods to facilitate the integration of Matlab UDD objects with Java code - this article explains how...
  3. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  4. Disabling menu entries in deployed docked figures Matlab's standard menu items can and should be removed from deployed docked figures. This article explains how. ...
]]>
A few days ago, a user posted a question on StackOverflow asking whether it is possible to trap a Java-based event in a Matlab callback.IB-Matlab connectivity (Matlab and TWS may be on separate computers)

It so happens that only a few weeks ago I completed a consulting project which required exactly this. The project was to integrate a Matlab computational engine with a Java interface to Interactive Brokers (IB) – a well-known online brokerage firm. The idea was to use the Java interface to fetch real-time data about securities (stocks, bonds, options etc.), use a Matlab processing utility, then use the Java interface again to send Buy or Sell orders back to IB.

If you are interested in the final result (IB-Matlab, a complete and field-tested Matlab-IB interface), look here.

The challenge

A big challenge in this project (aside from handling quite a few IB interface quirks), was to propagate events from the Java interface to the Matlab application. This had to be done asynchronously, since events such as order execution can occur at any time following the order placement. Moreover, even simple requests such as retrieving security information (bid/ask prices for example) is handled by IB via Java events, not as simple function return values.

Handling Java-based events in Matlab is not a trivial task. Not only merely undocumented, but it is also not intuitive. I have spent quite a few hours trying to crack this issue. In fact, I believe it was one of my more challenging tasks in figuring out the undocumented aspects of the Matlab-Java interface. Few other challenges were as difficult, yet with a happy ending (Drag & Drop is a similar issue – I will describe it in another article sometime).

The solution

Fast-forward all the fruitless attempted variations, here is the bottom line. Refer to the following simple Java class example:

public class EventTest
{
    private java.util.Vector data = new java.util.Vector();
    public synchronized void addMyTestListener(MyTestListener lis) {
        data.addElement(lis);
    }
    public synchronized void removeMyTestListener(MyTestListener lis) {
        data.removeElement(lis);
    }
    public interface MyTestListener extends java.util.EventListener {
        void testEvent(MyTestEvent event);
    }
    public class MyTestEvent extends java.util.EventObject {
        private static final long serialVersionUID = 1L;
        public float oldValue,newValue;        
        MyTestEvent(Object obj, float oldValue, float newValue) {
            super(obj);
            this.oldValue = oldValue;
            this.newValue = newValue;
        }
    }
    public void notifyMyTest() {
        java.util.Vector dataCopy;
        synchronized(this) {
            dataCopy = (java.util.Vector)data.clone();
        }
        for (int i=0; i < dataCopy.size(); i++) {
            MyTestEvent event = new MyTestEvent(this, 0, 1);
            ((MyTestListener)dataCopy.elementAt(i)).testEvent(event);
        }
    }
}

When compiling EventTest.java, three class files are created: EventTest.class, EventTest$MyTestEvent.class and EventTest$MyTestListener.class. Place them on Matlab’s Java static classpath, using edit(‘classpath.txt’) (using the dynamic classpath causes many problems that using the static classpath solves). They can now be accessed as follows:

>> which EventTest
EventTest is a Java method  % EventTest constructor
 
>> evt = EventTest
evt =
EventTest@16166fc
 
>> evt.get
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback = 
	TestEventCallbackData = []
 
	BeingDeleted = off
	ButtonDownFcn = 
	Children = []
	Clipping = on
	CreateFcn = 
	DeleteFcn = 
	BusyAction = queue
	HandleVisibility = on
	HitTest = on
	Interruptible = on
	Parent = []
	Selected = off
	SelectionHighlight = on
	Tag = 
	Type = EventTest
	UIContextMenu = []
	UserData = []
	Visible = on
 
>> set(evt)
	Class
	TestEventCallback: string -or- function handle -or- cell array
	...
 
>> set(evt,'TestEventCallback',@(h,e)disp(h))
 
>> get(evt)
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback = [ (1 by 1) function_handle array]    % < = ok
	TestEventCallbackData = []
	...
 
>> evt.notifyMyTest   % invoke Java event
              0.0009765625   % < = Matlab callback

Note how Matlab automatically converted the Java event testEvent, declared in interface MyTestListener, into a Matlab callback TestEventCallback (the first character is always capitalized). All Java events are automatically converted in this fashion, by appending a ‘Callback’ suffix. Here is a code snippet from R2008a’s \toolbox\matlab\uitools\@opaque\addlistener.m that shows this (slightly edited):

hSrc = handle(jobj,'callbackproperties');
allfields = sortrows(fields(set(hSrc)));
for i = 1:length(allfields)
   fn = allfields{i};
   if ~isempty(findstr('Callback',fn))
      disp(strrep(fn,'Callback',''));
   end
end
 
callback = @(o,e) cbBridge(o,e,response);
hdl = handle.listener(handle(jobj), eventName, callback);
function cbBridge(o,e,response)
   hgfeval(response, java(o), e.JavaEvent)
end

Note that hgfeval, which is used within the cbBridge callback function, is a semi-documented pure-Matlab built-in function, which I described a few weeks ago.

If several events have the same case-insensitive name, then the additional callbacks will have an appended underscore character (e.g., ‘TestEventCallback_’):

// In the Java class:
public interface MyTestListener extends java.util.EventListener
{
    void testEvent(MyTestEvent e);
    void testevent(TestEvent2 e);
}
% …and back in Matlab:
>> evt=EventTest; evt.get
	Class = [ (1 by 1) java.lang.Class array]
	TestEventCallback = 
	TestEventCallbackData = []
	TestEventCallback_ = 
	TestEventCallback_Data = [] 
	...

To complete this discussion, it should be noted that Matlab also automatically defines corresponding Events in the Java object’s classhandle. Unfortunately, classhandle events are not differentiated in a similar manner – in this case only a single event is created, named Testevent. classhandle events, and their relationship to the preceding discussion, will be described in Donn Scull’s upcoming series on UDD.

An alternative to using callbacks on Java events, as shown above, is to use undocumented handle.listeners:

hListener = handle.listener(handle(evt),'TestEvent',callback);

There are several other odds and ends, but this article should be sufficient for implementing a fully-functional Java event handling mechanism in Matlab. Good luck!

p.s. – if you’re still stuck, consider hiring me for a short consulting project. I’ll be happy to help.

]]>
https://undocumentedmatlab.com/blog_old/matlab-callbacks-for-java-events/feed 88
Uitab customizationshttps://undocumentedmatlab.com/blog_old/uitab-customizations https://undocumentedmatlab.com/blog_old/uitab-customizations#comments Wed, 17 Nov 2010 18:00:16 +0000 https://undocumentedmatlab.com/?p=1959 Related posts:
  1. Figure toolbar components Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to access existing toolbar icons and how to add non-button toolbar components....
  2. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  3. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  4. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
]]>
This article concludes my planned series on Matlab’s built-in semi-documented tab-panel functionality. In previous article I have shown how Matlab’s uitab and uitabgroup functions can be used to present tabbed contents, and how icon images can be attached to tabs using their undocumented underlying Java component. Today I will show other customizations that can be done to tabs.

Disabling tabs

Our first customization is to disable particular tabs. We start with a basic tab group, and get the underlying Java component:

% Prevent an annoying warning msg
warning off MATLAB:uitabgroup:OldVersion
 
% Prepare a tab-group consisting of two tabs
hTabGroup = uitabgroup; drawnow;
tab1 = uitab(hTabGroup, 'title','Panel 1');
a = axes('parent', tab1); surf(peaks);
tab2 = uitab(hTabGroup, 'title','Panel 2');
uicontrol(tab2, 'String','Close', 'Callback','close(gcbf)');
 
% Get the underlying Java reference (use hidden property)
jTabGroup = getappdata(handle(hTabGroup),'JTabbedPane');

Remember that Java uses 0-based indexing so tab #1 is actually the second tab. Let’s disable it by using the Java object’s setEnabledAt() method:

jTabGroup.setEnabledAt(1,false);  % disable only tab #1 (=second tab)
jTabGroup.setEnabled(false);  % disable all tabs
jTabGroup.setEnabled(true);  % re-enable all tabs (except tab #1)

A disabled tab

A disabled tab

Note that setting the property value for a specific tab overrides the value set for ALL tabs, despite the fact that setEnabled is called after setEnabledAt.

Look-and-Feel

Unlike some other controls, tabs have distinctly different appearances in different Look & Feels. Take a look at Plastic3DLookAndFeel, NimbusLookAndFeel and MetalLookAndFeel for tab panels that look distinctly different and more stylish than the WindowsLookAndFeel shown above.


WindowsLookAndFeel

WindowsLookAndFeel

WindowsClassicLookAndFeel

WindowsClassicLookAndFeel


Plastic3DLookAndFeel

Plastic3DLookAndFeel

MotifLookAndFeel

MotifLookAndFeel


MetalLookAndFeel

MetalLookAndFeel

NimbusLookAndFeel

NimbusLookAndFeel


Other customizations

There are other things we can customize, such as setting mnemonics (keyboard shortcuts), etc. – refer to the official documentation or any good textbook about Java Swing.

Tab callbacks are the same as the standard Swing components callbacks, except for StateChangedCallback, which is automatically linked to the internal function that synchronizes between the Java tab group and the Matlab uicontainers (in other words: it’s not a good idea to mess with it…).

Some jTabGroup functions that work well with standard JTabbedPane fail with uitabgroup: For example, jTabGroup.setIconAt or setTabLayoutPolicy. I am unsure of the reason for this. Other limitations with uitabgroup are a reported problem when compiling any GUI that includes it; a reported bug when reordering tabs; a reported problem rendering some graphic object properties (e.g., clipping); and a reported problem in displaying tabs containing ActiveX or Java objects (plus suggested solutions). Interested readers can fix all these issues by modifying the m-files in the folders %matlabroot%/toolbox/matlab/@uitools/@uitabgroup and /@uitools/@uitab. At least some of these problems are fixed as of R2010a.

Readers might also be interested in the Yet Another Layout Manager utility. This utility directly uses Swing’s JTabbedPane object to implement tab panels, essentially mimicking the built-in uitab/uitabgroup functions.

This concludes my series on Matlab’s uitab. Any other specific customizations you are interested in? Any nice variation of your own? Please do share your thoughts in a comment.

]]>
https://undocumentedmatlab.com/blog_old/uitab-customizations/feed 9