Semi-documented function – Undocumented Matlab https://undocumentedmatlab.com Charting Matlab's unsupported hidden underbelly Fri, 20 Oct 2017 09:57:44 +0000 en-US hourly 1 https://wordpress.org/?v=4.4.1 Password & spinner controls in Matlab GUIhttps://undocumentedmatlab.com/blog/password-and-spinner-controls-in-matlab-gui https://undocumentedmatlab.com/blog/password-and-spinner-controls-in-matlab-gui#comments Wed, 14 Dec 2016 17:28:09 +0000 http://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/password-and-spinner-controls-in-matlab-gui/feed 4
Editable combo-boxhttps://undocumentedmatlab.com/blog/editable-combo-box https://undocumentedmatlab.com/blog/editable-combo-box#comments Wed, 09 Oct 2013 15:38:55 +0000 http://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 ($39, 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/editable-combo-box/feed 19
Function definition meta-infohttps://undocumentedmatlab.com/blog/function-definition-meta-info https://undocumentedmatlab.com/blog/function-definition-meta-info#comments Wed, 04 Sep 2013 13:38:42 +0000 http://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/function-definition-meta-info/feed 6
Math libraries version info & upgradehttps://undocumentedmatlab.com/blog/math-libraries-version-info-upgrade https://undocumentedmatlab.com/blog/math-libraries-version-info-upgrade#comments Wed, 17 Jul 2013 18:00:36 +0000 http://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/math-libraries-version-info-upgrade/feed 7
Handle Graphics Behaviorhttps://undocumentedmatlab.com/blog/handle-graphics-behavior https://undocumentedmatlab.com/blog/handle-graphics-behavior#comments Wed, 06 Mar 2013 18:00:19 +0000 http://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 uiundo This article describes how Matlab's undocumented uiundo undo/redo manager can be customized...
 
]]>
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/handle-graphics-behavior/feed 4
Customizing menu items part 1https://undocumentedmatlab.com/blog/customizing-menu-items-part-1 https://undocumentedmatlab.com/blog/customizing-menu-items-part-1#comments Wed, 25 Apr 2012 18:14:08 +0000 http://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/customizing-menu-items-part-1/feed 6
Common javacomponent problemshttps://undocumentedmatlab.com/blog/common-javacomponent-problems https://undocumentedmatlab.com/blog/common-javacomponent-problems#comments Wed, 07 Dec 2011 18:00:38 +0000 http://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/common-javacomponent-problems/feed 28
Types of undocumented Matlab aspectshttps://undocumentedmatlab.com/blog/types-of-undocumented-matlab-aspects https://undocumentedmatlab.com/blog/types-of-undocumented-matlab-aspects#respond Thu, 24 Nov 2011 18:00:36 +0000 http://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/types-of-undocumented-matlab-aspects/feed 0
Javacomponent background colorhttps://undocumentedmatlab.com/blog/javacomponent-background-color https://undocumentedmatlab.com/blog/javacomponent-background-color#comments Wed, 12 Oct 2011 14:39:43 +0000 http://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/javacomponent-background-color/feed 2
Bug and workaround in timeseries plothttps://undocumentedmatlab.com/blog/bug-and-workaround-in-timeseries-plot https://undocumentedmatlab.com/blog/bug-and-workaround-in-timeseries-plot#comments Wed, 07 Sep 2011 18:41:33 +0000 http://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/bug-and-workaround-in-timeseries-plot/feed 3
Uitable sortinghttps://undocumentedmatlab.com/blog/uitable-sorting https://undocumentedmatlab.com/blog/uitable-sorting#comments Tue, 26 Jul 2011 18:00:01 +0000 http://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. 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....
 
]]>
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 30-page report about using and customizing Matlab’s uitable, which greatly expands on the above. This report is available for a small fee 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/uitable-sorting/feed 43
Borderless button used for plot propertieshttps://undocumentedmatlab.com/blog/borderless-button-used-for-plot-properties https://undocumentedmatlab.com/blog/borderless-button-used-for-plot-properties#comments Wed, 11 May 2011 17:28:35 +0000 http://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/borderless-button-used-for-plot-properties/feed 16
An interesting uitree utilityhttps://undocumentedmatlab.com/blog/interesting-uitree-utility https://undocumentedmatlab.com/blog/interesting-uitree-utility#comments Wed, 30 Mar 2011 18:00:59 +0000 http://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/interesting-uitree-utility/feed 5
handle2struct, struct2handle & Matlab 8.0https://undocumentedmatlab.com/blog/handle2struct-struct2handle-and-matlab-8 https://undocumentedmatlab.com/blog/handle2struct-struct2handle-and-matlab-8#comments Wed, 29 Dec 2010 18:00:56 +0000 http://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/handle2struct-struct2handle-and-matlab-8/feed 11
Matlab callbacks for Java eventshttps://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events https://undocumentedmatlab.com/blog/matlab-callbacks-for-java-events#comments Tue, 30 Nov 2010 22:09:35 +0000 http://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.

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 (i.e., 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/matlab-callbacks-for-java-events/feed 85
Uitab customizationshttps://undocumentedmatlab.com/blog/uitab-customizations https://undocumentedmatlab.com/blog/uitab-customizations#comments Wed, 17 Nov 2010 18:00:16 +0000 http://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/uitab-customizations/feed 7
Uitab colors, icons and imageshttps://undocumentedmatlab.com/blog/uitab-colors-icons-images https://undocumentedmatlab.com/blog/uitab-colors-icons-images#comments Wed, 10 Nov 2010 18:00:01 +0000 http://undocumentedmatlab.com/?p=1955
 
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 nodes – part 1 This article describes how to customize specific nodes of 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. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
 
]]>
A few months ago I published a post about Matlab’s semi-documented tab-panel functionality, where I promised a follow-up article on tab customizations. A reader of this blog asked a related question earlier today, so I decided it’s about time I fulfilled this promise.

