One of my consulting clients asked me last week if I knew an easy way to integrate a range (dual-knob) slider control in Matlab GUI. Today’s post is an expansion of the answer I provided him, which I though might interest other Matlab users.
- Matlab vs. Java sliders
- Using JSlider
- Range (dual-knob) sliders
- AppDesigner – Matlab’s new GUI
- Conclusions and some personal musings
Matlab vs. Java sliders
As funny as it may sound, Matlab’s so-called “slider” control (
uicontrol('Style','slider')) is actually implemented as a scroll-bar, rather than the more natural JSlider. I believe that this is due to a design decision that occurred sometime in the 1990’s (sliders were not as prevalent then as they are nowadays). This was never corrected, probably for backward-compatibility reasons. So to this day, Matlab’s so-called “slider” is actually a scroll-bar, and we do not [yet] have a real slider control in standard Matlab, apparently since the ‘slider’ uicontrol style is already in use. Spoiler alert: this will change soon — keep reading.
It gets worse: for some reason Matlab’s implementation of the so-called “slider” uses a Windows95 look-and-feel that makes the control look antique in today’s GUI standards. Using Java Swing’s standard JScrollBar control would at least have made it appear more consistent with the other Matlab controls, which are all based more closely on Java Swing:
% Standard Matlab "slider" uicontrol('style','slider', 'position',[10,10,200,20]); % Standard Java JScrollBar jScrollbar = javax.swing.JScrollBar; jScrollbar.setOrientation(jScrollbar.HORIZONTAL); javacomponent(jScrollbar,[10,40,200,20]); % Standard Java JSlider (20px high if no ticks/labels, otherwise use 45px) jSlider = javax.swing.JSlider; javacomponent(jSlider,[10,70,200,45]);
I advise users of the current Matlab GUI to use
JSlider, rather than Matlab’s standard “slider” uicontrol. The rest of today’s post will discuss the
As shown above, we can use the javacomponent function to display any Java component in a Matlab container (such as uipanel or figure). We can easily modify the slider’s appearance using its internal properties:
set(jSlider, 'Value',84, 'MajorTickSpacing',20, 'PaintLabels',true); % with labels, no ticks
set(jSlider, 'Value',22, 'PaintLabels',false, 'PaintTicks',true); % with ticks, no labels
jSlider.setPaintLabels(true); % or: jSlider.setPaintLabels(1); % with both ticks and labels
[jhSlider, hContainer] = javacomponent(jSlider,[10,10,100,40]); set(jSlider, 'Value',72, 'Orientation',jSlider.VERTICAL, 'MinorTickSpacing',5); set(hContainer,'position',[10,10,40,100]); %note container size change
We can query the current slider value via its Value property:
>> value = get(jSlider,'Value'); % or: value = jSlider.getValue; value = 29
We can easily attach Matlab callback functions to slider value-change events:
>> hjSlider = handle(jSlider, 'CallbackProperties') hjSlider = javahandle_withcallbacks.javax.swing.JSlider >> hjSlider.StateChangedCallback = @(hjSlider,eventData) disp(get(hjSlider,'Value')); >> set(hjSlider, 'StateChangedCallback', @myCallback); %alternative
As you can see, standard Java controls (such as
JSlider here) are very simple to customize and use in Matlab GUI. I have shown more complex customizations elsewhere in this blog, as well as in my Matlab-Java programming book.
JSlider (and Java sliders in general) only supports integer values, so if you need floating-point values you’d either need to find some other Java Swing component somewhere that supports what you need, or do the scaling yourself with some text label. I recently created a Matlab class wrapper for a client that does exactly that: the underlying component was a Java slider and the labels were updated to display floating-point values, dynamically updated based on the Matlab class object’s properties. It only took a short morning to create a fully-functional generic slider class that works quite well.
Range (dual-knob) sliders
This brings me to my client’s query that I mentioned at the beginning of this post:
JSlider only contains a single knob. Is it possible to integrate a range (dual-knob) slider?
My initial response was to simply google for “Java range slider“. This returns numerous different controls, both open-source and commercial, that we can download and integrate in Matlab. All it takes is to download the *.class, *.zip or *.jar file that contains the component, add it to Matlab Java classpath using the javaaddpath function, and then use the javacomponent to display it, just as we did with
This is simple enough, but then I thought of an even simpler solution, namely to use JIDE’s library of commercial-grade controls that is pre-bundled in Matlab. Surely enough, a quick search in JIDE’s enormous catalog yielded its
RangeSlider component, which extends
JSlider with a dual knob.
RangeSlider‘s appearance has changed somewhat across Matlab releases (or actually, JIDE releases, as they are integrated within the corresponding Matlab releases), but its basic functionality remained unchanged:
jRangeSlider = com.jidesoft.swing.RangeSlider(0,100,20,70); % min,max,low,high jRangeSlider = javacomponent(jRangeSlider, [0,0,200,80], gcf); set(jRangeSlider, 'MajorTickSpacing',25, 'MinorTickSpacing',5, 'PaintTicks',true, 'PaintLabels',true, ... 'Background',java.awt.Color.white, 'StateChangedCallback',@myCallbackFunc);
We can move the two knobs relative to each other. We can also move the entire range (i.e., both knobs at once), by either dragging the square on top of the right knob (R2010b), or by dragging the space between the two knobs (R2014b).
The benefit of JIDE controls is that they are pre-bundled in every Matlab installation and deployed MCR. There is no need to download anything, nor to use javaaddpath. All the richness of JIDE’s commercial-grade libraries (at least those libraries used in Matlab, which is plenty) is automatically available to us within Matlab, just as easily as the standard Java Swing controls. MathWorks has already paid a small fortune to integrate JIDE’s libraries in Matlab, and we can use it free of charge within Matlab GUIs. This is a great (and sadly undocumented) advantage of Matlab GUI. Matlab GUI programmers who wish to enrich their GUI are strongly encourages to take the time to review the long list of controls provide by JIDE in Matlab. I’ve posted quite a few articles on using JIDE components in Matlab – feel free to take a look and see the richness that JIDE can bring to your GUI. Additional material can be found in my Matlab-Java programming book.
In the specific case of
RangeSlider, this control is part of the JIDE Common Layer that JideSoft open-sourced a few years ago. This means that we can download the latest version of this library and use it in Matlab, in case it has some new component that is still not available in our version of Matlab. For example, Matlab R2014b includes JIDE version 3.4.1, released by JideSoft on May 2012 – the latest version (3.6.9, released last week) includes numerous fixes and improvements that were integrated in the past 3 years:
>> com.jidesoft.utils.Lm.getProductVersion ans = 3.4.1
Note that JIDE’s online documentation (PDF, javadoc, webpage) always refers to the latest version. To use the latest Common-layer library in Matlab, simply download it and replace Matlab’s pre-bundled <matlabroot>/java/jarext/jide/jide-common.jar file. Be careful with changing Matlab’s installation files (such as this one), as there is always a risk that some Matlab functionality might break. So always keep a copy of the original file, in case you need to revert your changes. Alternatively, place the jide-common.jar file in some other user folder and use it in Matlab on an as-needed basis using javaaddpath and javarmpath.
Using the latest commercial (non-open-sourced) JIDE libraries, such as jide-grids.jar, jide-components.jar or jide-charts.jar, is only possible if you purchase them from JideSoft. But as noted, we can freely use the older bundled libraries in our Matlab GUIs without paying JideSoft anything.
Disclaimer: I am an engineer, not a lawyer. What I said above is my personal opinion; it is not legal advice. If you are unsure about licensing of JIDE components in your programs, contact MathWorks or JideSoft.
AppDesigner – Matlab’s new GUI
Last autumn, with little fanfare, MathWorks released the App Designer toolbox, which can be freely downloaded from the File Exchange. This is not just another File Exchange utility. It is in fact an official MathWorks Technical Preview that is both functional by itself, and also provides very interesting insight of Matlab’s upcoming new GUI. MathWorks have not announced exactly when this new AppDesigner will replace the aging GUIDE in Matlab. But the fact that AppDesigner is an actual working product in the public domain since late 2014, and that MathWorks has officially endorsed it as a “Technical Preview”, mean that this day is close.
In the new AppDesigner, sliders finally appear modern, complete with all sorts of customizable properties:
Java controls still provide more customizability than Matlab, even in the new AppDesigner, but the functionality gap is now significantly reduced. This provides the flexibility of modern easy-to-create/maintain GUIs for users who do not need to preserve backward-compatibility with existing GUIs or extra customizabilty enabled by Java, while preserving the functionality for those who do.
Java components and even standard Matlab uicontrols cannot be added to an AppDesigner window because it is not a standard Java
JFramewindow. The new App window has its own set of controls, separate from uicontrols (topic for a separate blog post someday). However, we can always keep using javacomponent and uicontrol in plain-ol’ figures, as before, side-by-side with the new AppDesigned windows. The new App window can be created using the new appwindow function, whereas the existing figure function creates a standard figure window (basically a Java
JFrame) that accepts javacomponent and uicontrol. Maybe one day I’ll find out if there’s a way to combine these two seemingly disparate sets of GUIs. In the meantime I’m content that there’s a new way to create Matlab GUIs that has not previously existed.
AppDesigner is a very nice addition for Matlab GUI builders, and it will get even better with time. Having looked at some of the internals, I’m drooling over the potential improvements. MathWorks has invested quite a bit in this new product, so I’m confident that many of these improvements will find their way into AppDesigner in the upcoming releases. I just hope it will remain a free utility and will not turn into an addon toolbox when officially released (I have not seen any mention about this either way, so it’s still an open question; I’ll clarify this point here when I learn something). For the time being, AppDesigner is free to use.
MathWorks is actively looking for ways to improve AppDesigner, so if you find any functionality that is missing or buggy, please provide feedback:
Conclusions and some personal musings
Matlab itself has kept its Desktop GUI relatively modern, and integrates advanced JIDE GUI controls internally. But until AppDesigner came about, Matlab application builders were not provided with similarly modern documented GUI components and design tools, in keeping with the times.
It is indeed possible, as I’ve repeatedly claimed in this blog, to create professional-looking GUIs in Matlab. However, this currently requires using undocumented features and Java controls.
In Matlab’s upcoming AppDesigner, making professional-looking Matlab GUIs will be easier, with sleek new controls, user-friendly visual layout, and easy-to-maintain class-based code. I still find the tech-preview to be lacking in some respects, and not integrated with the existing GUI functionality. Still, the fact that MathWorks has gone out of its way to provide a Technical Preview of its upcoming new GUI, despite its normal reluctance to provide a technical development roadmap, shows a commitment to improving Matlab’s user-facing front-end. This makes me optimistic that most shortcomings will be solved by the time AppDesigner is officially released, hopefully soon.
Until this happens, and possibly even later, we can significantly improve Matlab’s standard GUI using Java in standard figure windows. Interested readers can find out more information about integrating Java controls in Matlab GUI in my book “Undocumented Secrets of MATLAB-Java Programming” (CRC Press, 2011, ISBN 978-1439869031). If you already have this book, please be kind enough to post your feedback on it on Amazon (link), for the benefit of others.
Swing and even the SwingX extensions from Oracle never included a dial for some reason.
For open-source JSliders, some readers might like the GJDial that was used in some of the Project Waterloo internal GUIs.
It’s a simple, self-contained, subclass of JSlider that presents visually as a dial instead of a slider and supports both single and multi-turn operation. That can be handy when you need fine control but want to pack the GUI into a small screen area.
Hopefully, TMW will include dials in the new AppDesigner.