Java – 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 Sending HTML emails from Matlabhttps://undocumentedmatlab.com/blog/sending-html-emails-from-matlab https://undocumentedmatlab.com/blog/sending-html-emails-from-matlab#respond Wed, 02 Aug 2017 21:19:42 +0000 http://undocumentedmatlab.com/?p=6986
 
Related posts:
  1. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  2. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  3. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  4. Multi-line uitable column headers Matlab uitables can present long column headers in multiple lines, for improved readability. ...
 
]]>
A few months ago I wrote about various tricks for sending email/text messages from Matlab. Unfortunately, Matlab only sends text emails by default and provides no documented way to send HTML-formatted emails. Text-only emails are naturally very bland and all mail clients in the past 2 decades support HTML-formatted emails. Today I will show how we can send such HTML emails from Matlab.

A quick recap: Matlab’s sendmail function uses Java (specifically, the standard javax.mail package) to prepare and send emails. The Java classes are extremely powerful and so there is no wonder that Mathworks chose to use them rather than reinventing the wheel. However, Matlab’s sendmail function only uses part of the functionality exposed by these classes (admittedly, the most important parts that deal with the basic mail-sending mechanism), and does not expose external hooks or input args that would enable the user to take full advantage of the more advanced features, HTML formatting included.

Only two small changes are needed in sendmail.m to support HTML formatting:

  1. HTML formatting required calling the message-object’s setContent() method, rather than setText().
  2. We need to specify 'text/html' as part of the message’s encoding

To implement these features, change the following (lines #119-130 in the original sendmail.m file of R2017a, changed lines highlighted):

% Construct the body of the message and attachments.
body = formatText(theMessage);
if numel(attachments) == 0    if ~isempty(charset)        msg.setText(body, charset);
    else
        msg.setText(body);
    end
else
    % Add body text.
    messageBodyPart = MimeBodyPart;
    if ~isempty(charset)        messageBodyPart.setText(body, charset);
    ...

to this (changed lines highlighted):

% Construct the body of the message and attachments.
body = formatText(theMessage);
isHtml = ~isempty(body) && body(1) == '<';  % msg starting with '<' indicates HTMLif isHtml    if isempty(charset)        charset = 'text/html; charset=utf-8';    else        charset = ['text/html; charset=' charset];    endendif numel(attachments) == 0  && ~isHtml    if isHtml        msg.setContent(body, charset);    elseif ~isempty(charset)        msg.setText(body, charset);
    else
        msg.setText(body);
    end
    else
        % Add body text.
        messageBodyPart = MimeBodyPart;
        if isHtml            messageBodyPart.setContent(body, charset);        elseif ~isempty(charset)            messageBodyPart.setText(body, charset);
        ...

In addition, I also found it useful to remove the hard-coded 75-character line-wrapping in text messages. This can be done by changing the following (line #291 in the original sendmail.m file of R2017a):

maxLineLength = 75;

to this:

maxLineLength = inf;  % or some other large numeric value

Deployment

It’s useful to note two alternatives for making these fixes:

  • Making the changes directly in %matlabroot%/toolbox/matlab/iofun/sendmail.m. You will need administrator rights to edit this file. You will also need to redo the fix whenever you install Matlab, either installation on a different machine, or installing a new Matlab release. In general, I discourage changing Matlab’s internal files because it is simply not very maintainable.
  • Copying %matlabroot%/toolbox/matlab/iofun/sendmail.m into a dedicated wrapper function (e.g., sendEmail.m) that has a similar function signature and exists on the Matlab path. This has the benefit of working on multiple Matlab releases, and being copied along with the rest of our m-files when we install our Matlab program on a different computer. The downside is that our wrapper function will be stuck with the version of sendmail.m that we copied into it, and we’d lose any possible improvements that Mathworks may implement in future Matlab releases.

The basic idea for the second alternative, the sendEmail.m wrapper, is something like this (the top highlighted lines are the additions made to the original sendmail.m, with everything placed in sendEmail.m on the Matlab path):

function sendEmail(to,subject,theMessage,attachments)%SENDEMAIL Send e-mail wrapper (with HTML formatting)   sendmail(to,subject,theMessage,attachments); 
% The rest of this file is copied from %matlabroot%/toolbox/matlab/iofun/sendmail.m (with the modifications mentioned above):
function sendmail(to,subject,theMessage,attachments)
%SENDMAIL Send e-mail.
%   SENDMAIL(TO,SUBJECT,MESSAGE,ATTACHMENTS) sends an e-mail.  TO is either a
%   character vector specifying a single address, or a cell array of character vector
...

We would then call the wrapper function as follows:

sendEmail('abc@gmail.com', 'email subject', 'regular text message');     % will send a regular text message
sendEmail('abc@gmail.com', 'email subject', '<b><font color="blue">HTML-formatted</font> <i>message');  % HTML-formatted message

In this case, the code automatically infers HTML formatting based on whether the first character in the message body is a ‘<‘ character. Instead, we could just as easily have passed an additional input argument (isHtml) to our sendEmail wrapper function.

Hopefully, in some future Matlab release Mathworks will be kind enough to enable sending 21st-century HTML-formatted emails without needing such hacks. Until then, note that sendmail.m relies on standard non-GUI Java networking classes, which are expected to be supported far into the future, well after Java-based GUI may cease to be supported in Matlab. For this reason I believe that while it seems a bit tricky, the changes that I outlined in today’s post actually have a low risk of breaking in a future Matlab release.

Do you have some other advanced email feature that you use in your Matlab program by some crafty customization to sendmail? If so, please share it in a comment below.

]]>
https://undocumentedmatlab.com/blog/sending-html-emails-from-matlab/feed 0
MathWorks-solicited Java surveyhttps://undocumentedmatlab.com/blog/mathworks-solicited-java-survey https://undocumentedmatlab.com/blog/mathworks-solicited-java-survey#comments Wed, 22 Mar 2017 22:05:34 +0000 http://undocumentedmatlab.com/?p=6866
 
Related posts:
  1. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
  2. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  3. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  4. Matlab callbacks for Java events Events raised in Java code can be caught and handled in Matlab callback functions - this article explains how...
 
]]>
Over the years I’ve reported numerous uses for integrating Java components and functionality in Matlab. As I’ve also recently reported, MathWorks is apparently making a gradual shift away from standalone Java-based figures, toward browser-based web-enabled figures. As I surmised a few months ago, MathWorks has created dedicated surveys to solicit user feedbacks on the most important (and undocumented) non-compatible aspects of this paradigm change: one regarding users’ use of the javacomponent function, the other regarding the use of the figure’s JavaFrame property:

In MathWorks’ words:

In order to extend your ability to build MATLAB apps, we understand you sometimes need to make use of undocumented Java UI technologies, such as the JavaFrame property. In response to your needs, we are working to develop documented alternatives that address gaps in our app building offerings.

To help inform our work and plans, we would like to understand how you are using the JavaFrame property. Based on your understanding of how it is being used within your app, please take a moment to fill out the following survey. The survey will take approximately 1-2 minutes to finish.

I urge anyone who uses one or both of these features to let MathWorks know how you’re using them, so that they could incorporate that functionality into the core (documented) Matlab. The surveys are really short and to the point. If you wish to send additional information, please email George.Caia at mathworks.com.

The more feedback responses that MathWorks will get, the better it will be able to prioritize its R&D efforts for the benefit of all users, and the more likely are certain features to get a documented solution at some future release. If you don’t take the time now to tell MathWorks how you use these features in your code, don’t complain if and when they break in the future…

My personal uses of these features

  • Functionality:
    • Figure: maximize/minimize/restore, enable/disable, always-on-top, toolbar controls, menu customizations (icons, tooltips, font, shortcuts, colors)
    • Table: sorting, filtering, grouping, column auto-sizing, cell-specific behavior (tooltip, context menu, context-sensitive editor, merging cells)
    • Tree control
    • Listbox: cell-specific behavior (tooltip, context menu)
    • Tri-state checkbox
    • uicontrols in general: various event callbacks (e.g. mouse hover/unhover, focus gained/lost)
    • Ability to add Java controls e.g. color/font/date/file selector panel or dropdown, spinner, slider, search box, password field
    • Ability to add 3rd-party components e.g. JFreeCharts, JIDE controls/panels

  • Appearance:
    • Figure: undecorated (frameless), other figure frame aspects
    • Table: column/cell-specific rendering (alignment, icons, font, fg/bg color, string formatting)
    • Listbox: auto-hide vertical scrollbar as needed, cell-specific renderer (icon, font, alignment, fg/bg color)
    • Button/checkbox/radio: icons, text alignment, border customization, Look & Feel
    • Right-aligned checkbox (button to the right of label)
    • Panel: border customization (rounded/matte/…)

You can find descriptions/explanations of many of these in posts I made on this website over the years.

]]>
https://undocumentedmatlab.com/blog/mathworks-solicited-java-survey/feed 2
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
Sending email/text messages from Matlabhttps://undocumentedmatlab.com/blog/sending-email-text-messages-from-matlab https://undocumentedmatlab.com/blog/sending-email-text-messages-from-matlab#comments Wed, 07 Dec 2016 21:24:03 +0000 http://undocumentedmatlab.com/?p=6765
 
Related posts:
  1. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  2. Legend ‘-DynamicLegend’ semi-documented feature The built-in Matlab legend function has a very useful semi-documented feature for automatic dynamic update, which is explained here....
  3. Undocumented XML functionality Matlab's built-in XML-processing functions have several undocumented features that can be used by Java-savvy users...
  4. Inactive Control Tooltips & Event Chaining Inactive Matlab uicontrols cannot normally display their tooltips. This article shows how to do this with a combination of undocumented Matlab and Java hacks....
 
]]>
In this day and age, applications are expected to communicate with users by sending email/text messages to alert them about applicative events (“IBM stock purchased @$99.99” or “House is on fire!”). Matlab has included the sendmail function to handle this for many years. Unfortunately, sendmail requires some tweaking to be useful on all but the most basic/insecure mail servers. Today’s post will hopefully fill the missing gaps.

None of the information I’ll present today is really new – it was all there already if you just knew what to search for online. But hopefully today’s post will concentrate all these loose ends in a single place, so it may have some value:

Using a secure mail server

All modern mail servers use end-to-end TLS/SSL encryption. The sendmail function needs extra configuration to handle such connections, since it is configured for a non-encrypted connection by default. Here’s the code that does this for gmail, using SMTP server smtp.gmail.com and default port #465 (for other SMTP servers, see here):

setpref('Internet', 'SMTP_Server',   'smtp.gmail.com');
setpref('Internet', 'SMTP_Username', username);
setpref('Internet', 'SMTP_Password', password);
 
props = java.lang.System.getProperties;
props.setProperty('mail.smtp.auth',                'true');  % Note: 'true' as a string, not a logical value!
props.setProperty('mail.smtp.starttls.enable',     'true');  % Note: 'true' as a string, not a logical value!
props.setProperty('mail.smtp.socketFactory.port',  '465');   % Note: '465'  as a string, not a numeric value!
props.setProperty('mail.smtp.socketFactory.class', 'javax.net.ssl.SSLSocketFactory');
 
sendmail(recipient, title, body, attachments);  % e.g., sendmail('recipient@gmail.com', 'Hello world', 'What a nice day!', 'C:\images\sun.jpg')

All this is not enough to enable Matlab to connect to gmail’s SMTP servers. In addition, we need to set the Google account to allow access from “less secure apps” (details, direct link). Without this, Google will not allow Matlab to relay emails. Other mail servers may require similar server-side account configurations to enable Matlab’s access.

Note: This code snippet uses a bit of Java as you can see. Under the hood, all networking code in Matlab relies on Java, and sendmail is no exception. For some reason that I don’t fully understand, MathWorks chose to label the feature of using sendmail with secure mail servers as a feature that relies on “undocumented commands” and is therefore not listed in sendmail‘s documentation. Considering the fact that all modern mail servers are secure, this seems to make sendmail rather useless without the undocumented extension. I assume that TMW are well aware of this, which is the reason they posted a partial documentation in the form of an official tech-support answer. I hope that one day MathWorks will incorporate it into sendmail as optional input args, so that using sendmail with secure servers would become fully documented and officially supported.

Emailing multiple recipients

To specify multiple email recipients, it is not enough to set sendmail‘s recipient input arg to a string with , or ; delimiters. Instead, we need to provide a cell array of individual recipient strings. For example:

sendmail({'recipient1@gmail.com','recipient2@gmail.com'}, 'Hello world', 'What a nice day!')

Note: this feature is actually fully documented in sendmail‘s doc-page, but for some reason I see that some users are not aware of it (to which it might be said: RTFM!).

Sending text messages

With modern smartphones, text (SMS) messages have become rather outdated, as most users get push notifications of incoming emails. Still, for some users text messages may still be a useful. To send such messages, all we need is to determine our mobile carrier’s email gateway for SMS messages, and send a simple text message to that email address. For example, to send a text message to T-Mobile number 123-456-7890 in the US, simply email the message to 1234567890@tmomail.net (details).

Ke Feng posted a nice Matlab File Exchange utility that wraps this messaging for a wide variety of US carriers.

User configuration panel

Many GUI programs contain configuration panels/tabs/windows. Enabling the user to set up their own email provider is a typical use-case for such a configuration. Naturally, you’d want your config panel not to display plain-text password, nor non-integer port numbers. You’d also want the user to be able to test the email connection.

Here’s a sample implementation for such a panel that I implemented for a recent project – I plan to discuss the implementation details of the password and port (spinner) controls in my next post, so stay tuned:

User configuration of emails in Matlab GUI (click to zoom-in)
User configuration of emails in Matlab GUI (click to zoom-in)

]]>
https://undocumentedmatlab.com/blog/sending-email-text-messages-from-matlab/feed 5
Speeding up Matlab-JDBC SQL querieshttps://undocumentedmatlab.com/blog/speeding-up-matlab-jdbc-sql-queries https://undocumentedmatlab.com/blog/speeding-up-matlab-jdbc-sql-queries#comments Wed, 16 Nov 2016 11:43:17 +0000 http://undocumentedmatlab.com/?p=6742
 