As with most Matlab controls, the underlying Java component enables far greater customization than possible using plain Matlab. Today I will show three specific customizations. 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');

Foreground & background tab colors

We can set the tab font color using setForeground() and setForegroundAt(), or via HTML. Note that setForegroundAt() overrides anything set by setForeground(). Also remember that Java uses 0-based indexing so tab #1 is actually the second tab:

% Equivalent manners to set a red tab foreground:
jTabGroup.setForegroundAt(1,java.awt.Color(1.0,0,0)); % tab #1
jTabGroup.setTitleAt(1,'<html><font color="red"><i>Panel 2');
jTabGroup.setForeground(java.awt.Color.red);

Unfortunately, the corresponding setBackgroundAt(tabIndex,color) method has no visible effect, and the Matlab-extended tabs keep their white/gray backgrounds. A similar attempt to modify the tab’s BackgroundColor property fails, since Matlab made this property unmodifiable (=’none’). A simple solution is to use a CSS background:

% Equivalent manners to set a yellow tab background:
jTabGroup.setTitleAt(0,'<html><div style="background:#ffff00;">Panel 1');
jTabGroup.setTitleAt(0,'<html><div style="background:yellow;">Panel 1');

uitabgroup with non-default forground and background tab colors and fonts

uitabgroup with non-default forground and background tab colors and fonts

We can set the foreground text color using the CSS color directive. Similarly, we can also set a background gradient image for the tabs, using the CSS background-image directive. Which leads us to our next customization:

Icon images

Icons and sub-components can be added to the tabs. Unfortunately, for some reason that I do not fully understand, jTabGroup.setIconAt() has no apparent effect. The solution is to set our own custom control as the requested tab, and add our icon (or other customizations) to it. Here is a simple example:

% Add an icon to tab #1 (=second tab)
icon = javax.swing.ImageIcon('C:\Yair\save.gif');
jLabel = javax.swing.JLabel('Tab #2');
jLabel.setIcon(icon);
jTabGroup.setTabComponentAt(1,jLabel);	% Tab #1 = second tab
 
% Note: icon is automatically grayed when label is disabled
jLabel.setEnabled(false);
jTabGroup.setEnabledAt(1,false);  % disable only tab #1

tab with a custom icon (enabled)
tab with a custom icon (enabled)

tab with a custom icon (enabled & disabled)

Close buttons

