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)
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.
The relevant Java Swing control for password fields is
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);
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.
The relevant Java Swing control for spinners is
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.
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);
For more information, refer to my detailed post on using spinners in Matlab GUI.
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.