Related posts:
  1. Javacomponent background color This article explains how to align Java component background color with a Matlab color....
  2. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  3. Pause for the better Java's thread sleep() function is much more accurate than Matlab's pause() function. ...
  4. Explicit multi-threading in Matlab part 1 Explicit multi-threading can be achieved in Matlab by a variety of simple means. ...
 
]]>
Many of my consulting projects involve interfacing a Matlab program to an SQL database. In such cases, using MathWorks’ Database Toolbox is a viable solution. Users who don’t have the toolbox can also easily connect directly to the database using either the standard ODBC bridge (which is horrible for performance and stability), or a direct JDBC connection (which is also what the Database Toolbox uses under the hood). I explained this Matlab-JDBC interface in detail in chapter 2 of my Matlab-Java programming book. A bare-bones implementation of an SQL SELECT query follows (data update queries are a bit different and will not be discussed here):

% Load the appropriate JDBC driver class into Matlab's memory
% (but not directly, to bypass JIT pre-processing - we must do it in run-time!)
driver = eval('com.mysql.jdbc.Driver');  % or com.microsoft.sqlserver.jdbc.SQLServerDriver or whatever
 
% Connect to DB
dbPort = '3306'; % mySQL=3306; SQLServer=1433; Oracle=...
connectionStr = ['jdbc:mysql://' dbURL ':' dbPort '/' schemaName];  % or ['jdbc:sqlserver://' dbURL ':' dbPort ';database=' schemaName ';'] or whatever
dbConnObj = java.sql.DriverManager.getConnection(connectionStr, username, password);
 
% Send an SQL query statement to the DB and get the ResultSet
stmt = dbConnObj.createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
try stmt.setFetchSize(1000); catch, end  % the default fetch size is ridiculously small in many DBs
rs = stmt.executeQuery(sqlQueryStr);
 
% Get the column names and data-types from the ResultSet's meta-data
MetaData = rs.getMetaData;
numCols = MetaData.getColumnCount;
data = cell(0,numCols);  % initialize
for colIdx = numCols : -1 : 1
    ColumnNames{colIdx} = char(MetaData.getColumnLabel(colIdx));
    ColumnType{colIdx}  = char(MetaData.getColumnClassName(colIdx));  % http://docs.oracle.com/javase/7/docs/api/java/sql/Types.html
end
ColumnType = regexprep(ColumnType,'.*\.','');
 
% Get the data from the ResultSet into a Matlab cell array
rowIdx = 1;
while rs.next  % loop over all ResultSet rows (records)
    for colIdx = 1 : numCols  % loop over all columns in the row
        switch ColumnType{colIdx}
            case {'Float','Double'}
                data{rowIdx,colIdx} = rs.getDouble(colIdx);
            case {'Long','Integer','Short','BigDecimal'}
                data{rowIdx,colIdx} = double(rs.getDouble(colIdx));
            case 'Boolean'
                data{rowIdx,colIdx} = logical(rs.getBoolean(colIdx));
            otherwise %case {'String','Date','Time','Timestamp'}
                data{rowIdx,colIdx} = char(rs.getString(colIdx));
        end
    end
    rowIdx = rowIdx + 1;
end
 
% Close the connection and clear resources
try rs.close();   catch, end
try stmt.close(); catch, end
try dbConnObj.closeAllStatements(); catch, end
try dbConnObj.close(); catch, end  % comment this to keep the dbConnObj open and reuse it for subsequent queries

Naturally, in a real-world implementation you also need to handle database timeouts and various other errors, handle data-manipulation queries (not just SELECTs), etc.

Anyway, this works well in general, but when you try to fetch a ResultSet that has many thousands of records you start to feel the pain – The SQL statement may execute much faster on the DB server (the time it takes for the stmt.executeQuery call), yet the subsequent double-loop processing to fetch the data from the Java ResultSet object into a Matlab cell array takes much longer.

In one of my recent projects, performance was of paramount importance, and the DB query speed from the code above was simply not good enough. You might think that this was due to the fact that the data cell array is not pre-allocated, but this turns out to be incorrect: the speed remains nearly unaffected when you pre-allocate data properly. It turns out that the main problem is due to Matlab’s non-negligible overhead in calling methods of Java objects. Since the JDBC interface only enables retrieving a single data item at a time (in other words, bulk retrieval is not possible), we have a double loop over all the data’s rows and columns, in each case calling the appropriate Java method to retrieve the data based on the column’s type. The Java methods themselves are extremely efficient, but when you add Matlab’s invocation overheads the total processing time is much much slower.

So what can be done? As Andrew Janke explained in much detail, we basically need to push our double loop down into the Java level, so that Matlab receives arrays of primitive values, which can then be processed in a vectorized manner in Matlab.

So let’s create a simple Java class to do this:

// Copyright (c) Yair Altman UndocumentedMatlab.com
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
 
public class JDBC_Fetch {
 
	public static int DEFAULT_MAX_ROWS = 100000;   // default cache size = 100K rows (if DB does not support non-forward-only ResultSets)
 
	public static Object[] getData(ResultSet rs) throws SQLException {
		try {
			if (rs.last()) {  // data is available
				int numRows = rs.getRow();    // row # of the last row
				rs.beforeFirst();             // get back to the top of the ResultSet
				return getData(rs, numRows);  // fetch the data
			} else {  // no data in the ResultSet
				return null;
			}
		} catch (Exception e) {
			return getData(rs, DEFAULT_MAX_ROWS);
		}
	}
 
	public static Object[] getData(ResultSet rs, int maxRows) throws SQLException {
		// Read column number and types from the ResultSet's meta-data
		ResultSetMetaData metaData = rs.getMetaData();
		int numCols = metaData.getColumnCount();
		int[] colTypes = new int[numCols+1];
		int numDoubleCols = 0;
		int numBooleanCols = 0;
		int numStringCols = 0;
		for (int colIdx = 1; colIdx <= numCols; colIdx++) {
			int colType = metaData.getColumnType(colIdx);
			switch (colType) {
				case Types.FLOAT:
				case Types.DOUBLE:
				case Types.REAL:
					colTypes[colIdx] = 1;  // double
					numDoubleCols++;
					break;
				case Types.DECIMAL:
				case Types.INTEGER:
				case Types.TINYINT:
				case Types.SMALLINT:
				case Types.BIGINT:
					colTypes[colIdx] = 1;  // double
					numDoubleCols++;
					break;
				case Types.BIT:
				case Types.BOOLEAN:
					colTypes[colIdx] = 2;  // boolean
					numBooleanCols++;
					break;
				default: // 'String','Date','Time','Timestamp',...
					colTypes[colIdx] = 3;  // string
					numStringCols++;
			}
		}
 
		// Loop over all ResultSet rows, reading the data into the 2D matrix caches
		int rowIdx = 0;
		double [][] dataCacheDouble  = new double [numDoubleCols] [maxRows];
		boolean[][] dataCacheBoolean = new boolean[numBooleanCols][maxRows];
		String [][] dataCacheString  = new String [numStringCols] [maxRows];
		while (rs.next() && rowIdx < maxRows) {
			int doubleColIdx = 0;
			int booleanColIdx = 0;
			int stringColIdx = 0;
			for (int colIdx = 1; colIdx <= numCols; colIdx++) {
				try {
					switch (colTypes[colIdx]) {
						case 1:  dataCacheDouble[doubleColIdx++][rowIdx]   = rs.getDouble(colIdx);   break;  // numeric
						case 2:  dataCacheBoolean[booleanColIdx++][rowIdx] = rs.getBoolean(colIdx);  break;  // boolean
						default: dataCacheString[stringColIdx++][rowIdx]   = rs.getString(colIdx);   break;  // string
					}
				} catch (Exception e) {
					System.out.println(e);
					System.out.println(" in row #" + rowIdx + ", col #" + colIdx);
				}
			}
			rowIdx++;
		}
 
		// Return only the actual data in the ResultSet
		int doubleColIdx = 0;
		int booleanColIdx = 0;
		int stringColIdx = 0;
		Object[] data = new Object[numCols];
		for (int colIdx = 1; colIdx <= numCols; colIdx++) {
			switch (colTypes[colIdx]) {
				case 1:   data[colIdx-1] = dataCacheDouble[doubleColIdx++];    break;  // numeric
				case 2:   data[colIdx-1] = dataCacheBoolean[booleanColIdx++];  break;  // boolean
				default:  data[colIdx-1] = dataCacheString[stringColIdx++];            // string
			}
		}
		return data;
	}
}

So now we have a JDBC_Fetch class that we can use in our Matlab code, replacing the slow double loop with a single call to JDBC_Fetch.getData(), followed by vectorized conversion into a Matlab cell array (matrix):

% Get the data from the ResultSet using the JDBC_Fetch wrapper
data = cell(JDBC_Fetch.getData(rs));
for colIdx = 1 : numCols
   switch ColumnType{colIdx}
      case {'Float','Double'}
          data{colIdx} = num2cell(data{colIdx});
      case {'Long','Integer','Short','BigDecimal'}
          data{colIdx} = num2cell(data{colIdx});
      case 'Boolean'
          data{colIdx} = num2cell(data{colIdx});
      otherwise %case {'String','Date','Time','Timestamp'}
          %data{colIdx} = cell(data{colIdx});  % no need to do anything here!
   end
end
data = [data{:}];

On my specific program the resulting speedup was 15x (this is not a typo: 15 times faster). My fetches are no longer limited by the Matlab post-processing, but rather by the DB’s processing of the SQL statement (where DB indexes, clustering, SQL tuning etc. come into play).

Additional speedups can be achieved by parsing dates at the Java level (rather than returning strings), as well as several other tweaks in the Java and Matlab code (refer to Andrew Janke’s post for some ideas). But certainly the main benefit (the 80% of the gain that was achieved in 20% of the worktime) is due to the above push of the main double processing loop down into the Java level, leaving Matlab with just a single Java call to JDBC_Fetch.

Many additional ideas of speeding up database queries and Matlab programs in general can be found in my second book, Accelerating Matlab Performance.

If you’d like me to help you speed up your Matlab program, please email me (altmany at gmail), or fill out the query form on my consulting page.

]]>
https://undocumentedmatlab.com/blog/speeding-up-matlab-jdbc-sql-queries/feed 6
Working with non-standard DPI displayshttps://undocumentedmatlab.com/blog/working-with-non-standard-dpi-displays https://undocumentedmatlab.com/blog/working-with-non-standard-dpi-displays#comments Wed, 09 Nov 2016 21:47:27 +0000 http://undocumentedmatlab.com/?p=6736
 
Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  2. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  3. Blurred Matlab figure window Matlab figure windows can be blurred using a semi-transparent overlaid window - this article explains how...
  4. Customizing figure toolbar background Setting the figure toolbar's background color can easily be done using just a tiny bit of Java magic powder. This article explains how. ...
 
]]>
With high-density displays becoming increasingly popular, some users set their display’s DPI to a higher-than-standard (i.e., >100%) value, in order to compensate for the increased pixel density to achieve readable interfaces. This OS setting tells the running applications that there are fewer visible screen pixels, and these are spread over a larger number of physical pixels. This works well for most cases (at least on recent OSes, it was a bit buggy in non-recet ones). Unfortunately, in some cases we might actually want to know the screen size in physical, rather than logical, pixels. Apparently, Matlab root’s ScreenSize property only reports the logical (scaled) pixel size, not the physical (unscaled) one:

>> get(0,'ScreenSize')   % with 100% DPI (unscaled standard)
ans =
        1       1      1366       768
 
>> get(0,'ScreenSize')   % with 125% DPI (scaled)
ans =
        1       1      1092.8     614.4

The same phenomenon also affects other related properties, for example MonitorPositions.

Raimund Schlüßler, a reader on this blog, was kind enough to point me to this problem and its workaround, which I thought worthy to share here: To get the physical screen-size, use the following builtin Java command:

>> jScreenSize = java.awt.Toolkit.getDefaultToolkit.getScreenSize
jScreenSize =
java.awt.Dimension[width=1366,height=768]
 
>> width = jScreenSize.getWidth
width =
        1366
 
>> height = jScreenSize.getHeight
height =
        768

Also see the related recent article on an issue with the DPI-aware feature starting with R2015b.

Upcoming travels – London/Belfast, Zürich & Geneva

I will shortly be traveling to consult some clients in Belfast (via London), Zürich and Geneva. If you are in the area and wish to meet me to discuss how I could bring value to your work, then please email me (altmany at gmail):

  • Belfast: Nov 28 – Dec 1 (flying via London)
  • Zürich: Dec 11-12
  • Geneva: Dec 13-15
]]>
https://undocumentedmatlab.com/blog/working-with-non-standard-dpi-displays/feed 6
uigetfile/uiputfile customizationshttps://undocumentedmatlab.com/blog/uigetfile-uiputfile-customizations https://undocumentedmatlab.com/blog/uigetfile-uiputfile-customizations#comments Wed, 02 Nov 2016 23:38:57 +0000 http://undocumentedmatlab.com/?p=6728
 
Related posts:
  1. Plot-type selection components Several built-in components enable programmatic plot-type selection in Matlab GUI - this article explains how...
  2. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  3. Animated busy (spinning) icon An animated spinning icon label can easily be embedded in Matlab GUI. ...
  4. Auto-completion widget Matlab includes a variety of undocumented internal controls that can be used for an auto-completion component. ...
 
]]>
Matlab includes a few built-in file and folder selection dialog windows, namely uigetfile, uiputfile and uigetdir. Unfortunately, these functions are not easily extendable for user-defined functionalities. Over the years, several of my consulting clients have asked me to provide them with versions of these dialog functions that are customized in certain ways. In today’s post I discuss a few of these customizations: a file selector dialog with a preview panel, and automatic folder update as-you-type in the file-name edit box.

It is often useful to have an integrated preview panel to display the contents of a file in a file-selection dialog. Clicking the various files in the tree-view would display a user-defined preview in the panel below, based on the file’s contents. An integrated panel avoids the need to manage multiple figure windows, one for the selector dialog and another for the preview. It also reduces the screen real-estate used by the dialog (also see the related resizing customization below).

I call the end-result uigetfile_with_preview; you can download it from the Matlab File Exchange:

filename = uigetfile_with_preview(filterSpec, prompt, folder, callbackFunction, multiSelectFlag)

uigetfile_with_preview