Now let’s try a more complex example, of adding a close (‘x’) button to one of the tabs. Generalizing this code snippet is left as an exercise to the reader:

% First let's load the close icon
jarFile = fullfile(matlabroot,'/java/jar/mwt.jar');
iconsFolder = '/com/mathworks/mwt/resources/';
iconURI = ['jar:file:/' jarFile '!' iconsFolder 'closebox.gif'];
icon = javax.swing.ImageIcon(java.net.URL(iconURI));
 
% Now let's prepare the close button: icon, size and callback
jCloseButton = handle(javax.swing.JButton,'CallbackProperties');
jCloseButton.setIcon(icon);
jCloseButton.setPreferredSize(java.awt.Dimension(15,15));
jCloseButton.setMaximumSize(java.awt.Dimension(15,15));
jCloseButton.setSize(java.awt.Dimension(15,15));
set(jCloseButton, 'ActionPerformedCallback',@(h,e)delete(tab2));
 
% Now let's prepare a tab panel with our label and close button
jPanel = javax.swing.JPanel;	% default layout = FlowLayout
set(jPanel.getLayout, 'Hgap',0, 'Vgap',0);  % default gap = 5px
jLabel = javax.swing.JLabel('Tab #2');
jPanel.add(jLabel);
jPanel.add(jCloseButton);
 
% Now attach this tab panel as the tab-group's 2nd component
jTabGroup.setTabComponentAt(1,jPanel);	% Tab #1 = second tab

tab with an attached close button

tab with an attached close button

Next week’s article will conclude the series on Matlab’s uitab. Any particular customization you are interested in? Please do post a comment.

Addendum Oct 3 2014: the uitab and uitabgroup functions have finally become fully supported and documented in Matlab version 8.4 (R2014b). However, the Java-based customizations shown in this article are still unsupported and undocumented, although they remain practically unchanged from what I’ve described in this article, four years earlier.

]]>
https://undocumentedmatlab.com/blog/uitab-colors-icons-images/feed 32
The hgfeval functionhttps://undocumentedmatlab.com/blog/hgfeval https://undocumentedmatlab.com/blog/hgfeval#comments Wed, 27 Oct 2010 18:00:59 +0000 http://undocumentedmatlab.com/?p=1925
 
Related posts:
  1. Customizing menu items part 1 Matlab menus can be customized in a variety of undocumented manners - first article of a series. ...
  2. 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....
  3. Matlab layout managers: uicontainer and relatives Matlab contains a few undocumented GUI layout managers, which greatly facilitate handling GUI components in dynamically-changing figures....
  4. Tab panels – uitab and relatives This article describes several undocumented Matlab functions that support tab-panels...
 
]]>
Last week’s article about using a static GUI control, made use of the hgfeval function for its callback switch-yard dispatching. Today’s article will expose this important but often overlooked function.

hgfeval is a built-in semi-documented function. This means that the function is explained in a comment within the hgfeval.m file (which can be seen via the edit(‘hgfeval’) command), that is nonetheless not part of the official help or doc sections. It is an unsupported function originally intended only for internal Matlab use, which of course doesn’t mean we can’t use it. hgfeval is currently used extensively within the Matlab code-base.

Callback chaining

hgfeval‘s main purpose is to programmatically (synchronously) invoke a callback, rather than it being dynamically (a-synchronously) invoked when some event occurs. This need often occurs when chaining events. In a nutshell, we need to programmatically invoke Callback A (an executable code [=string], function handle, or cell array of function handle with extra parameters) within our code, which is typically located in another callback (B). For example:

function CallbackB(hObject, hEventData, varargin)
    callbackA = get(gcf, 'ButtonDownFcn');
    hgfeval(callbackA);
end