As you can see from the function signature, the user can specify the file-type filter, prompt and initial folder (quite similar to uigetfile, uiputfile), as well as a custom callback function for updating the preview of a selected file, and a flag to enable selecting multiple files (not just one).

uigetfile_with_preview.m only has ~120 lines of code and plenty of comments, so feel free to download and review the code. It uses the following undocumented aspects:

  1. I used a com.mathworks.hg.util.dFileChooser component for the main file selector. This is a builtin Matlab control that extends the standard javax.swing.JFileChooser with a few properties and methods. I don’t really need the extra features, so you can safely replace the component with a JFileChooser if you wish (lines 54-55). Various properties of the file selector are then set, such as the folder that is initially displayed, the multi-selection flag, the component background color, and the data-type filter options.
  2. I used the javacomponent function to place the file-selector component within the dialog window.
  3. I set a callback on the component’s PropertyChangeCallback that is invoked whenever the user interactively selects a new file. This callback clears the preview panel and then calls the user-defined callback function (if available).
  4. I set a callback on the component’s ActionPerformedCallback that is invoked whenever the user closes the figure or clicks the “Open” button. The selected filename(s) is/are then returned to the caller and the dialog window is closed.
  5. I set a callback on the component’s file-name editbox’s KeyTypedCallback that is invoked whenever the user types in the file-name editbox. The callback checks whether the entered text looks like a valid folder path and if so then it automatically updates the displayed folder as-you-type.

If you want to convert the code to a uiputfile variant, add the following code lines before the uiwait in line 111:

hjFileChooser.setShowOverwriteDialog(true);  % default: false (true will display a popup alert if you select an existing file)
hjFileChooser.setDialogType(hjFileChooser.java.SAVE_DIALOG);  % default: OPEN_DIALOG
hjFileChooser.setApproveButtonText('Save');  % or any other string. Default for SAVE_DIALOG: 'Save'
hjFileChooser.setApproveButtonToolTipText('Save file');  % or any other string. Default for SAVE_DIALOG: 'Save selected file'

In memory of my dear father.

]]>
https://undocumentedmatlab.com/blog/uigetfile-uiputfile-customizations/feed 2
Listbox selection hackshttps://undocumentedmatlab.com/blog/listbox-selection-hacks https://undocumentedmatlab.com/blog/listbox-selection-hacks#comments Wed, 13 Jul 2016 15:36:19 +0000 http://undocumentedmatlab.com/?p=6534
 
Related posts:
  1. Editbox data input validation Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...
  2. Continuous slider callback Matlab slider uicontrols do not enable a continuous-motion callback by default. This article explains how this can be achieved using undocumented features....
  3. 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....
  4. Customizing combobox popups Matlab combobox (dropdown) popups can be customized in a variety of ways. ...
 
]]>
Last week a reader on the CSSM newsgroup asked whether it is possible to programmatically deselect all listbox items. By default, Matlab listboxes enable a single item selection: trying to deselect it interactively has no effect, while trying to set the listbox’s Value property to empty ([]) results in the listbox disappearing and a warning issued to the Matlab console:

Single-selection Matlab listbox

>> hListbox = uicontrol('Style','list', 'String',{'item #1','item #2','item #3','item #4','item #5','item #6'});
>> set(hListbox,'Value',[]);
Warning: Single-selection 'listbox' control requires a scalar Value.
Control will not be rendered until all of its parameter values are valid
(Type "warning off MATLAB:hg:uicontrol:ValueMustBeScalar" to suppress this warning.)

The reader’s question was whether there is a way to bypass this limitation so that no listbox item will be selected. The answer to this question was provided by MathWorker Steve(n) Lord. Steve is a very long-time benefactor of the Matlab community with endless, tireless, and patient advise to queries small and large (way beyond the point that would have frustrated mere mortals). Steve pointed out that by default, Matlab listboxes only enable a single selection – not more and not less. However, when the listbox’s Max value is set to be >1, the listbox enables multiple-items selection, meaning that Value accepts and reports an array of item indices, and there is nothing that prevents this array from being empty (meaning no items selected):

>> hListbox = uicontrol('Style','list', 'Max',2, 'String',{'item #1','item #2','item #3','item #4','item #5','item #6'});
>> set(hListbox,'Value',[]);  % this is ok - listbox appears with no items selected

Note: actually, the listbox checks the value of MaxMin, but by default Min=0 and there is really no reason to modify this default value, just Max.

While this makes sense if you think about it, the existing documentation makes no mention of this fact:

The Max property value helps determine whether the user can select multiple items in the list box simultaneously. If Max – Min > 1, then the user can select multiple items simultaneously. Otherwise, the user cannot select multiple items simultaneously. If you set the Max and Min properties to allow multiple selections, then the Value property value can be a vector of indices.

Some readers might think that this feature is not really undocumented, since it does not directly conflict with the documentation text, but then so are many other undocumented aspects and features on this blog, which are not mentioned anywhere in the official documentation. I contend that if this feature is officially supported, then it deserves an explicit sentence in the official documentation.

However, the original CSSM reader wanted to preserve Matlab’s single-selection model while enabling deselection of an item. Basically, the reader wanted a selection model that enables 0 or 1 selections, but not 2 or more. This requires some tweaking using the listbox’s selection callback:

set(hListbox,'Callback',@myCallbackFunc);
 
...
function test(hListbox, eventData)
   value = get(hListbox, 'Value');
   if numel(value) > 1
       set(hListbox, 'Value', value(1));
   end
end

…or a callback-function version that is a bit better because it takes the previous selection into account and tries to set the new selection to the latest-selected item (this works in most cases, but not with shift-clicks as explained below):

function myCallbackFunc(hListbox, eventData)
   lastValue = getappdata(hListbox, 'lastValue');
   value = get(hListbox, 'Value');
   if ~isequal(value, lastValue)
      value2 = setdiff(value, lastValue);
      if isempty(value2)
         setappdata(hListbox, 'lastValue', value);
      else
         value = value2(1);  % see quirk below
         setappdata(hListbox, 'lastValue', value);
         set(hListbox, 'Value', value);
      end
   end
end

This does the job of enabling only a single selection at the same time as allowing the user to interactively deselect that item (by ctrl-clicking it).

There’s just a few quirks: If the user selects a block of items (using shift-click), then only the second-from-top item in the block is selected, rather than the expected last-selected item. This is due to line #9 in the callback code which selects the first value. Matlab does not provide us with information about which item was clicked, so this cannot be helped using pure Matlab. Another quirk that cannot easily be solved using pure Matlab is the flicker that occurs when the selection changes and is then corrected by the callback.

We can solve both of these problems using the listbox’s underlying Java component, which we can retrieve using my findjobj utility:

% No need for the standard Matlab callback now
set(hListbox,'Callback',[]);
 
% Get the underlying Java component peer
jScrollPane = findjobj(h);
jListbox = jScrollPane.getViewport.getView;
jListbox = handle(jListbox,'CallbackProperties');  % enable callbacks
 
% Attach our callback to the listbox's Java peer
jListbox.ValueChangedCallback = {@myCallbackFunc, hListbox};
 
...
function myCallbackFunc(jListbox, eventData, hListbox)
   if numel(jListbox.getSelectedIndices) > 1
      set(hListbox, 'Value', jListbox.getLeadSelectionIndex+1);  % +1 because Java indices start at 0
   end
end

We can use a similar mechanism to control other aspects of selection, for example to enable only up to 3 selections but no more etc.

We can use this underlying Java component peer for a few other useful selection-related hacks: First, we can use the peer’s RightSelectionEnabled property or setRightSelectionEnabled() method to enable the user to select by right-clicking listbox items (this is disabled by default):

jListbox.setRightSelectionEnabled(true);  % false by default
set(jListbox,'RightSelectionEnabled',true);  % equivalent alternative

A similarly useful property is DragSelectionEnabled (or the corresponding setDragSelectionEnabled() method), which is true by default, and controls whether the selection is extended to other items when the mouse drags an item up or down the listbox.

Finally, we can control whether in multi-selection mode we enable the user to only select a single contiguous block of items, or not (which is Matlab’s default behavior). This is set via the SelectionMode property (or associated setSelectionMode() method), as follows:

jListbox.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
jListbox.setSelectionMode(1);  % equivalent alternative (less maintainable/readable, but simpler)

SINGLE_SELECTION (default for Max=1)SINGLE_INTERVAL_SELECTION (only possible with Java)MULTIPLE_INTERVAL_SELECTION (default for Max>1)
SINGLE_SELECTION =0SINGLE_INTERVAL_SELECTION =1MULTIPLE_INTERVAL_SELECTION =2
(Matlab default for Max=1)(only possible with Java)(Matlab default for Max>1)

Additional listbox customizations can be found in related posts on this blog (see links below), or in section 6.6 of my Matlab-Java Programming Secrets book (which is still selling nicely almost five years after its publication, to the pleasant surprise of my publisher…).

]]>
https://undocumentedmatlab.com/blog/listbox-selection-hacks/feed 4
Handling red Java console errorshttps://undocumentedmatlab.com/blog/handling-red-java-console-errors https://undocumentedmatlab.com/blog/handling-red-java-console-errors#comments Wed, 29 Jun 2016 17:00:51 +0000 http://undocumentedmatlab.com/?p=6468
 
Related posts:
  1. Setting system tray icons System-tray icons can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  2. Setting system tray popup messages System-tray icons and messages can be programmatically set and controlled from within Matlab, using new functionality available since R2007b....
  3. JGit-Matlab integration JGit source-control integration package can easily be integrated in Matlab. ...
  4. Non-textual editor actions The UIINSPECT utility can be used to expand EditorMacro capabilities to non-text-insertion actions. This is how:...
 
]]>
Anyone who has worked with non-trivial Matlab GUIs knows that from time to time we see various red Java stack-trace errors appear in the Matlab console (Command Window). These errors do not appear often when using documented Matlab controls, but they do from time to time. The errors appear significantly more frequently when working with undocumented Java-based hacks that I often show on this blog, and especially when working with complex controls such as uitable or uitree. Such controls have a very large code-base under the hood, and the Matlab code and data sometimes clashes with the asynchronous Java methods that run on a separate thread. Such clashes and race conditions often lead to red Java stack-trace errors that are spewed onto the Matlab console. For example:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at com.jidesoft.plaf.basic.BasicCellSpanTableUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at com.jidesoft.grid.CellStyleTable.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	...

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 >= 0
	at java.util.Vector.elementAt(Unknown Source)
	at javax.swing.table.DefaultTableColumnModel.getColumn(Unknown Source)
	at com.jidesoft.grid.ContextSensitiveTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.CellSpanTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.TreeTable.getActualCellRenderer(Unknown Source)
	at com.jidesoft.grid.GroupTable.getCellRenderer(Unknown Source)
	at com.jidesoft.grid.JideTable.b(Unknown Source)
	at com.jidesoft.grid.CellSpanTable.calculateRowHeight(Unknown Source)
	...

In almost all such Java error messages, the error is asynchronous to the Matlab code and does not interrupt it. No error exception is thrown (or can be trapped), and the Matlab code proceeds without being aware that anything is wrong. In fact, in the vast majority of such cases, nothing is visibly wrong – the program somehow overcomes the reported problem and there are no visible negative effects on the GUI. In other words, these error messages are harmless and can almost always be ignored. Still, if we could only stop those annoying endless red stack-trace messages in the Matlab console!

Note that today’s post only discusses untrappable asynchronous Java error messages, not synchronous errors that can be trapped in Matlab via try-catch. These synchronous errors are often due to programmatic errors (e.g., bad method input args or an empty reference handle) and can easily be handled programmatically. On the other hand, the asynchronous errors are non-trappable, so they are much more difficult to isolate and fix.

In many of the cases, the error occurs when the control’s underlying data model is changed by the Matlab code, and some of the controls’s Java methods are not synced with the new model by the time they run. This can be due to internal bugs in the Matlab or Java control’s implementation, or to simple race conditions that occur between the Matlab thread and the Java Event Dispatch Thread (EDT). As noted here, such race conditions can often be solved by introducing a simple delay into the Matlab code:

javaControl.doSomething();
pause(0.05); drawnow;javaControl.doSomethingElse();

In addition, asking Matlab to run the Java component’s methods on the EDT can also help solve race conditions:

javaControl = javaObjectEDT(javaControl);

Unfortunately, sometimes both of these are not enough. In such cases, one of the following ideas might help:

  • Add fprintf(' \b') to your Matlab code: this seemingly innocent hack of displaying a space & immediately erasing it with backspace, appears to force the Java engine to flush its event queue and synchronize things, thereby avoiding the annoying Java console errors. I know it sounds like adding a sprinkle of useless black magic to the code, but it does really work in some cases!
    javaControl.doSomething();
    pause(0.05); drawnow;  % this never hurt anyone!
    fprintf(' \b');javaControl.doSomethingElse();
  • It is also possible to directly access the console text area and remove all the text after a certain point. Note that I strongly discourage messing around with the console text in this manner, since it might cause problems with Matlab’s internals. Still, if you are adventurous enough to try, then here’s an example:
    jCmdWinDoc = com.mathworks.mde.cmdwin.CmdWinDocument.getInstance;
    currentPos = cmdWinDoc.getLength;
     
    javaControl.doSomething();
    pause(0.05); drawnow;  % this never hurt anyone!
    javaControl.doSomethingElse();
     
    pause(0.1);  % let the java error time to display itself in the console
    jCmdWinDoc.remove(currentPos, cmdWinDoc.getLength-currentPos);
  • When all else fails, consider simply clearing the Matlab console using the Matlab clc command a short while after updating the Java control. This will erase the red Java errors, along with everything else in the console, so naturally it cannot be freely used if you use the console to display useful information to the user.

It should be emphasized: not all of these suggested remedies work in all cases; in some cases some of them work, and in other cases others might work. There does not seem to be a general panacea to this issue. The main purpose of the article was to list the possible solutions in a single place, so that users could try them out and select those that work for each specific case.

Do you know of any other (perhaps better) way of avoiding or hiding such asynchronous Java console errors? If so, then please post a comment below.

]]>
https://undocumentedmatlab.com/blog/handling-red-java-console-errors/feed 6
Figure window customizationshttps://undocumentedmatlab.com/blog/figure-window-customizations https://undocumentedmatlab.com/blog/figure-window-customizations#respond Wed, 01 Jun 2016 08:00:11 +0000 http://undocumentedmatlab.com/?p=6439
 
Related posts:
  1. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
  2. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  3. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  4. Frameless (undecorated) figure windows Matlab figure windows can be made undecorated (borderless, title-less). ...
 
]]>
A friend recently asked me, in light of my guesstimate that Java-based Matlab figures will be replaced by web-based figures sometime around 2018-2020, whether there are any “killer features” that make it worthwhile to use undocumented Java-based tricks today, despite the fact that they will probably break in 2-5 years. In my opinion, there are many such features; today I will focus on just a subset of them – those features that relate to the entire figure window.

Over the years I wrote many articles here about figure-level customizations, as well as an entire chapter in my Matlab-Java programming book. So today’s post will be a high-level overview, and users who are interested in any specific topic can visit the referenced links for the implementation details.

An undecorated Matlab figure window - one of many possible figure-level customizations
An undecorated Matlab figure window – one of many possible figure-level customizations

JavaFrame

JavaFrame is an undocumented hidden property of the figure handle that provides access to the underlying Java window (JFrame) peer object’s reference. Since R2008a, a warning is issued whenever we retrieve this property:

>> jFrame = get(gcf,'JavaFrame');
Warning: figure JavaFrame property will be obsoleted in a future release.
For more information see the JavaFrame resource on the MathWorks web site.
(Type "warning off MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame" to suppress this warning.) 

Until HG2 (R2014b+) we could suppress the warning by simply wrapping the figure handle within a handle() call, as explained here. Since R2014b we need to use the warning function to do this:

warning('off', 'MATLAB:HandleGraphics:ObsoletedProperty:JavaFrame');

We can do several things directly with the JavaFrame‘s properties and methods, including:

  • Maximize/minimize/restore the window, via the properties Maximized/Minimized (which accept and return a boolean (logical) value), or the corresponding methods jFrame.isMaximized(), isMinimized(), setMaximized(flag), setMinimized(flag). details
  • Modify the container to which the figure will be docked. By default this is the “Figures” container, but this can be changed to any user-specified container, or even to the “Editor”, using the GroupName property or its associated methods. See the related setFigDockGroup utility that I posted on the Matlab File exchange.
  • Remove the top separator line between the toolbar and the content-pane, to blend them together, via the jFrame.showTopSeparator(flag) method.
  • Retrieve a direct Java reference to the Matlab Desktop and the figure’s internal containers via the Desktop and FigurePanelContainer properties, respectively (we can also get those references by other means).
  • Retrieve a direct Java reference to the containing JFrame (Java window), as discussed below
  • A few other features that I will not discuss here

MathWorks have set up a dedicated webpage where you can specify how you are using JavaFrame and why it is important for you: http://www.mathworks.com/javaframe. I encourage you to use this webpage to tell MathWorks which features are important for you. This will help them to decide which functionality should be added to the new web-based figures.

JFrame window

The JavaFrame handle enables direct retrieval of the containing Java JFrame (window) reference, using several alternatives. Here are two of these alternatives (there are others):

% Alternative #1
>> jWindow = jFrame.getFigurePanelContainer.getTopLevelAncestor
jWindow = 
com.mathworks.hg.peer.FigureFrameProxy$FigureFrame[fClientProxyFrame,72,62,576x507,...]
 
% Alternative #2
try
    jClient = jFrame.fFigureClient;  % This works up to R2011a
catch
    try
        jClient = jFrame.fHG1Client;  % This works from R2008b-R2014a
    catch
        jClient = jFrame.fHG2Client;  % This works from R2014b and up
    end
end
jWindow = jClient.getWindow;

Customized menu items Customized menu items
Integrated figure status bar

Customized menu items (top) and figure status bar (bottom)

With the retrieved jWindow reference, we can do several additional interesting things:

  • Enable/disable the entire figure in a single go (details)
  • Remove/restore the window frame (borders and title bar), otherwise known as an “undecorated window” (details)
  • Set the figure window to be “Always-On-Top”, i.e. not occluded by any other window, via the AlwaysOnTop property, or the corresponding jWindow.isAlwaysOnTop(), setAlwaysOnTop(flag) methods.
  • Make the figure window fully or partially transparent (details). Note: this fails on R2013b/Java7 and higher due to a change in the way that transparency works in Java 7 compared to earlier releases; in other words blame Oracle’s Java, not MathWorks’ Matlab….
  • Blur/restore the figure window (details). This too works only up to R2013a.
  • Detect and handle window-level focus gain/loss events (details), as well as window-level mouse events (enter/exit/hover etc. – details).
  • Customize the figure’s menu bar – dynamic behavior, tooltips, highlights, keyboard shortcuts/accelerators, font colors/styles, callbacks, icons etc. (details1, details2)
  • Control figure docking in compiled (deployed) applications (details1, details2)
  • Display an integral figure status-bar with text and GUI controls (details1, details2).
  • A few other features that I will not discuss here

As you can see, there are numerous very interesting customizations that can be done to Matlab figures which rely on the undocumented implementation. Here are a couple of usage examples that you can easily adapt (follow the links above for additional details and usage examples):

jWindow.setEnabled(false);     % disable entire figure [true/false]
jWindow.setMinimized(true);    % minimize window [true/false]
jWindow.setMaximized(true);    % maximize window [true/false]
jWindow.setAlwaysOnTop(true);  % set to be always on top [true/false]
 
% Set a Matlab callback function to a window focus-gain event
hjWindow = handle(jWindow, 'CallbackProperties');
hjWindow.FocusGainedCallback = @myCallbackFunc;

In addition to the Java-based features above, some functionalities can also be achieved via direct OS manipulations, for example using Jan Simon’s great WindowAPI utility (Windows-only), although I typically prefer using the Java approach since it is cross-platform compatible.

Using all these features is super-easy, so there is not really a question of code complexity or technical risk – the main question is whether to accept the risk that the associated code will stop working when Matlab figures will eventually become web-based.

So is it worth the risk?

This is an excellent question. I contend that the answer depends on the specific use-case. In one project you may decide that it is indeed worth-while to use these undocumented features today, whereas in another GUI you may decide that it is not.

It might make sense to use the features above in any of the following circumstances:

  • If you need any of the features in your Matlab GUI today. In this case, you really have no alternative other than to use these features, since there is no documented way to achieve the required functionality.
  • If you do not plan to upgrade your Matlab release soon, or at least after the Java-based figures are discontinued in a few years. The commercial Matlab license is perpetual, enabling users to enjoy these features for as long as they continue using this Matlab release.
  • If you are compiling your Matlab program using the Matlab Compiler or Coder toolboxes. In such cases, the executable will remain static, until such time (if ever) that you decide to recompile it using a newer Matlab release. Users of the compiled code could continue to use the compiled undocumented features well into the future, for as long as their computers keep running. In such cases, we are not concerned with release compatibility issues.
  • If you accept the risk that some recoding may be necessary in the future, or that some functionality will degrade, for the added benefit that they provide your GUIs today.
  • If you are willing to code without MathWorks’ official support and endorsement, and accept the fact that they will not fix any internal bugs that you may discover which is related to these features.
  • If you wish to present a professional-grade GUI today, and worry about potential incompatibilities only if and when they eventually arrive, sometime in the future.

Here’s another twist to consider: do not take it for granted that when web-based uifigures replace Java-based figures all the documented functionality will work as-is on the new uifigures just as they have on the old figures. In fact, I personally believe that we will need to extensively modify our GUI code to make it compatible with the new uifigures. In other words, avoiding the undocumented hacks above will probably not save us from the need to recode (or at least adapt) our GUI, it will just reduce the necessary work somewhat. We encountered a similar situation with the graphics hacks that I exposed over the years: many people avoided them in the fear that they might someday break; then when R2014b came and HG2 graphics replaced HG1, it turned out that many of these supposedly risky hacks continued working in HG2 (examples: LooseInset, YLimInclude) whereas quite a bit of standard fully-documented Matlab functionality was broken and required some recoding. I believe that the lessons from the HG2 migration were well studied and assimilated by MathWorks, but realistically speaking we should not expect a 100% full-proof transition to uifigures.

Still, accepting the risk does not mean that we should bury our head in the sand. Whenever using any undocumented feature in your code, I strongly suggest to use defensive coding practices, such as wrapping your code within try-catch blocks. This way, even if the feature is removed in R2020a (or whenever), the program will still run, albeit with somewhat diminished functionality, or in other words, graceful degradation. For example:

try
    jFrame = get(hFig, 'JavaFrame');
    jFrame.setMaximized(true);
catch
    oldUnits = get(hFig, 'Units');
    set(hFig, 'Units','norm', 'Pos',[0,0,1,1]);
    set(hFig, 'Units',oldUnits);
end

Once again, I urge you to visit http://www.mathworks.com/javaframe and tell MathWorks which of the above features are important for you. The more users tell MathWorks that they depend on a specific feature, the more would MathWorks be likely to invest R&D efforts in enabling it in the future web-based figures.

]]>
https://undocumentedmatlab.com/blog/figure-window-customizations/feed 0
Transparent labelshttps://undocumentedmatlab.com/blog/transparent-labels https://undocumentedmatlab.com/blog/transparent-labels#comments Wed, 04 May 2016 16:26:08 +0000 http://undocumentedmatlab.com/?p=6403
 
Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  2. Plot-type selection components Several built-in components enable programmatic plot-type selection in Matlab GUI - this article explains how...
  3. Uitable sorting Matlab's uitables can be sortable using simple undocumented features...
  4. Frameless (undecorated) figure windows Matlab figure windows can be made undecorated (borderless, title-less). ...
 
]]>
For the application that I will be presenting at next week’s MATLAB Expo in Munich (presentation slides), I wanted to add a text label at a specific location within the figure. The problem was, as you can clearly see from the screenshot below, that there is precious little available space for a new label. I could drive the entire content down to make space for it, but that would reduce the usable space for the actual contents, which is already at a premium:

Adding a transparent label to Matlab GUI (click for full-size image)
Adding a transparent label to Matlab GUI (click for full-size image)

A natural place for the new label, as indicated, would be on top of the empty space next to the content’s sub-tabs (Correlation and Backtesting). This empty space is taken up by Matlab’s uitabgroup control, and we can simply place our label on top of it.

Well, easier said than done…

The obvious first attempt is to set the label’s position to [0,0,1,1] (in normalized units of its parent container). The label text will appear at the expected location, since Matlab labels are always top-aligned. However, the label’s opaque background will hide anything underneath (which is basically the entire content).

If we set the label’s position to something smaller (say, [.2,.9,.6,.1]), the label will now hide a much smaller portion of the content, but will still mask part of it (depending of the exact size of the figure) and for very small figure might actually make the label too small to display. Making the label background transparent will solve this dilemma.

Unfortunately, all Matlab controls are made opaque by default. Until recently there was not much that could be done about this, since all Matlab controls used heavyweight java.awt.Panel-derived containers that cannot be made transparent (details). Fortunately, in HG2 (R2014b onward) containers are now lightweight javax.swing.JPanel-derived and we can transform them and their contained control from opaque to non-opaque (i.e., having a transparent background).

There are 3 simple steps for this:

  1. Find the text label control’s underlying Java peer (control) reference handle. This can be done using my findjobj utility, or by direct access via the containing uipanel hierarchy (if the label is inside such a uipanel), as explained here.
  2. Set the Java label reference to be non-opaque (via its setOpaque() method)
  3. Repaint the label via its repaint() method
% Create the Matlab text label uicontrol
hLabel = uicontrol('Style','text', 'Parent',hPanel, 'Units','norm', 'Pos',[0,0,1,1], 'String','Results for BERY / PKG (1 hour)');
 
% Get the underlying Java peer (control) reference
jLabel = findjobj(hLabel);
%jLabel = hPanel.JavaFrame.getGUIDEView.getComponent(0).getComponent(0).getComponent(0).getComponent(0);  % a direct alternative
 
% Set the control to be non-opaque and repaint it
jLabel.setOpaque(false);
jLabel.repaint();

This now looks nice, but not quite: Matlab displays the label text at the very top of its container, and this is not really in-line with the uitab labels. We need to add a small vertical padding at the top. One way to do this would be to set the label’s position to [0,0,1,.99] rather than [0,0,1,1]. Unfortunately, this results in varying amounts of padding depending on the container/figure height. A better alternative here would be to set the label to have a fixed-size padding amount. This can be done by attaching an empty Border to our JLabel:

% Attach a 6-pixel top padding
jBorder = javax.swing.BorderFactory.createEmptyBorder(6,0,0,0);  % top, left, bottom, right
jLabel.setBorder(jBorder);

Another limitation is that while the transparent background presents the illusion of emptiness, trying to interact with any of the contents beneath it using mouse clicks fails because the mouse clicks are trapped by the Label background, transparent though it may be. We could reduce the label’s size so that it occludes a smaller portion of the content. Alternatively, we can remove the label’s mouse listeners so that any mouse events are passed-through to the controls underneath (i.e., not consumed by the label control, or actually it’s internal Java container):

jLabelParent = jLabel.getParent;
 
% Remove the mouse listeners from the control's internal container
jListener = jLabelParent.getMouseListeners;
jLabelParent.removeMouseListener(jListener(1));
 
jListener = jLabelParent.getMouseMotionListeners;
jLabelParent.removeMouseMotionListener(jListener(1));

Using the label’s Java peer reference, we could do a lot of other neat stuff. A simple example for this is the VerticalAlignment or LineWrap properties – for some reason that eludes me, Matlab’s uicontrol only allows specifying the horizontal alignment and forces a line-wrap, despite the fact that these features are readily available in the underlying Java peer.

Finally, while it is not generally a good design practice to change fonts throughout the GUI, it sometimes makes sense to use different font colors, sizes, faces and/or attributes for parts of the label text, in various situations. For example, to emphasize certain things, as I’ve done in my title label. Such customizations can easily be done using HTML strings with most Matlab uicontrols, but unfortunately not for labels, even today in R2016a. MathWorks created custom code that removes the HTML support in Matlab labels, for reasons that elude me yet again, especially since Matlab upcoming future GUI will probably be web-based so it will also natively support HTML, so maybe there’s still hope that HTML will be supported in Matlab labels in a future release.