hgfeval is important when we want to force the objects passed as the callback’s first two input parameters (hObject and hEventData): hgfeval pre-pends all its extra parameters (arguments #2+) to the callback’ed function. So, calling hgfeval({@myFunc,arg1,arg2}, argA, argB) will actually invoke myFunc(argA,argB,arg1,arg2). Using this syntax we guaranty that whatever the invoked callback may be, its initial arguments will always be set to the necessary argA,argB.

This is often used in what MathWorks calls a callback-bridge. For example, in the following example we set the cbBridge function as a callback bridge for myCallback, that forces java(o) as the reference object (the invoked callback’s first argument) and e.JavaEvent as the second arg; all user args will then follow as optional additional args:

hdl = handle.listener(handle(jobj), eventName, ...
                      @(o,e)cbBridge(o,e,myCallback));
 
function cbBridge(o,e,myCallback)
    hgfeval(myCallback, java(o), e.JavaEvent)
end

In this example, the myCallback variable can be any valid Matlab callback specification: string, function handle, or cell array.

If we had used myCallback directly, then myCallback would have been invoked with o and e rather than java(o) and e.JavaEvent. The point here is that using the callback bridge and hgfeval enabled us to tailor the parameters passed to the callback function.

Forward & backward compatibility

hgfeval has been built-in within all standard Matlab 7 releases, so while it may be discontinued in some future Matlab release, it did have a very long life span.

Even if for some reason this function is removed in some future Matlab release, it can easily be reproduced – after all, it only contains 35 very simple lines of pure Matlab code. In fact, for some project that had to rely on Matlab 6 (in which hgfeval was not yet available), it was an almost trivial task to retrofit an hgfeval look-alike (I had to remove function handles and similar minor tweaks):

%% hgfeval replacement for Matlab 6 compatibility
function hgfeval(fcn,varargin)
    if isempty(fcn),  return;  end
    if iscell(fcn)
        feval(fcn{1},varargin{:},fcn{2:end});
    elseif ischar(fcn)
        evalin('base', fcn);
    else
        feval(fcn,varargin{:});
    end
%end  %no function end in Matlab 6...

Have you ever used hgfeval in your code? If so, please share your experience in a comment below.

]]>
https://undocumentedmatlab.com/blog/hgfeval/feed 2
Customizing uitree nodes – part 2https://undocumentedmatlab.com/blog/customizing-uitree-nodes-2 https://undocumentedmatlab.com/blog/customizing-uitree-nodes-2#comments Wed, 01 Sep 2010 18:00:57 +0000 http://undocumentedmatlab.com/?p=1850
 
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. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
  3. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
  4. Customizing uitree nodes – part 1 This article describes how to customize specific nodes of Matlab GUI tree controls created using the undocumented uitree function...
 
]]>
In my previous posts I have shown how Matlab’s semi-documented uitree and uitreenode functions can be used to display hierarchical (tree) control in Matlab GUI. Today I conclude this mini-series by answering a reader’s request to show how checkboxes, radio buttons and other similar controls can be attached to tree nodes.

There are actually several ways this can be done:

Matlab icon control

The simplest is to create two icons (checked/unchecked) and switch the node’s icon whenever it is selected (use mtree’s NodeSelectedCallback or jtree’s MouseClickedCallback callbacks) – a sample implementation was posted by Gwendolyn Fischer a couple of years ago, based on even earlier posts by John Anderson, Brad Phelan and me. Here it is, with minor fixes:

function uitree_demo
% function based on treeExperiment6 by John Anderson
% see http://www.mathworks.com/matlabcentral/newsreader/view_thread/104957#269485
%
% The mousePressedCallback part is inspired by Yair Altman
%
% derived from Brad Phelan's tree demo
% create a tree model based on UITreeNodes and insert into uitree.
% add and remove nodes from the treeModel and update the display
import javax.swing.*
import javax.swing.tree.*;
 
% figure window
f = figure('Units', 'normalized');
 
b1 = uicontrol( 'string','add Node', ...
   'units' , 'normalized', ...
   'position', [0 0.5 0.5 0.5], ...
   'callback', @b1_cb);
 
b2 = uicontrol( 'string','remove Node', ...
   'units' , 'normalized', ...
   'position', [0.5 0.5 0.5 0.5], ...
   'callback', @b2_cb);
 
%[I,map] = imread([matlab_work_path, '/checkedIcon.gif']);
[I,map] = checkedIcon;
javaImage_checked = im2java(I,map);
 
%[I,map] = imread([matlab_work_path, '/uncheckedIcon.gif']);
[I,map] = uncheckedIcon;
javaImage_unchecked = im2java(I,map);
 