Anyway, the bottom line is that if we need our label to have HTML support today, we can use a standard Java JLabel and add it to the GUI using the javacomponent function. Here’s a simple usage example:

% Create the label and add it to the GUI
jLabel = javaObjectEDT(javax.swing.JLabel('<html>Results for <b>BERY / PKG (1 Hour)</b></html>'));
[hjLabel, hContainer] = javacomponent(jLabel, [10,10,10,10], hPanel);
set(hContainer, 'Units','norm', 'Pos',[0,0,1,1])
 
% Make the label (and its internal container) transparent
jLabel.getParent.getParent.setOpaque(false)  % label's internal container
jLabel.setOpaque(false)  % the label control itself
 
% Align the label
jLabel.setVerticalAlignment(jLabel.TOP);
jLabel.setHorizontalAlignment(jLabel.CENTER);
 
% Add 6-pixel top border padding and repaint the label
jLabel.setBorder(javax.swing.BorderFactory.createEmptyBorder(6,0,0,0));
jLabel.repaint;
 
% Now do the rest - mouse-listeners removal etc.
...

If you happen to attend the Matlab Expo next week in Munich Germany, please do come by and say hello!

]]>
https://undocumentedmatlab.com/blog/transparent-labels/feed 2
Smart listbox & editbox scrollbarshttps://undocumentedmatlab.com/blog/smart-listbox-editbox-scrollbars https://undocumentedmatlab.com/blog/smart-listbox-editbox-scrollbars#comments Wed, 20 Apr 2016 17:47:46 +0000 http://undocumentedmatlab.com/?p=6379
 
Related posts:
  1. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  2. Editbox data input validation Undocumented features of Matlab editbox uicontrols enable immediate user-input data validation...
  3. Customizing combobox popups Matlab combobox (dropdown) popups can be customized in a variety of ways. ...
  4. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
 
]]>
A good friend recently asked me for examples where using Java in Matlab programs provides a significant benefit that would offset the risk of using undocumented/unsupported functionality, which may possibly stop working in some future Matlab release. Today I will discuss a very easy Java-based hack that in my opinion improves the appearance of Matlab GUIs with minimal risk of a catastrophic failure in a future release.

The problem with Matlab listbox and multi-line editbox controls in the current (non web-based) GUI, is that they use a scrollbar whose behavior policy is set to VERTICAL_SCROLLBAR_ALWAYS. This causes the vertical scrollbar to appear even when the listbox does not really require it. In many cases, when the listbox is too narrow, this also causes the automatic appearance of a horizontal scrollbar. The end result is a listbox that displays 2 useless scrollbars, that possibly hide some listbox contents, and are a sore to the eyes:

Standard (left) and smart (right) listbox scrollbars

Standard (left) and smart (right) listbox scrollbars

   
default scrollbars (VERTICAL_SCROLLBAR_ALWAYS)

default scrollbars (VERTICAL_SCROLLBAR_ALWAYS)

non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)     non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)

non-default scrollbars (VERTICAL_SCROLLBAR_AS_NEEDED)

By default, Matlab implements a vertical scrollbar policy of VERTICAL_SCROLLBAR_ALWAYS for sufficiently tall uicontrols (>20-25 pixels, which practically means always) and VERTICAL_SCROLLBAR_NEVER for shorter uicontrols (this may possibly be platform-dependent).

A similar problem happens with the horizontal scrollbar: Matlab implements a horizontal scrollbar policy of HORIZONTAL_SCROLLBAR_NEVER for all editboxes and also for narrow listboxes (<35 pixels), and HORIZONTAL_SCROLLBAR_AS_NEEDED for wide listboxes.

In many cases we may wish to modify the settings, as in the example shown above. The solution to this is very easy, as I explained back in 2010.

All we need to do is to retrieve the control’s underlying Java reference (a Java JScrollPane object) and change the policy value to VERTICAL_SCROLLBAR_AS_NEEDED:

% Create a multi-line (Max>1) editbox uicontrol
hEditbox = uicontrol('style','edit', 'max',5, ...);
 
try  % graceful-degradation for future compatibility
   % Get the Java scroll-pane container reference
   jScrollPane = findjobj(hEditbox);
 
   % Modify the scroll-pane's scrollbar policies
   % (note the equivalent alternative methods used below)
   set(jScrollPane,'VerticalScrollBarPolicy',javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);   %VERTICAL_SCROLLBAR_AS_NEEDED=20
   jScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);  %HORIZONTAL_SCROLLBAR_AS_NEEDED=30
catch
   % Never mind...
end

Note that updating the uicontrol handle Position property has the side-effect of automatically reverting the scrollbar policies to their default values (HORIZONTAL_SCROLLBAR_NEVER and VERTICAL_SCROLLBAR_ALWAYS/NEVER). This also happens whenever the uicontrol is resized interactively (by resizing its container figure window, for example). It is therefore advisable to set jScrollPane’s ComponentResizedCallback property to “unrevert” the policies:

cbFunc = @(h,e) set(h,'VerticalScrollBarPolicy',20, 'HorizontalScrollBarPolicy',30);
hjScrollPane = handle(jScrollPane,'CallbackProperties');
set(hjScrollPane,'ComponentResizedCallback',cbFunc);

smart_scrollbars utility

I created a new utility called smart_scrollbars that implements all of this, which you can download from the Matlab File Exchange. The usage in Matlab code is very simple:

% Fix scrollbars for a specific listbox
hListbox = uicontrol('style','list', ...);
smart_scrollbars(hListbox)
 
% Fix scrollbars for a specific editbox
hEditbox = uicontrol('style','edit', 'max',5, ...);
smart_scrollbars(hEditbox)
 
% Fix all listbox/editbox scrollbars in a panel or figure
smart_scrollbars              % fixes all scrollbars in current figure (gcf)
smart_scrollbars(hFig)        % fixes all scrollbars in a specific figure
smart_scrollbars(hContainer)  % fixes all scrollbars in a container (panel/tab/...)

Performance considerations

Finding the underlying JScrollPane reference of Matlab listboxes/editboxes can take some time. While the latest version of findjobj significantly improved the performance of this, it can still take quite a while in complex GUIs. For this reason, it is highly advisable to limit the search to a Java container of the control that includes as few internal components as possible.

In R2014b or newer, this is easily achieved by wrapping the listbox/editbox control in a tightly-fitting invisible uipanel. The reason is that in R2014b, uipanels have finally become full-fledged Java components (which they weren’t until then), but more to the point they now contain a property with a direct reference to the underlying JPanel. By using this panel reference we limit findjobj‘s search only to the contained scrollpane, and this is much faster:

% Slower code:
hListbox = uicontrol('style','list', 'parent',hParent, 'pos',...);
smart_scrollbars(hListbox)
 
% Much faster (using a tightly-fitting transparent uipanel wrapper):
hPanel = uipanel('BorderType','none', 'parent',hParent, 'pos',...);  % same position/units/parent as above
hListbox = uicontrol('style','list', 'parent',hPanel, 'units','norm', 'pos',[0,0,1,1], ...);
smart_scrollbars(hListbox)

The smart_scrollbars utility detects cases where there is a potential for such speedups and reports it in a console warning message:

>> smart_scrollbars(hListbox)
Warning: smart_scrollbars can be much faster if the list/edit control is wrapped in a tightly-fitting uipanel (details)

If you wish, you can suppress this warning using code such as the following:

oldWarn = warning('off', 'YMA:smart_scrollbars:uipanel');
smart_scrollbars(hListbox)
warning(oldWarn);  % restore warnings

Musings on future compatibility

Going back to my friend’s question at the top of today’s post, the risk of future compatibility was highlighted in the recent release of Matlab R2016a, which introduced web-based uifigures and controls, for which the vast majority of Java hacks that I presented in this blog since 2009 (including today’s hack) will not work. While the full transition from Java-based to web-based GUIs is not expected anytime soon, this recent addition highlighted the risk inherent in using unsupported functionality.

Users can take a case-by-case decision whether any improved functionality or appearance using Java hacks is worth the extra risk: On one hand, such hacks have been quite stable and worked remarkably well for the past decade, and will probably continue working into 2020 or so (or longer if you keep using a not up-to-the-moment Matlab release, or if you create compiled applications). On the other hand, once they stop working sometime in R2020a (or whenever), major code rewrites may possibly be required, depending on the amount of dependency of your code on these hacks.

There is an obvious tradeoff between improved GUIs now and for the coming years, versus increased maintainability cost a few years in the future. Each specific GUI will have its own sweet spot on the wide spectrum between using no such hacks at all, through non-critical hacks that provide graceful functionality degradation if they ever fail, to major Java-based functionality that would require complete rework. It is certainly NOT an all-or-nothing decision. Users who take the conservative approach of using no unsupported feature at all, lose the opportunity to have professional grade Matlab GUIs today and in the upcoming years. Decisions, decisions, …

In any case, we can reduce the risk of using such hacks today by carefully wrapping all their code in try-catch blocks. This way, even if the code fails in some future Matlab release, we’d still be left with a working implementation based on fully-supported functionality. This is the reason why I’ve used such a block in the code snippet above, as well as in my smart_scrollbars utility. What this means is that you can safely use smart_scrollbars in your code today and if the worst happens and it stops working in a few years, then it will simply do nothing without causing any error. In other word, future compatibility in the form of graceful degradation. I strongly advise using such defensive coding techniques whenever you use unsupported features.

]]>
https://undocumentedmatlab.com/blog/smart-listbox-editbox-scrollbars/feed 4
Faster findjobjhttps://undocumentedmatlab.com/blog/faster-findjobj https://undocumentedmatlab.com/blog/faster-findjobj#comments Mon, 11 Apr 2016 09:18:14 +0000 http://undocumentedmatlab.com/?p=6376
 
Related posts:
  1. FindJObj – find a Matlab component’s underlying Java object The FindJObj utility can be used to access and display the internal components of Matlab controls and containers. This article explains its uses and inner mechanism....
  2. FindJObj GUI – display container hierarchy The FindJObj utility can be used to present a GUI that displays a Matlab container's internal Java components, properties and callbacks....
  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. Continuous slider callback Matlab slider uicontrols do not enable a continuous-motion callback by default. This article explains how this can be achieved using undocumented features....
 
]]>
My findjobj utility, created in 2007 and updated over the years, has received wide recognition and is employed by numerous Matlab programs, including a few dozen utilities in the Matlab File Exchange. I am quite proud of this utility and find it extremely useful for customizing Matlab controls in many ways that are impossible using standard Matlab properties. I have shown many examples of this in this blog over the past years.

I am happy to announce that I have just uploaded a new version of findjobj to the Matlab File Exchange, which significantly improves the utility’s performance for the most common use-case of a single input and a single output, namely finding the handle of the underlying Java component (peer) of a certain Matlab control:

>> hButton = uicontrol('String','click me!');
 
>> tic, jButton = findjobj(hButton); toc  % old findjobj
Elapsed time is 1.513217 seconds.
 
>> tic, jButton = findjobj(hButton); toc  % new findjobj
Elapsed time is 0.029348 seconds.

The new findjobj is backward-compatible with the old findjobj and with all prior Matlab releases. It is a drop-in replacement that will significantly improve your program’s speed.

The new version relies on several techniques:

First, as I showed last year, in HG2 (R2014 onward), Matlab uipanels have finally become full-featured Java JPanels, that can be accessed and customized in many interesting manners. More to the point here, we can now directly access the underlying JPanel component handle using the uipanel‘s hidden JavaFrame property (thanks to MathWorks for supplying this useful hook!). The new findjobj version detects this and immediately returns this handle if the user specified a uipanel input.

I still do not know of any direct way to retrieve the underlying Java component’s handle for Matlab uicontrols, this has been a major frustration of mine for quite a few years. So, we need to find the containing Java container in which we will recursively search for the control’s underlying Java handle. In the old version of finjobj, we retrieve the containing figure’s JFrame reference and from it the ContentPane handle, and use this handle as the Java container that is recursively searched. This is quite slow when the figure window is heavily-laden with multiple controls. In the new version, we try to use the specified Matlab uicontrol‘s direct parent, which is very often a uipanel. In this case, we can directly retrieve the panel’s JPanel reference as explained above. This results in a must smaller and faster search since we need to recursively search far fewer controls within the container, compared to the figure’s ContentPane.

In addition, I used a suggestion by blog reader Hannes for a faster recursive search that uses the control’s tooltip rather than its size, position and class. Finally, the search order is reversed to search backward from the last child component, since this is the component that will most often contain the requested control peer.

Feel free to download and use the new findjobj version. The code for the fast variant can be found in lines #190-205 and #3375-3415.

Enjoy!

p.s. – as I explained last week, today’s discussion, and in general anything that has to do with Java peers of GUI controls, only relates to the existing JFrame-based figure windows, not to the new web-based uifigure.

]]>
https://undocumentedmatlab.com/blog/faster-findjobj/feed 11
Adding a search box to figure toolbarhttps://undocumentedmatlab.com/blog/adding-a-search-box-to-figure-toolbar https://undocumentedmatlab.com/blog/adding-a-search-box-to-figure-toolbar#comments Wed, 30 Mar 2016 13:50:53 +0000 http://undocumentedmatlab.com/?p=6353
 
Related posts:
  1. Enable/disable entire figure window Disabling/enabling an entire figure window is impossible with pure Matlab, but is very simple using the underlying Java. This article explains how....
  2. Setting status-bar text The Matlab desktop and figure windows have a usable statusbar which can only be set using undocumented methods. This post shows how to set the status-bar text....
  3. 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....
  4. Figure toolbar customizations Matlab's toolbars can be customized using a combination of undocumented Matlab and Java hacks. This article describes how to customize the Matlab figure toolbar....
 
]]>
Last week I wrote about my upcoming presentations in Tel Aviv and Munich, where I will discuss a Matlab-based financial application that uses some advanced GUI concepts. In today’s post I will review one of these concepts that could be useful in a wide range of Matlab applications – adding an interactive search box to the toolbar of Matlab figures.

The basic idea is simple: whenever the user types in the search box, a Matlab callback function checks the data for the search term. If one or more matches are found then the searchbox’s background remains white, otherwise it is colored yellow to highlight the term. When the user presses <Enter>, the search action is triggered to highlight the term in the data, and any subsequent press of <Enter> will highlight the next match (cycling back at the top as needed). Very simple and intuitive:

Interactive search-box in Matlab figure toolbar

Interactive search-box in Matlab figure toolbar


In my specific case, the search action (highlighting the search term in the data) involved doing a lot of work: updating multiple charts and synchronizing row selection in several connected uitables. For this reason, I chose not to do this action interactively (upon each keypress in the search box) but rather only upon clicking <Enter>. In your implementation, if the search action is simpler and faster, you could do it interactively for an even more intuitive effect.

Technical components

The pieces of today’s post were already discussed separately on this website, but never shown together as I will do today:

Adding a search-box to the figure toolbar

As a first step, let’s create the search-box component and add it to our figure’s toolbar:

% First, create the search-box component on the EDT, complete with invokable Matlab callbacks:
jSearch = com.mathworks.widgets.SearchTextField('Symbol');  % 'Symbol' is my default search prompt
jSearchPanel = javaObjectEDT(jSearch.getComponent);  % this is a com.mathworks.mwswing.MJPanel object
jSearchPanel = handle(jSearchPanel, 'CallbackProperties');  % enable Matlab callbacks
 
% Now, set a fixed size for this component so that it does not resize when the figure resizes:
jSize = java.awt.Dimension(100,25);  % 100px wide, 25px tall
jSearchPanel.setMaximumSize(jSize)
jSearchPanel.setMinimumSize(jSize)
jSearchPanel.setPreferredSize(jSize)
jSearchPanel.setSize(jSize)
 
% Now, attach the Matlab callback function to search box events (key-clicks, Enter, and icon clicks):
jSearchBox = handle(javaObjectEDT(jSearchPanel.getComponent(0)), 'CallbackProperties');
set(jSearchBox, 'ActionPerformedCallback', {@searchSymbol,hFig,jSearchBox})
set(jSearchBox, 'KeyPressedCallback',      {@searchSymbol,hFig,jSearchBox})
 
jClearButton = handle(javaObjectEDT(jSearchPanel.getComponent(1)), 'CallbackProperties');
set(jClearButton, 'ActionPerformedCallback', {@searchSymbol,hFig,jSearchBox})
 
% Now, get the handle for the figure's toolbar:
hToolbar = findall(hFig,'tag','FigureToolBar');
jToolbar = get(get(hToolbar,'JavaContainer'),'ComponentPeer');  % or: hToolbar.JavaContainer.getComponentPeer
 
% Now, justify the search-box to the right of the toolbar using an invisible filler control
% (first add the filler control to the toolbar, then the search-box control):
jFiller = javax.swing.Box.createHorizontalGlue;  % this is a javax.swing.Box$Filler object
jToolbar.add(jFiller,      jToolbar.getComponentCount);
jToolbar.add(jSearchPanel, jToolbar.getComponentCount);
 
% Finally, refresh the toolbar so that the new control is displayed:
jToolbar.revalidate
jToolbar.repaint

Now that the control is displayed in the toolbar, let’s define what our Matlab callback function searchSymbol() does. Remember that this callback function is invoked whenever any of the possible events occur: keypress, <Enter>, or clicking the search-box’s icon (typically the “x” icon, to clear the search term).

We first reset the search-box appearance (foreground/background colors), then we check the search term (if non-empty). Based on the selected tab, we search the corresponding data table’s symbol column(s) for the search term. If no match is found, we highlight the search term by setting the search-box’s text to be red over yellow. Otherwise, we change the table’s selected row to the next match’s row index (i.e., the row following the table’s currently-selected row, cycling back at the top of the table if no match is found lower in the table).

Reading and updating the table’s selected row requires using my findjobj utility – for performance considerations the jTable handle should be cached (perhaps in the hTable’s UserData or ApplicationData):

% Callback function to search for a symbol
function searchSymbol(hObject, eventData, hFig, jSearchBox)
    try
        % Clear search-box formatting
        jSearchBox.setBackground(java.awt.Color.white)
        jSearchBox.setForeground(java.awt.Color.black)
        jSearchBox.setSelectedTextColor(java.awt.Color.black)
        jSearchBox.repaint
 
        % Search for the specified symbol in the data table
        symbol = char(jSearchBox.getText);
        if ~isempty(symbol)
            handles = guidata(hFig);
            hTab = handles.hTabGroup.SelectedTab;
            colOffset = 0;
            forceCol0 = false;
            switch hTab.Title
                case 'Scanning'
                    hTable = handles.tbScanResults;
                    symbols = cell(hTable.Data(:,1));
                case 'Correlation'
                    hTable = handles.tbCorrResults;
                    symbols = cell(hTable.Data(:,1:2));
                case 'Backtesting'
                    hTab = handles.hBacktestTabGroup.SelectedTab;
                    hTable = findobj(hTab, 'Type','uitable', 'Tag','results');
                    pairs = cell(hTable.Data(:,1));
                    symbols = cellfun(@(c)strsplit(c,'/'), pairs, 'uniform',false);
                    symbols = reshape([symbols{:}],2,[])';
                    forceCol0 = true;
                case 'Trading'
                    hTable = handles.tbTrading;
                    symbols = cell(hTable.Data(:,2:3));
                    colOffset = 1;
                otherwise  % ignore
                    return
            end
            if isempty(symbols)
                return
            end
            [rows,cols] = ind2sub(size(symbols), find(strcmpi(symbol,symbols)));
            if isempty(rows)
                % Not found - highlight the search term
                jSearchBox.setBackground(java.awt.Color.yellow)
                jSearchBox.setForeground(java.awt.Color.red)
                jSearchBox.setSelectedTextColor(java.awt.Color.red)
                jSearchBox.repaint
            elseif isa(eventData, 'java.awt.event.KeyEvent') && isequal(eventData.getKeyCode,10)
                % Found with <Enter> event - highlight the relevant data row
                jTable = findjobj(hTable);
                try jTable = jTable.getViewport.getView; catch, end  % in case findjobj returns the containing scrollpane rather than the jTable
                [rows, sortedIdx] = sort(rows);
                cols = cols(sortedIdx);
                currentRow = jTable.getSelectedRow + 1;
                idx = find(rows>currentRow,1);
                if isempty(idx),  idx = 1;  end
                if forceCol0
                    jTable.changeSelection(rows(idx)-1, 0, false, false)
                else
                    jTable.changeSelection(rows(idx)-1, cols(idx)-1+colOffset, false, false)
                end
                jTable.repaint
                jTable.getTableHeader.repaint
                jTable.getParent.getParent.repaint
                drawnow
            end
        end
    catch
        % never mind - ignore
    end
end

That’s all there is to it. In my specific case, changing the table’s selected row cased an immediate trigger that updated the associated charts, synchronized the other data tables and did several other background tasks.

What about the new web-based uifigure?

The discussion above refers only to traditional Matlab figures (both HG1 and HG2), not to the new web-based (AppDesigner) uifigures that were officially introduced in R2016a (I wrote about it last year).

AppDesigner uifigures are basically webpages rather than desktop windows (JFrames). They use an entirely different UI mechanism, based on HTML webpages served from a localhost webserver, using the DOJO Javascript toolkit for visualization and interaction, rather than Java Swing as in the existing JFrame figures. The existing figures still work without change, and are expected to continue working alongside the new uifigures for the foreseeable future. I’ll discuss the new uifigures in separate future posts (in the meantime you can read a bit about them in my post from last year).

I suspect that the new uifigures will replace the old figures at some point in the future, to enable a fully web-based (online) Matlab. Will this happen in 2017 or 2027 ? – your guess is as good as mine, but my personal guesstimate is around 2018-2020.

]]>
https://undocumentedmatlab.com/blog/adding-a-search-box-to-figure-toolbar/feed 1
Customizing contour plots part 2https://undocumentedmatlab.com/blog/customizing-contour-plots-part-2 https://undocumentedmatlab.com/blog/customizing-contour-plots-part-2#comments Wed, 09 Mar 2016 18:00:49 +0000 http://undocumentedmatlab.com/?p=6304
 
Related posts:
  1. Minimize/maximize figure window Matlab figure windows can easily be maximized, minimized and restored using a bit of undocumented magic powder...
  2. getundoc – get undocumented object properties getundoc is a very simple utility that displays the hidden (undocumented) properties of a specified handle object....
  3. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  4. Matlab’s HG2 mechanism HG2 is presumably the next generation of Matlab graphics. This article tries to explore its features....
 
]]>
A few months ago I discussed various undocumented manners by which we can customize Matlab contour plots. A short while ago I receive an email from a blog reader (thanks Frank!) alerting me to another interesting way by which we can customize such plots, using the contour handle’s hidden ContourZLevel property. In today’s post I will explain how we can use this property and expand the discussion with some visualization interactivity.

The ContourZLevel property

The contour handle’s ContourZLevel property is a hidden property. This means that, just like all other hidden properties, it is accessible if we just happen to know its name (which is easy using my getundoc utility). This property sets the Z level at which the contour lines are drawn.

For example, by default the meshc function sets ContourZLevel‘s value to the bottom of the 3D display (in other words, to the axes’ ZLim(1) value). This is done within the mesh.m function:

Standard Matlab meshc output (contour at bottom)

Standard Matlab meshc output (contour at bottom)

We can, however, modify the contour’s level value to any other Z location:

% create a mesh and contour plot
handles = meshc(peaks);
 
% handles is a 2-element array of handles: the surface plot and the contours
hContour = handles(2); % get the handle to the contour lines
hContour.ContourZLevel = 4.5; % set the contour's Z position (default: hAxes.ZLim(1)=-10)
 
% We can also customize other aspects of the contour lines, for example:
hContour.LineWidth = 2; % set the contour lines' width (default: 0.5)

Customized Matlab meshc output

Customized Matlab meshc output

Adding some visualization interactivity

Now let’s add some fun interactivity using a vertical slider to control the contour’s height (Z level). Matlab’s slider uicontrol is really just an ugly scrollbar, so we’ll use a Java JSlider instead:

% Add a controlling slider to the figure
jSlider = javaObjectEDT(javax.swing.JSlider);
jSlider.setOrientation(jSlider.VERTICAL);
jSlider.setPaintTicks(true);
jSlider.setMajorTickSpacing(20);
jSlider.setMinorTickSpacing(5);
jSlider.setBackground(java.awt.Color.white);
[hjSlider, hContainer] = javacomponent(jSlider, [10,10,30,120], gcf);
 
% Set the slider's action callback
hAxes = hContour.Parent;  % handle to containing axes
zmin = hAxes.ZLim(1);
zmax = hAxes.ZLim(2);
zrange = zmax - zmin;
cbFunc = @(hSlider,evtData) set(hContour,'ContourZLevel',hSlider.getValue/100*zrange+zmin);
hjSlider.StateChangedCallback = cbFunc;  % set the callback for slider action events
cbFunc(hjSlider,[]);  % evaluate the callback to synchronize the initial display

Interactive contour height

Interactive contour height

]]>
https://undocumentedmatlab.com/blog/customizing-contour-plots-part-2/feed 5
Programmatic shortcuts manipulation – part 2https://undocumentedmatlab.com/blog/programmatic-shortcuts-manipulation-part-2 https://undocumentedmatlab.com/blog/programmatic-shortcuts-manipulation-part-2#comments Wed, 30 Dec 2015 16:42:52 +0000 http://undocumentedmatlab.com/?p=6169
 
Related posts:
  1. Customizing Workspace context-menu Matlab's Workspace table context-menu can be configured with user-defined actions - this article explains how....
  2. Variables Editor scrolling The Matlab Variables Editor can be accessed to provide immediate scrolling to a specified cell location. ...
  3. Customizing help popup contents The built-in HelpPopup, available since Matlab R2007b, has a back-door that enables displaying arbitrary text, HTML and URL web-pages....
  4. setPrompt – Setting the Matlab Desktop prompt The Matlab Desktop's Command-Window prompt can easily be modified using some undocumented features...
 
]]>
Today I will expand last week’s post on customizing Matlab Desktop’s shortcuts. I will show that we can incorporate non-standard controls, and add tooltips and user callbacks in undocumented ways that are not available using the interactive Desktop GUI.

Custom shortcut controls

Custom shortcut controls


Today’s article will focus on the new toolstrip interface of Matlab release R2012b and later; adaptation of the code to R2012a and earlier is relatively easy (in fact, simpler than the toolstrip-based code below).

Displaying the Shortcuts panel

Before we begin to modify shortcuts in the Toolstrip’s shortcuts menu, we need to ensure that the Shortcuts panel is visible and active (in current focus), otherwise our customizations will be ignored or cause an error. There is probably a more direct way of doing this, but a simple way that I found was to edit the current Desktop’s layout to include a directive to display the Shortcuts tab, and then load that layout:

jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
hMainFrame = com.mathworks.mde.desk.MLDesktop.getInstance.getMainFrame;
jToolstrip = hMainFrame.getToolstrip;
isOk = jToolstrip.setCurrentTab('shortcuts');
if ~isOk  % i.e., Shortcuts tab is NOT displayed
    % Save the current Desktop layout
    jDesktop.saveLayout('Yair');  pause(0.15);
 
    % Update the layout file to display the Shortcuts tab
    filename = fullfile(prefdir, 'YairMATLABLayout.xml');
    fid = fopen(filename, 'rt');
    txt = fread(fid, '*char')';
    fclose(fid);
    txt = regexprep(txt,'(ShowShortcutsTab=)"[^"]*"','');
    txt = regexprep(txt,'(<Layout [^>]*)>','$1 ShowShortcutsTab="yes">');
    fid = fopen(filename, 'wt');
    fwrite(fid,txt);
    fclose(fid);
 
    % Load the modified layout
    jDesktop.restoreLayout('Yair');  pause(0.15);
 
    % The shortcuts tab should now be visible, so transfer focus to that tab
    jToolstrip.setCurrentTab('shortcuts');
end

Custom controls

As I explained in last week’s post, we can use scUtils.addShortcutToBottom to add a simple push-button shortcut to the relevant category panel within the Shortcuts toolstrip tab. To add custom controls, we can simply add the controls to the relevant shortcut category panel container (a com.mathworks.toolstrip.components.TSPanel object). The standard shortcuts are typically placed in the Shortcuts tab’s second TSPanel (“general”), and other categories have TSPanels of their own.