% javaImage_checked/unchecked are assumed to have the same width
iconWidth = javaImage_unchecked.getWidth;
 
% create top node
rootNode = uitreenode('v0','root', 'File List', [], 0);
% [matlab_work_path, '/fileListIcon.gif'],0);
 
% create two children with checkboxes
cNode = uitreenode('v0','unselected', 'File A', [], 0);
% as icon is embedded here we set the icon via java, otherwise one could
% use the uitreenode syntax uitreenode(value, string, icon, isLeaf) with
% icon being a qualified pathname to an image to be used.
cNode.setIcon(javaImage_unchecked);
rootNode.add(cNode);
 
cNode = uitreenode('v0','unselected', 'File B', [], 0);
cNode.setIcon(javaImage_unchecked);
rootNode.add(cNode);
 
% set treeModel
treeModel = DefaultTreeModel( rootNode );
 
% create the tree
tree = uitree('v0');
tree.setModel( treeModel );
% we often rely on the underlying java tree
jtree = handle(tree.getTree,'CallbackProperties');
% some layout
drawnow;
set(tree, 'Units', 'normalized', 'position', [0 0 1 0.5]);
set(tree, 'NodeSelectedCallback', @selected_cb );
 
% make root the initially selected node
tree.setSelectedNode( rootNode );
 
% MousePressedCallback is not supported by the uitree, but by jtree
set(jtree, 'MousePressedCallback', @mousePressedCallback);
 
  % Set the mouse-press callback
  function mousePressedCallback(hTree, eventData) %,additionalVar)
  % if eventData.isMetaDown % right-click is like a Meta-button
  % if eventData.getClickCount==2 % how to detect double clicks
 
  % Get the clicked node
    clickX = eventData.getX;
    clickY = eventData.getY;
    treePath = jtree.getPathForLocation(clickX, clickY);
    % check if a node was clicked
    if ~isempty(treePath)
      % check if the checkbox was clicked
      if clickX <= (jtree.getPathBounds(treePath).x+iconWidth)
        node = treePath.getLastPathComponent;
        nodeValue = node.getValue;
        % as the value field is the selected/unselected flag,
        % we can also use it to only act on nodes with these values
        switch nodeValue
          case 'selected'
            node.setValue('unselected');
            node.setIcon(javaImage_unchecked);
            jtree.treeDidChange();
          case 'unselected'
            node.setValue('selected');
            node.setIcon(javaImage_checked);
            jtree.treeDidChange();
        end
      end
    end
  end % function mousePressedCallback
 
  function selected_cb( tree, ev )
    nodes = tree.getSelectedNodes;
    node = nodes(1);
    path = node2path(node);
  end
 
  function path = node2path(node)
    path = node.getPath;
    for i=1:length(path);
      p{i} = char(path(i).getName);
    end
    if length(p) > 1
      path = fullfile(p{:});
    else
      path = p{1};
    end
  end
 
  % add node
  function b1_cb( h, env )
    nodes = tree.getSelectedNodes;
    node = nodes(1);
    parent = node;
    childNode = uitreenode('v0','dummy', 'Child Node', [], 0);
    treeModel.insertNodeInto(childNode,parent,parent.getChildCount());
 
    % expand to show added child
    tree.setSelectedNode( childNode );
 
    % insure additional nodes are added to parent
    tree.setSelectedNode( parent );
  end
 
  % remove node
  function b2_cb( h, env )
    nodes = tree.getSelectedNodes;
    node = nodes(1);
    if ~node.isRoot
      nP = node.getPreviousSibling;
      nN = node.getNextSibling;
      if ~isempty( nN )
        tree.setSelectedNode( nN );
      elseif ~isempty( nP )
        tree.setSelectedNode( nP );
      else
        tree.setSelectedNode( node.getParent );
      end
      treeModel.removeNodeFromParent( node );
    end
  end