Now here’s the tricky part about TSPanels: we cannot directly add components to the sectino panel (that would be too easy…): the section panels are composed of an array of internal TSPanels, and we need to add the new controls to those internal panels. However, these panels only contain 3 empty slots. If we try to add more than 3 components, the 4th+ component(s) will simply not be displayed. In such cases, we need to create a new TSPanel to display the extra components.

Here then is some sample code to add a combo-box (drop-down) control:

% First, get the last internal TSPanel within the Shortcuts tab's "general" section panel
% Note: jToolstrip was defined in the previous section above
jShortcutsTab = jToolstrip.getModel.get('shortcuts').getComponent;
jSectionPanel = jShortcutsTab.getSectionComponent(1).getSection.getComponent;  % the TSPanel object "general"
jContainer = jSectionPanel.getComponent(jSectionPanel.getComponentCount-1);
 
% If the last internal TSPanel is full, then prepare a new internal TSPanel next to it
if jContainer.getComponentCount >= 3
    % Create a new empty TSPanel and add it to the right of the last internal TSPanel
    jContainer = com.mathworks.toolstrip.components.TSPanel;
    jContainer.setPreferredSize(java.awt.Dimension(100,72));
    jSectionPanel.add(jContainer);
    jSectionPanel.repaint();
    jSectionPanel.revalidate();
end
 
% Create the new control with a custom tooltip and callback function
optionStrings = {'Project A', 'Project B', 'Project C'};
jCombo = com.mathworks.toolstrip.components.TSComboBox(optionStrings);
jCombo = handle(javaObjectEDT(jCombo), 'callbackproperties'));
set(jCombo, 'ActionPerformedCallback', @myCallbackFunction);
jCombo.setToolTipText('Select the requested project');
 
% Now add the new control to the internal TSPanel
jContainer.add(jCombo);
jContainer.repaint();
jContainer.revalidate();

Custom shortcut controls

Custom shortcut controls

Matlab’s internal com.mathworks.toolstrip.components package contains many embeddable controls, including the following (I emphasized those that I think are most useful within the context of the Shortcuts panel): TSButton, TSCheckBox, TSComboBox, TSDropDownButton (a custom combo-box component), TSFormattedTextField, TSLabel, TSList, TSRadioButton, TSScrollPane, TSSlider, TSSpinner, TSSplitButton, TSTextArea, TSTextField, and TSToggleButton. These controls are in most cases simple wrappers of the corresponding Java Swing controls. For example, TSSpinner extends the standard Swing JSpinner control. In some cases, the controls are more complex: for example, the TSSplitButton is similar to Matlab’s uisplittool control.

Toolstrip controls

Toolstrip controls

In fact, these controls can be used even outside the toolstrip, embedded directly in our Matlab figure GUI, using the javacomponent function. For example:

dataModel = javax.swing.SpinnerNumberModel(125, 15, 225, 0.5);  % defaultValue, minValue, maxValue, stepSize
jSpinner = com.mathworks.toolstrip.components.TSSpinner(dataModel);
jSpinner = handle(javaObjectEDT(jSpinner), 'CallbackProperties');
[hjSpinner, hContainer] = javacomponent(jSpinner, [10,10,60,20], gcf);

You can find additional interesting components within the %matlabroot%/java/jar/toolstrip.jar file, which can be opened in any zip file utility or Java IDE. In fact, whatever controls that you see Matlab uses in its Desktop toolstrip (including galleries etc.) can be replicated in custom tabs, sections and panels of our own design.

Matlab Desktop’s interactive GUI only enables creating simple push-button shortcuts having string callbacks (that are eval‘ed in run-time). Using the undocumented programmatic interface that I just showed, we can include more sophisticated controls, as well as customize those controls in ways that are impossible via the programmatic GUI: add tooltips, set non-string (function-handle) callbacks, enable/disable controls, modify icons in run-time etc.

For example (intentionally showing two separate ways of setting the component properties):

% Toggle-button
jTB = handle(javaObjectEDT(com.mathworks.toolstrip.components.TSToggleButton('Toggle button')), 'CallbackProperties')
jTB.setSelected(true)
jTB.setToolTipText('toggle me!')
jTB.ActionPerformedCallback = @(h,e)doSomething();
jContainer.add(jTB);
 
% Check-box
jCB = handle(javaObjectEDT(com.mathworks.toolstrip.components.TSCheckBox('selected !')), 'CallbackProperties');
set(jCB, 'Selected', true, 'ToolTipText','Please select me!', 'ActionPerformedCallback',{@myCallbackFunction,extraData});
jContainer.add(jCB);

(resulting in the screenshot at the top of this post)

Important note: none of these customizations is saved to file. Therefore, they need to be redone programmatically for each separate Matlab session. You can easily do that by calling the relevant code in your startup.m file.

If you wish me to assist with any customization of the Desktop shortcuts, or any other Matlab aspect, then contact me for a short consultancy.

Happy New Year everybody!

]]>
https://undocumentedmatlab.com/blog/programmatic-shortcuts-manipulation-part-2/feed 4
Hyperlink text labelshttps://undocumentedmatlab.com/blog/hyperlink-text-labels https://undocumentedmatlab.com/blog/hyperlink-text-labels#comments Wed, 21 Oct 2015 14:42:48 +0000 http://undocumentedmatlab.com/?p=6033
 
Related posts:
  1. 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...
  2. GUI integrated HTML panel Simple HTML can be presented in a Java component integrated in Matlab GUI, without requiring the heavy browser control....
  3. Matlab-Java interface using a static control The switchyard function design pattern can be very useful when setting Matlab callbacks to Java GUI controls. This article explains why and how....
  4. ScreenCapture utility The ScreenCapture utility uses purely-documented Matlab for capturing a screen region as an image from within Matlab. ...
 
]]>
It is often useful to include hyperlinked text labels in GUIs. Such labels provide single-click access to important functionality, improve branding, and are non-intrusive action controls having a lower visual impact than a full-blown button. There are several ways that we can display such hyperlinks in Matlab GUIs, and today I will show one of my favorites.

The basic idea is to create a Java text label control whose label displays an HTML link. The control is modified to change the mouse cursor when it hovers over the hyperlink, and a mouse-click callback is set to open the hyperlink target in the system browser:

hyperlink text label

hyperlink text label

% Create and display the text label
url = 'UndocumentedMatlab.com';
labelStr = ['<html>More info: <a href="">' url '</a></html>'];
jLabel = javaObjectEDT('javax.swing.JLabel', labelStr);
[hjLabel,hContainer] = javacomponent(jLabel, [10,10,250,20], gcf);
 
% Modify the mouse cursor when hovering on the label
hjLabel.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.HAND_CURSOR));
 
% Set the label's tooltip
hjLabel.setToolTipText(['Visit the ' url ' website']);
 
% Set the mouse-click callback
set(hjLabel, 'MouseClickedCallback', @(h,e)web(['http://' url], '-browser'))

Note the visual illusion here: we do not directly click the hyperlink (note that its href is empty), but rather the label control. The end-result is the same.

Also note that this technique could be used to easily display clickable icons/images, including animated and transparent GIFs, by simply setting the label’s HTML string to display the relevant image. I have already shown how to do this in another post. Uses could range from clickable logo images to clickable help icons.

We could also use a flat (borderless) button. I have already posted related articles about button customizations in Matlab GUIs (here, here and here). In fact, I have already shown how we can use borderless buttons in Matlab axes to display a non-obtrusive control for controlling plot properties. The code would be very similar to the above, except that we would use a JButton rather than a JLabel, and also need to setBorder([]) and similar button-specific modifications. Buttons have a bit more functionality and customizability than simple text labels; the appearance would be the same, but the extra customizability may be handy in very special cases, although not for most use-cases.

One of the benefits of using either JLabels or JButtons is that they enable multiple callbacks (e.g., FocusGained,FocusLost) and properties (e.g., VerticalAlignment,ToolTipText) that the standard Matlab text uicontrol does not provide (not to mention their builtin ability to display HTML, which Matlab’s uicontrol text labels do not posses).

]]>
https://undocumentedmatlab.com/blog/hyperlink-text-labels/feed 5
Font selection componentshttps://undocumentedmatlab.com/blog/font-selection-components https://undocumentedmatlab.com/blog/font-selection-components#comments Wed, 07 Oct 2015 17:45:06 +0000 http://undocumentedmatlab.com/?p=6013
 
Related posts:
  1. Date selection components The JIDE package, pre-bundled in Matlab, contains several GUI controls for selecting dates - this article explains how they can be used...
  2. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  3. Tri-state checkbox Matlab checkboxes can easily be made to support tri-state functionality....
  4. Advanced JIDE Property Grids JIDE property grids can use complex cell renderer and editor components and can signal property change events asynchronously to Matlab callbacks...
 
]]>
I’ve written here in the past about how Matlab includes multiple alternatives for color selection, plot-type selection and date selection components, that can easily be integrated in Matlab figures (GUI). Today, I will show that Matlab also contains various built-in components for font selection.

These components are used by Matlab itself, integrated within the Preferences panel, print setup popup, property inspector window and so on. In most cases the components have remained unchanged for multiple releases, some existing in Matlab releases for the past decade or more. However, since internal components can change without prior notice, there is no assurance that any particular component will continue to be available in future Matlab releases.

Readers who are interested in additional details about the components mentioned in today’s post are referred to sections 3.3.3 and 5.5.2 of my book, Undocumented Secrets of MATLAB-Java Programming.

uisetfont

The only documented font-selection alternative in Matlab is uisetfont, which presents a popup dialog window that returns the selected font properties in a simple Matlab struct:

>> font = uisetfont
font = 
      FontName: 'Arial'
    FontWeight: 'normal'
     FontAngle: 'normal'
     FontUnits: 'points'
      FontSize: 10

Matlab's uisetfont dialog

Matlab's uisetfont dialog


The main drawback of uisetfont is the fact that it displays a separate non-resizable modal dialog window. We cannot embed uisetfont within our own panel, integrated in our GUI figure.

DesktopFontPicker

DesktopFontPicker is a Swing component that presents a font selection panel that can easily be inserted into any Matlab GUI container (figure, panel or tab) using the javacomponent function:

font = java.awt.Font('Tahoma',java.awt.Font.PLAIN, 11);
jFontPanel = com.mathworks.widgets.DesktopFontPicker(true, font);
[jhPanel,hContainer] = javacomponent(jFontPanel, [10,10,250,170], gcf);

DesktopFontPicker panel

DesktopFontPicker panel

Instead of the “Use desktop font” label, we can use our own label:

jFontPanel.setUseDesktopFontLabel('Use Yair''s standard font...')

Non-standard DesktopFontPicker panel

Non-standard DesktopFontPicker panel

To extract the selected font, use one of the following methods provided by DesktopFontPicker:

jFont = jFontPanel.getSelectedFont();  % returns a java.awt.Font object
flag = jFontPanel.getUseDesktopFont();  % true if top radio-button is selected; false if custom font is selected

FontPrefsPanel

The builtin com.mathworks.mlwidgets.prefs.FontPrefsPanel class is used in Matlab to display the font preferences panel in the Preferences window. We can integrate it directly in our GUI:

jFontPanel=com.mathworks.mlwidgets.prefs.FontPrefsPanel(java.awt.Dimension);
[jhPanel,hContainer] = javacomponent(jFontPanel, [1,1,500,470], gcf);

Using this class is admittedly more cumbersome than DesktopFontPicker and I would not recommend using it in practice.

FontPicker

Font selection can also be shown with drop-downs (combo-boxes), rather than with lists as in DesktopFontPicker, FontPrefsPanel, or uisetfont. Use of drop-downs significantly reduces the display “real-estate” required by the control. This is useful in forms where the font selection is only one of several user-configurable options, and where enough space must be reserved for other configuration controls. We can do this using the com.mathworks.widgets.fonts.FontPicker class.

Up until Matlab release R2010a, FontPicker‘s constructor accepted optional parameters of a pre-selected font (a java.awt.Font object), an optional boolean flag indicating whether to display sample text using the selected font, an optional layout indicator, and optional list of selectable font names. Several screenshots of different parameter combinations are shown below:

import com.mathworks.widgets.fonts.FontPicker
jFontPicker = FontPicker(font, sampleFlag, layout);
[hjFontPicker, hContainer] = javacomponent(jFontPicker, position, gcf);
FontPickerFontPickerFontPicker
font=[]java.awt.Font('Tahoma', java.awt.Font.PLAIN, 8 )[]
sampleFlag=falsefalsetrue
layout=FontPicker.GRID_LAYOUT (=1)FontPicker.LONG_LAYOUT (=2)FontPicker.LONG_LAYOUT (=2)
position=[10,200,140,40][10,200,225,20][10,200,225,80]

As before, the selected font can be retrieved using jFontPicker.getSelectedFont().

In Matlab release R2010b, FontPicker‘s interface changed, and the above code no longer works. This highlights a common pitfall in future-compatibility of internal components: even when the components remain, their interface sometimes changes. Here is the new code format, starting with R2010b:

jLayout = javaMethod('valueOf', 'com.mathworks.widgets.fonts.FontPicker$Layout', 'WIDE_WITH_SAMPLE');  % options: COMPACT, WIDE, WIDE_WITH_SAMPLE
jFont = java.awt.Font('Tahoma', java.awt.Font.PLAIN, 10);  % initial font to display (may not be [])
jFontPicker = com.mathworks.widgets.fonts.FontPicker(jFont, jLayout);
jFontPanel = jFontPicker.getComponent;
[jhPanel,hContainer] = javacomponent(jFontPanel, [10,10,250,120], gcf);

FontChooserPanel

As a final alternative for font selection, we can use the JIDE font-selection component. This component has two variants: as a drop-down/combo-box (com.jidesoft.combobox.FontComboBox) and as a standard JPanel (com.jidesoft.combobox.FontChooserPanel):

jFont = java.awt.Font('arial black',java.awt.Font.PLAIN, 8);
jFontPicker = com.jidesoft.combobox.FontComboBox(jFont);
[hjFontPicker, hContainer] = javacomponent(jFontPicker, position, gcf);
set(hjFontPicker, 'ItemStateChangedCallback', @myCallbackFunction);

JIDE's FontComboBox

JIDE's FontComboBox

Within the callback function, use getSelectedFont() to retrieve the updated font (again, a java.awt.Font object). There is also a corresponding setSelectedFont(font) to programmatically update the control with the specified Font object.

The combo-box presents a FontChooserPanel, which can be accessed (via the PopupPanel property or the corresponding getPopupPanel() method) after it has been initially created. Thereafter, the panel can be customized. For example, the preview text can be modified via the panel’s PreviewText property (or the setPreviewText(text) method).

The same FontChooserPanel can also be displayed as a stand-alone font-selection panel, unrelated to any combo-box. Different GUI requirements might prefer using a compact combo-box approach, or the larger stand-alone panel.

This combo-box/panel duality is a common feature of JIDE controls. I have previously shown it in my color selection components and date selection components articles.

popupmenu uicontrol

As another example of using a font-selection drop-down (combo-box), we can use a standard Matlab popupmenu uicontrol, setting its String property value to a cell-array containing the supported system’s fonts (as returned by the listfonts function). A nice twist here is to use the undocumented trick that all Matlab uicontrols inherently support HTML to list each of the fonts in their respective font style:

fontStr = @(font) ['<html><font face="' font '">' font '</font></html>'];
htmlStr = cellfun(fontStr, listfonts, 'uniform',false);
uicontrol('style','popupmenu', 'string',htmlStr, 'pos',[20,350,100,20]);

HTML-rendered fonts popup menu

HTML-rendered fonts popup menu

Note that we could also use a listbox uicontrol using the same code.

Austria visit, 11-15 October, 2015

I will be travelling to clients in Austria next week, between October 11-15. If you are in Austria and wish to meet me to discuss how I could bring value to your work, then please email me (altmany at gmail).

]]>
https://undocumentedmatlab.com/blog/font-selection-components/feed 3
Solving an mput (FTP) hang problemhttps://undocumentedmatlab.com/blog/solving-an-mput-ftp-hang-problem https://undocumentedmatlab.com/blog/solving-an-mput-ftp-hang-problem#comments Wed, 19 Aug 2015 20:10:17 +0000 http://undocumentedmatlab.com/?p=5974
 
Related posts:
  1. More undocumented timing features There are several undocumented ways in Matlab to get CPU and clock data...
  2. Uitable customization report Matlab's uitable can be customized in many different ways. A detailed report explains how. ...
  3. Waiting for asynchronous events The Matlab waitfor function can be used to wait for asynchronous Java/ActiveX events, as well as with timeouts. ...
  4. uisplittool & uitogglesplittool callbacks Matlab's undocumented uisplittool and uitogglesplittool are powerful toolbar controls - this article explains how to customize their behavior...
 
]]>
Matlab includes a variety of builtin utility functions that enable easy access to FTP. These functions are basically methods of an FTP object using Matlab’s old class system (for example, the mput function is implemented as mput.m in the %matlabroot%\toolbox\matlab\iofun\@ftp\ folder). These are pretty old files that haven’t changed much in years.

FTPI recently needed to upload files from Matlab onto an FTP server, and discovered that calling mput simply hang Matlab to the point that I needed to kill and restart the Matlab process. The problem was not in the FTP server, since it could be accessed normally using FTP clients such as FileZilla and WinSCP. So it had to be something internal to Matlab. My initial workaround was to create an automation script (using WinSCP in my case) for the file upload. But this kludge is both non-robust as well as slow. A fix to the Matlab problem would be much better.

Some online research yielded others who have complained about similar issues over the years, but I saw no concrete answer. I saw many references online to problems that relate to the combination of passive FTP with Windows 7 / firewall / Java 7, that suggested several fixes (example 1, example 2, example 3, example 4). However, none of them solved the problem: calling mput (or dir etc.) continued to freeze Matlab, forcing either a hard process kill or waiting several minutes for the timeout.

Today, Malcolm Lidierth, author of the Waterloo graphics package, told me that he also saw a similar situation on Mac. Fortunately, Malcolm discovered a much better solution to the problem than my external scripts workaround. It seems that simply setting the Java object underlying Matlab’s FTP object to use passive mode fixes the problem (possibly in addition to the other fixes mentioned above).

This can be done in two manners:

The easiest is to add the following highlighted line in mput.m, on or about line 69 (the exact line may change based on your Matlab release):

...
% Upload this file.
fis = java.io.FileInputStream(fileObject);
h.jobject.enterLocalPassiveMode();  % Use passive modestatus = h.jobject.storeFile(name,fis);
fis.close;
...

This works but has several limitations:

  1. it does not solve the problems of other passive FTP commands such as dir, although they can be solved in a similar manner
  2. it creates a counter-problem when connecting to non-passive FTP servers – users might wish to make this a parameter of the ftp constructor function
  3. and of course it requires changing Matlab’s installation files which is problematic in many aspects, as well as non-portable if you ever use your program on another machine or Matlab release.

Here’s a much simpler, portable and flexible solution: simply set the underlying Java object’s passive mode after connecting to the server (using the ftp constructor function) but before using mput or dir or any other command that uses passive FTP mode:

f = ftp('myftpserver.com',username,password);
cd(f);  sf=struct(f);  sf.jobject.enterLocalPassiveMode();mput(f,filename);
dir(f);
close(f);

Note that we need to connect first, then get the underlying Java reference using the struct hack (since direct access to f.jobject is prevented), then we enter local passive mode, and only then we call mput to upload the file. If we omit the highlighted line in the script above, then mput (and dir etc.) will hang.

This way, we can programmatically control when to use passive mode, and no changes to the Matlab install files is required: our Matlab script should now work on all platforms and Matlab releases.

Note the seemingly unnecessary call to cd(f) – this is done to ensure a valid connection before setting the passive mode. We should ensure to do this before each call to mput/dir etc., since otherwise, if the connection drops for any reason (e.g., timeout or some other disconnection), then the mput/dir command would reconnect without passive mode (causing a hang). By calling cd(f) we ensure that the connection is done and passive mode is re-entered before mput/dir are called.

As an interesting related note, ftp accepts an undocumented set of optional input parameters following its first 3 documented inputs (hostname, username and password). We can pass one or more of the following parameters in P-V (param name, param value) pairs format: System, LenientFutureDates, DefaultDateFormatStr, RecentDateFormatStr, ServerLanguageCode, ServerTimeZoneId, ShortMonthNames. All of these parameters expect string (char) values, except LenientFutureDates that expects a logical value (true/false). All the parameters have a default value of empty. An explanation of these parameters can be found in Apache’s documentation of the FTPClientConfig class (Matlab’s ftp uses a plain Apache FTPClient object, where you can also find an explanation of the enterLocalPassiveMode method that was used above).

Italy visit, Aug 26 – Sep 1, 2015

I will be traveling to north Italy between Aug 26 – Sep 1, 2015. If you happen to be in the area at that time, I will be happy to meet you to discuss how I could bring value to your work. Please email me (altmany at gmail) if you are interested.

Due to my travel, this blog will take a short summer vacation, and will return in early September. Stay tuned!

]]>
https://undocumentedmatlab.com/blog/solving-an-mput-ftp-hang-problem/feed 1
Accessing internal Java class membershttps://undocumentedmatlab.com/blog/accessing-internal-java-class-members https://undocumentedmatlab.com/blog/accessing-internal-java-class-members#comments Wed, 12 Aug 2015 18:00:03 +0000 http://undocumentedmatlab.com/?p=5960
 
Related posts:
  1. Borderless button used for plot properties A borderless button can be used to add unobtrusive functionality to plot axes...
  2. Javacomponent background color This article explains how to align Java component background color with a Matlab color....
  3. Types of undocumented Matlab aspects This article lists the different types of undocumented/unsupported/hidden aspects in Matlab...
  4. Java class access pitfalls There are several potential pitfalls when accessing Matlab classes from Matlab. ...
 
]]>
Following my previous post on using the Java classloader, I thought I’d follow up today with a somewhat-related peculiarity.

Inner classes

Whenever we have an enum or inner-class defined within a Java class, it can be accessed in Java using standard dot-notation. For example, com.mathworks.hg.peer.ComboboxPeer.MLComboBox refers to an inner class MLComboBox which is defined within the ComboboxPeer class. When compiled, the class would be stored in a file called ComboboxPeer$InnerClassName.class. In other words, the JVM uses the $ separator char to indicate that MLComboBox is internal to ComboboxPeer.

Within the Java code, we would simply use the regular dot-notation (ClassName.MLComboBox) – the $ separator is part of the internal JVM implementation that the Java programmer should not be concerned about.

Unfortunately, we cannot ignore this in Matlab: Matlab’s interpreter, which acts as a bridge to the JVM, is not smart enough to know that in certain cases the dot-notation should be converted into a $. Therefore, trying to access ClassName.MLComboBox directly in Matlab fails:

>> jObject = com.mathworks.hg.peer.ComboboxPeer.MLComboBox([])
Undefined function or variable 'MLComboBox'. 
 
>> jObject = com.mathworks.hg.peer.ComboboxPeer$MLComboBox([])
 jObject = com.mathworks.hg.peer.ComboboxPeer$MLComboBox([])
                                             ↑
Error: The input character is not valid in MATLAB statements or expressions.

The solution in such cases is to use Matlab’s javaObject (or javaObjectEDT) function with the JVM’s internal $-representation:

>> jObject = javaObject('com.mathworks.hg.peer.ComboboxPeer$MLComboBox',[])
jObject =
com.mathworks.hg.peer.ComboboxPeer$MLComboBox[,0,0,0x0,invalid,layout=com.mathworks.hg.peer.types.HGWindowsComboBoxUI$1,alignmentX=...]

To access public methods (functions) of the inner class, we could similarly use the javaMethod (or javaMethodEDT) function.

Enumerations

Java Enums act in a very similar manner to inner classes: we access them using standard dot-notation in Java source code, and the JVM translates the enumerations into $-notation internally. Unfortunately, we cannot access Java enums in Matlab using javaObject as shown above; we need to use a more circuitous way.

For example, JVM 1.6 (in Matlab 7.5 R2007b onward) provides access to the new TrayIcon object (I explained its usage back in 2009). One of TrayIcon‘s functionalities is displaying a message next to the tray icon, using java.awt.TrayIcon.displayMessage(). This method expects an object of type java.awt.TrayIcon.MessageType, which is an enumeration within the TrayIcon class. However, Matlab’s dot-notation does not recognize what should have been the following correct notation, so we need to resort to Java reflection:

>> trayIcon.displayMessage('title','info msg',TrayIcon.MessageType.INFO);
??? No appropriate method or public field MessageType for class java.awt.TrayIcon

>> trayIconClasses = trayIcon.getClass.getClasses;
>> trayIconClasses(1)
ans =
class java.awt.TrayIcon$MessageType	<= hurray!!!
>> MessageTypes = trayIconClasses(1).getEnumConstants
MessageTypes =
java.awt.TrayIcon$MessageType[]:
    [java.awt.TrayIcon$MessageType]	<= 1: ERROR
    [java.awt.TrayIcon$MessageType]	<= 2: WARNING
    [java.awt.TrayIcon$MessageType]	<= 3: INFO
    [java.awt.TrayIcon$MessageType]	<= 4: NONE
>> trayIcon.displayMessage('title','info msg',MessageTypes(3));

systray INFO message

and another example, now with a WARNING icon:

systray WARNING message

We can also access Java enums using their built-in values() and valueOf() methods:

>> msgType=javaMethod('valueOf','java.awt.TrayIcon$MessageType','INFO')
msgType =
INFO		<= a java.awt.TrayIcon$MessageType object
 
>> enums = cell(javaMethod('values','java.awt.TrayIcon$MessageType'));
>> msgType = enums{3};   % alternative way to find the INFO enum value
>> cellfun(@(c)c.toString.char, enums, 'uniform',false)'
ans = 
    'ERROR'    'WARNING'    'INFO'    'NONE'

Inner classes can also be accessed using the Java classloader, although this is more cumbersome.

Static fields

Using public Java static fields in Matlab is easy – in most cases we could use standard dot-notation. For example:

>> jColor = java.awt.Color.orange
jColor =
java.awt.Color[r=255,g=200,b=0]

We could use the struct function to get a Matlab struct with all the public static fields of a Java class object:

>> struct(java.awt.Color.red)
ans = 
          white: [1x1 java.awt.Color]
          WHITE: [1x1 java.awt.Color]
      lightGray: [1x1 java.awt.Color]
     LIGHT_GRAY: [1x1 java.awt.Color]
           gray: [1x1 java.awt.Color]
           GRAY: [1x1 java.awt.Color]
       darkGray: [1x1 java.awt.Color]
      DARK_GRAY: [1x1 java.awt.Color]
          black: [1x1 java.awt.Color]
          BLACK: [1x1 java.awt.Color]
            red: [1x1 java.awt.Color]
            RED: [1x1 java.awt.Color]
           pink: [1x1 java.awt.Color]
           PINK: [1x1 java.awt.Color]
         orange: [1x1 java.awt.Color]
          ...

But in some cases, we may have static fields of an uninstantiable inner class, and in such cases dot-notation will fail in Matlab. Moreover, since the inner class is not instantiable, we cannot use javaObject as above.

For example, trying to access internal static fields in java.nio.channels.FileChannel.MapMode, in order to use them to create a memory-mapped file using FileChannel.map(…), is problematic. In this specific case, we have the built-in memmapfile Matlab function as a much simpler alternative, but for the record, we could do this:

>> channel = java.io.FileInputStream('234.jpg').getChannel
channel =
sun.nio.ch.FileChannelImpl@1c7a5d3    <= which extends FileChannel
 
>> innerClasses = channel.getClass.getSuperclass.getDeclaredClasses;
>> innerClasses(1)
ans =
class java.nio.channels.FileChannel$MapMode
 
>> read_only_const = innerClasses(1).getField('READ_ONLY').get(1)
read_only_const = 
READ_ONLY    <= a java.nio.channels.FileChannel$MapMode object
 
>> fields = innerClasses(1).getFields;
>> read_only_const = fields(1).get(1);    % an alternative
 
>> buffer = channel.map(read_only_const, 0, channel.size);

Additional information can be found in my book, Undocumented Secrets of MATLAB-Java Programming (CRC Press, 2011). If you already have this book, please be kind enough to post a review on Amazon, to spread the word.

]]>
https://undocumentedmatlab.com/blog/accessing-internal-java-class-members/feed 4