end % of main function treeExperiment6
 
  function [I,map] = checkedIcon()
    I = uint8(...
        [1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0;
         2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,1;
         2,2,2,2,2,2,2,2,2,2,2,2,0,2,3,1;
         2,2,1,1,1,1,1,1,1,1,1,0,2,2,3,1;
         2,2,1,1,1,1,1,1,1,1,0,1,2,2,3,1;
         2,2,1,1,1,1,1,1,1,0,1,1,2,2,3,1;
         2,2,1,1,1,1,1,1,0,0,1,1,2,2,3,1;
         2,2,1,0,0,1,1,0,0,1,1,1,2,2,3,1;
         2,2,1,1,0,0,0,0,1,1,1,1,2,2,3,1;
         2,2,1,1,0,0,0,0,1,1,1,1,2,2,3,1;
         2,2,1,1,1,0,0,1,1,1,1,1,2,2,3,1;
         2,2,1,1,1,0,1,1,1,1,1,1,2,2,3,1;
         2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
         2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1;
         2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1;
         1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1]);
     map = [0.023529,0.4902,0;
            1,1,1;
            0,0,0;
            0.50196,0.50196,0.50196;
            0.50196,0.50196,0.50196;
            0,0,0;
            0,0,0;
            0,0,0];
  end
 
  function [I,map] = uncheckedIcon()
     I = uint8(...
       [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1;
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1;
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,1,1,1,1,1,1,1,1,1,1,2,2,3,1;
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1;
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,1;
        1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1]);
     map = ...
      [0.023529,0.4902,0;
       1,1,1;
       0,0,0;
       0.50196,0.50196,0.50196;
       0.50196,0.50196,0.50196;
       0,0,0;
       0,0,0;
       0,0,0];
  end

uitree with custom checkbox icons

uitree with custom checkbox icons

Custom Java classes

An alternative is to create a custom tree Java class and/or a custom TreeCellRenderer/TreeCellEditor. Specifically, to change the icons of each node you have to implement your own java component which derives from DefaultMutableTreeNode.

Some online resources to get you started:

Built-in classes

Another option is to use Matlab’s built-in classes, either com.mathworks.mwswing.checkboxtree.CheckBoxTree or com.jidesoft.swing.CheckBoxTree:

import com.mathworks.mwswing.checkboxtree.*
jRoot = DefaultCheckBoxNode('Root');
l1a = DefaultCheckBoxNode('Letters'); jRoot.add(l1a);
l1b = DefaultCheckBoxNode('Numbers'); jRoot.add(l1b);
l2a = DefaultCheckBoxNode('A'); l1a.add(l2a);
l2b = DefaultCheckBoxNode('b'); l1a.add(l2b);
l2c = DefaultCheckBoxNode('<html><b>&alpha;'); l1a.add(l2c);
l2d = DefaultCheckBoxNode('<html><i>&beta;'); l1a.add(l2d);
l2e = DefaultCheckBoxNode('3.1415'); l1b.add(l2e);
 
% Present the standard MJTree:
jTree = com.mathworks.mwswing.MJTree(jRoot);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jTree);
[jComp,hc] = javacomponent(jScrollPane,[10,10,120,110],gcf);
 
% Now present the CheckBoxTree:
jCheckBoxTree = CheckBoxTree(jTree.getModel);
jScrollPane = com.mathworks.mwswing.MJScrollPane(jCheckBoxTree);
[jComp,hc] = javacomponent(jScrollPane,[150,10,120,110],gcf);

a regular MJTree (left) and a CheckBoxTree (right)

a regular MJTree (left) and a CheckBoxTree (right)

Note: Matlab’s CheckBoxTree does not have a separate data model. Instead, it relies on the base MJTree’s model, which is a DefaultTreeModel by default. JIDE’s CheckBoxTree does have its own model.

This concludes my uitree mini-series. If you have any special customizations, please post a comment below.

]]>
https://undocumentedmatlab.com/blog/customizing-uitree-nodes-2/feed 59
Customizing uitree nodes – part 1https://undocumentedmatlab.com/blog/customizing-uitree-nodes https://undocumentedmatlab.com/blog/customizing-uitree-nodes#comments Wed, 25 Aug 2010 18:00:20 +0000 http://undocumentedmatlab.com/?p=1835
 
Related posts:
  1. Uitab colors, icons and images Matlab's semi-documented tab panels can be customized using some undocumented hacks...
  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. Customizing uitree nodes – part 2 This article shows how Matlab GUI tree nodes can be customized with checkboxes and similar controls...
  4. Customizing uitree This article describes how to customize Matlab GUI tree controls created using the undocumented uitree function...
 
]]>
In my previous posts, I introduced the semi-documented uitree function that enables displaying data in a hierarchical (tree) control in Matlab GUI, and showed how it can be customized. Today, I will continue by describing how specific uitree nodes can be customized.

To start the discussion, let’s re-create last week’s simple uitree:

% Fruits
fruits = uitreenode('v0', 'Fruits', 'Fruits', [], false);
fruits.add(uitreenode('v0', 'Apple',  'Apple',  [], true));
fruits.add(uitreenode('v0', 'Pear',   'Pear',   [], true));
fruits.add(uitreenode('v0', 'Banana', 'Banana', [], true));
fruits.add(uitreenode('v0', 'Orange', 'Orange', [], true));
 
% Vegetables
veggies = uitreenode('v0', 'Veggies', 'Vegetables', [], false);
veggies.add(uitreenode('v0', 'Potato', 'Potato', [], true));
veggies.add(uitreenode('v0', 'Tomato', 'Tomato', [], true));
veggies.add(uitreenode('v0', 'Carrot', 'Carrot', [], true));
 
% Root node
root = uitreenode('v0', 'Food', 'Food', [], false);
root.add(veggies);
root.add(fruits);
 
% Tree
figure('pos',[300,300,150,150]);
mtree = uitree('v0', 'Root', root);

User-created tree    User-created tree

User-created tree

Labels

Node labels (descriptions) can be set using their Name property (the second uitreenode data argument). Note that the horizontal space allotted for displaying the node name will not change until the node is collapsed or expanded. So, if the new name requires more than the existing space, it will be displayed as something like “abc…”, until the node is expanded or collapsed.

Node names share the same HTML support feature as all Java Swing labels. Therefore, we can specify font size/face/color, bold, italic, underline, super-/sub-script etc.:

txt1 = '<html><b><u><i>abra</i></u>';
txt2 = '<font color="red"><sup>kadabra</html>';
node.setName([txt1,txt2]);

HTML-enriched tree nodes

HTML-enriched tree nodes

Icons

Tree-node icons can be specified during node creation, as the third data argument to uitreenode, which accepts an icon-path (a string):

iconPath = fullfile(matlabroot,'/toolbox/matlab/icons/greenarrowicon.gif');
node = uitreenode('v0',value,name,iconPath,isLeaf);

Tree node icons can also be created or modified programmatically in run-time, using Matlab’s im2java function. Icons can also be loaded from existing files as follows (real-life programs should check and possibly update jImage’s size to 16 pixels, before setting the node icon, otherwise the icon might get badly cropped; also note the tree-refreshing action):

jImage = java.awt.Toolkit.getDefaultToolkit.createImage(iconPath);
veggies.setIcon(jImage);
veggies.setIcon(im2java(imread(iconPath)));  % an alternative
 
% refresh the veggies node (and all its children)
mtree.reloadNode(veggies);

Setting node icon

Setting node icon

Behavior

Nodes can be modified from leaf (non-expandable) to parent behavior (=expandable) by setting their LeafNode property (a related property is AllowsChildren):

set(node,'LeafNode',false);  % =expandable
node.setLeafNode(0);  % an alternative

One of the questions I was asked was how to “disable” a specific tree node. One way would be to modify the tree’s ExpandFcn callback. Another way is to use a combination of HTML rendering and the node’s AllowsChildren property:

label = char(veggies.getName);
veggies.setName(['<html><font color="gray">' label]);
veggies.setAllowsChildren(false);
t.reloadNode(veggies);

Disabled node

Disabled node

Another possible behavioral customization is adding a context-menu to a uitree. We can set node-specific tooltips using similar means.

Answering a reader’s request from last week, tree nodes icons can be used to present checkboxes, radio buttons and other similar node-specific controls. This can actually be done in several ways, that will be explored in next week’s article.

There are numerous other possible customizations – if readers are interested, perhaps I will describe some of them in future articles. If you have any special request, please post a comment below.

]]>
https://undocumentedmatlab.com/blog/customizing-uitree-nodes/feed 17