Sliders in Matlab GUI

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

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:

Matlab "slider" uicontrol (bottom), Java JScrollBar (above), and JSlider (top 2)

Matlab "slider" uicontrol (bottom),
Java JScrollBar (above),
and JSlider (top 2)

% 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 JScrollBar or JSlider, rather than Matlab’s standard “slider” uicontrol. The rest of today’s post will discuss the JSlider variant.

Using JSlider

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

JSlider customization

set(jSlider, 'Value',22, 'PaintLabels',false, 'PaintTicks',true);  % with ticks, no labels

JSlider customization

jSlider.setPaintLabels(true);  % or: jSlider.setPaintLabels(1);  % with both ticks and labels

JSlider customization

[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

JSlider customization

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.

Note that 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 JSlider above.

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);

RangeSlider in R2010b   RangeSlider in R2014b

RangeSlider in R2010b (left), R2014b (right)

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:

Sliders in Matlab's new AppDesigner

Sliders in Matlab's new AppDesigner

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 JFrame window. 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:

Feedback for Matlab's new AppDesigner

Feedback for Matlab's new AppDesigner

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.

Categories: GUI, Java, Medium risk of breaking in future versions, Undocumented feature

Tags: , , , , ,

Bookmark and SharePrint Print

57 Responses to Sliders in Matlab GUI

  1. Malcolm Lidierth says:

    Yair
    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.

    • Yair Altman says:

      Indeed, dials and knobs galore (details):

    • Malcolm Lidierth says:

      Yair
      These look great. Do they supply a “multi-turn” dial: value from first turn from zero = 0:10, second = 10:20 etc?. It’s not obvious from the screenshots that they do.
      That is what I needed to scroll through a lengthy strip-chart without jumping several seconds at a time because of the number of pixels used by a JSlider. Do others among your readers have a need for that behaviour?
      If so, shout now: TMW read this blog and it should not be too difficult to implement.
      ML

    • @Malcolm – is this what you mean?

      If so, then I haven’t seen this functionality in AppDesigner…
      I believe MathWorks would be working on stability and compatibility for their first release, rather than adding new features such as this. But we can definitely ask for them to be added to the dev queue. The best way to do this is to use the feedback form integrated in AppDesigner, since this will enter some backoffice system that is monitored and tracked. Relying on them to monitor this blog is risky, since it’s not tracked or monitored in the same way.

    • Malcolm Lidierth says:

      Yair
      Exactly that. I deleted a reference to a “10-turn potentiometer” in the OP because I wasn’t sure how many readers would be long enough in the tooth to recognise one.
      M

  2. David says:

    You can spot many of the new dials and gauges from the forthcoming app designer in the new Simulink HMI widgets section of R2015a. I believe all of the new controls are going to be web enabled.

  3. Christina says:

    How do you change the tick labels? I’m trying to use the JSlider for a time range and so I want the labels to be datestr(x,13) output of the times. Can’t seem to figure it out myself.

    Thanks!

  4. Vidya says:

    Hello Yair,

    I started using the Java sliders in Matlab yesterday and they work great (thanks for the texbook as well as the tutorials)! I do not have much experience with Java though, and can’t seem to get mouse callbacks to work with it. Your example above works great, but breaks when I try to implement it using guidata within a function. Basically I’m trying to get the value of the slider when the slider moves, but want this to be saved as a handle. Here is my code so far:

    function testMouse
       hFig = figure('Position',[450 100 700 850]);
       jSlider = javax.swing.JSlider;
       [jSlider,~] = javacomponent(jSlider,[100,20,500,50]);
       jbh = handle(jSlider,'CallbackProperties');
       set (jbh, 'MouseDraggedCallbackData', @myCallbackFcn)   guidata(hFig, handles);
     
    function myCallbackFcn
       get (jbh, 'MouseDraggedCallbackData')
       guidata(hFig, handles);

    Here is the error I get when I run the code in MATLAB:

    Error using javahandle_withcallbacks.javax.swing.JSlider/set Changing the 'MouseDraggedCallbackData' property of javahandle_withcallbacks.javax.swing.JSlider is not allowed.
    Error in testMouse (line 6) set (jbh, 'MouseDraggedCallbackData', @myCallbackFcn)
    

    I’d appreciate any suggestions. Thanks!

    • Yair Altman says:

      @Vidya – the *CallbackData properties are automatically populated by Matlab whenever the corresponding *Callback is called, and then this callback-data is passed on to the callback function as an input parameter. Therefore, it is not surprising that you cannot programmatically modify the contents of any *CallbackData property. You can only change *Callback, and in this specific case MouseDraggedCallback.

      Still, I do not see why you would want to set a MouseDraggedCallback: do you plan for your GUI users to interactively drag the entire slider control within your GUI??? If you are only trying to trap changes to the slider’s knob, then you should set StateChangedCallback instead, as I explained in the main article.

    • Vidya says:

      @Yair

      “do you plan for your GUI users to interactively drag the entire slider control within your GUI???”

      Sort of. I would like to save the (final) value of the slider position. That is, export it, for example to a text file. I was hoping to do this by updating the handle structure using guidata. This is proving to be difficult.

      “If you are only trying to trap changes to the slider’s knob, then you should set StateChangedCallback instead, as I explained in the main article.”

      This works, but only shows the current value of the slider in the command window. How can I save this information onto the workspace, or export the final value of the slider? Thanks.

    • @Vidya – you really need to learn how to use Matlab callbacks. Instead of calling disp to output the latest slider value to the console, you can set the callback to any Matlab function that does whatever you wish, such as storing the data in your handles struct or saving it somewhere or whatever. This is standard basic Matlab programming, it has nothing at all to do with Java. There’s plenty of documentation on using Matlab callbacks that you could (and should) use.

    • Vidya says:

      @Yair – Yes, you are correct. Just figured out how.

  5. Yaroslav says:

    Hi Yair,

    Regarding the new HG2 system: it seems that TMW have sealed all the graphic classes and widgets from sub-classing. They have also concealed (by pcode) the implementation, so that the old HG1 approach of copy-the-original-code-and-redesign-for-your-needs doesn’t work anymore. Since sub-classing may be instrumental in many cases providing simple and powerful solutions, I have several questions:
    1. Are you familiar with any ways to overcome this issue? If so, can you dedicate it a post?
    2. Do you know, whether TMW are planning to open their graphics classes sometime in the future?
    3. If both answers are negative, can you post something like “A layman’s guide to creating own Matlab graphics classes” ?
    With thanks and appreciation —

  6. Christina says:

    In Matlab2007 I’m trying to use the JSlider but I keep getting a “Warning: Transform Fcn…” error every time the GUI repaints. I cannot find a way to get rid of this warning. I’ve tried finding a way to define the Transform Fcn (whatever that is) so no avail. I’ve also tried suppressing the warning by doing:

    [a,msgID] = lastwarn();
    warning('off', msgID);

    and it doesn’t like the lastwarn() command. I’m stuck.

    • @Christina – sounds like something’s funky with your Java. Java warnings cannot be suppressed. You have a very old Matlab release so try upgrading to a newer release.

  7. Panos says:

    Hi Yair,

    any chance you know if the values passed by these new knobs can change on the fly according to the mouse, without having to land on a specific step on the knob first?
    Thanks!

  8. Ravi says:

    Dear Yair,

    really interesing way of integrating sliders. Yet, I dont get how I insert the Java double knob slider exactly. I tried putting it into a panel of my guide created GUI (replacing gcf with handles.myslider) but I cant get position right, as well as resizing does not work… Any ideas how to fix that?

    Thanks a bunch.
    Ravi

  9. Sog says:

    Dear Yair,

    I have a problem that I appreciate if you could help me to resolve it.
    I am using “JSlider” and I was wondering if there is a way to partially disable the slider to take some values? In my case, the default range for the slider is set to be 0-100, with predefined minor and major ticks, I want to not allow for the slider to take values less than 50 under some conditions! i.e., I want the range 0-50 to be disabled, is this doable?

    Thanks
    Sog

    • @Sog – you can do this by creating a slider data custom model in Java code. Alternatively, you can have your Matlab callback check the new value and reset it to an allowed value in case it is outside the valid range.

  10. Dan says:

    Yair,

    Thanks for your article.
    The RangeSlider is great except I’d like to use it for very small fractional values. For example: I want to set range of zero to 0.001. The component isn’t happy with naively setting the range I’d like. I *could* just set the range from 0 to 1 and do my own scaling but then I’d have to shut off the labels & put some text indicating something like “*10^-3″… and… before you know it… things look ugly.

    Am I missing something?

    Thanks!

    Dan

    • @Dan – RangeSlider (and JSlider in general) only supports integer values, so 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.

  11. Amir G. says:

    How can I update/refresh the ‘foreground’ property ?
    I’m able to change that property but visually it always stays black Tick Labels won’t change.

    Nevertheless, with your ‘findjobj’ GUI the foreground color is affecting and refreshing.

  12. Soroush says:

    Thanks for the great tutorial

    I had two questions:

    1. How can I change the default [0-100] range?
    2. Is there a way to implement this in GUIDE-based GUI’s?

    • @Soroush – the JSlider object, just like any other object in Java and Matlab, has properties that you can set, including Maximum and Minimum. Use the builtin get function to see the available property values, and set to modify them.

  13. Amlan Datta Chowdhury says:

    Can some body help me know how this slider can be used for decimal scale? I found that if we set the minimum and maximum as 0 & 1 it’s not working

  14. Richard says:

    It took me a while to realize that Java sliders only support integer values. You note that in one of the replies to a comment, but it would be very helpful to put that significant difference from Matlab sliders into the body of this document – thanks.

    • @Richard – I really don’t think that this is a very big deal: you can keep the slider’s int values and just display custom labels that map to real-world floating-point values (or string labels for that matter). I recently created a Matlab class wrapper for a consulting client, which maps between Matlab double values and the JSlider‘s int values – the underlying JSlider component’s labels were dynamically updated to display floating-point values, 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. It looks and behaves just like a native Matlab component, with double-precision labels.

  15. Xiaoyang Liu says:

    Hi, I was wondering how to set the slider as a child of the MATLAB figure. This will allow the figure WindowKeyPressFcn work while the slider has the focus. Apparently I cannot simply set the slider’s ‘Parent’ property because it is not a MATLAB object.

    Thank you very much.

    • Sliders in figure-based (not web-based) UI are Java objects whose parent is a dedicated Matlab container that is automatically created when you use the javacomponent function. It is this container whose Parent property you can then set to be either a figure or another container (such as a uipanel or uitab). Of course, you can set the parent directly in the call to javacomponent, as the 3rd input argument.

  16. Koby Goldberg says:

    Hi Yair,
    Great tutorial!
    From the day I saw it, I’m looking for ways to use those JSliders in any way I can! They look amazing!

    I wonder if there is a way to create triple knob slider…?
    I mean 2 knobs to specify a range (like in com.jidesoft.swing.RangeSlider) and another knob to specify a value somewhere in between those (or outside of those).
    I need this for a project I’ve started recently. The alternative is to use 2 different sliders, but it would be much cooler to have both slides together!

    I found this link: http://threerings.github.io/tripleplay/apidocs/index.html?tripleplay/ui/Slider.html but I have no idea how to use it, or even if it is relevant or possible in any way in matlab…

    Thanks,
    Koby

    • @Koby – in general, you need to download the JAR/ZIP file(s) that contain this class (and all other classes on which it depends) from the website that you found, then add this file(s) to your Java classpath in Matlab using the javaaddpath function, and finally create an object from the new class and display it onscreen just as I explained in the main post above.

  17. Misha says:

    Dear Yair,
    Thank you for all the wonderful tips!
    The sliders work as advertised, but I would like to be able to add a jSlider to an already existing GUI created using the GUIDE. More specifically, since the GUI is resizable, I would like make it so that upon creation, the slider be attached to a particular panel, so that the proportions are preserved window is being resized. Is there a way to do that? Thanks in advance.

  18. Koby says:

    Hi Yair,
    I wonder if it is possible to change the position of a jslider after initialized at the constructor to a different value?
    I couldn’t find any ‘Position’ property in it’s handler, like standard matlab UI elements have…

    Thanks,
    Koby

  19. Peter Cook says:

    Yair,

    Any idea what kind of object the sliders on the MATLAB colormap editor colormapeditor are? Of course findjobj(colormapeditor) didn’t work because there’s no (apparent) handle returned by colormapeditor. I am interested in using several sliders in a similar manner.

    • @Peter – as Ctrl-Shift-F1 indicates, the slider object is not a slider at all but rather a custom Java component created by MathWorks, namely com.mathworks.page.cmapeditor.CMEditView. You can take a look at the Matlab source-code for colormap (in %matlabroot%/toolbox/matlab/graph3d/colormapeditor.m) for additional details that might help you reuse this component.

  20. Zach Mauch says:

    I’m using the java slider in a GUI, but I’m getting some weird behavior as I actively slide. I added an edit box to populate the index into for the user. It populates fine when I move the slider one by one or slowly. When I grab it and drag, the callbacks appear to be piling up and the box gets populated with the first index instead of the last.

    Example:

    I drag the slider quickly from 20 to 60. The box will start at 60 and then quickly cycle down to 21.

    It is like the entire GUI is having trouble keeping up. Maybe I need to try to up the efficiency processing a little, but I didn’t think I was doing that much.

    Anyway, one workaround I thought of was to change it to a callback that will only implement when I release the slider rather than continually implementing it. Any suggestions?

    • @Zach – a slider that only fires when you release the drag handle is the default documented way that Matlab’s slider works. My post is only relevant if you want updates to happen while the handle is being dragged.

    • Marie Jeanneteau says:

      @Zach Mauch
      Have you found a way to solve your problem ?
      I am in the same case and was only using jRangeSlider because it is an easy way to use a ‘good looking’ knob-dual slider. But actually I am not that interested in updating while the handle is being dragged.

  21. Royi says:

    Hi,

    Is there a way to create triple slider?
    Namely a slider with 3 knobs to set left, center and right value?

    Thank You.

    • @Royi – I’m not familiar with any such control within Matlab, but you may possibly find such in one of the numerous online Java libraries (there were hundreds of thousands of Java libraries online, more than 10 times more than in the Matlab File Exchange). Then integrate the component in your Matlab GUI in much the same way.

  22. Bogdan says:

    Hi,

    is it possible to control the thumb color of a jslider within matlab?

    Thanks

    • The slider thumb color is typically set by the Look&Feel and cannot be changed, except by changing the L&F’s standard control color (which is not advisable).
      To update the Look-&-Feel in Matlab GUI, look here: https://undocumentedmatlab.com/blog/modifying-matlab-look-and-feel.

      A few L&Fs may honor the settable internal Slider.thumb client property, but I’m not sure which L&Fs and under which circumstances (for example, it might depend on your Operating System and/or the Matlab release [which affects the version of Java]):

      jSlider = javaObjectEDT(javax.swing.JSlider(0,100,20));
      jColor = java.awt.Color(1.0,0.0,0.0);  % red
      jSlider.putClientProperty('Slider.thumb',jColor);
      [hjSlider,hContainer] = javacomponent(jSlider, [10,10,100,20], gcf);

      but as I said above, many L&Fs ignore this property. Discovering how to proceed from here is a pure Java issue, unrelated to Matlab, so I leave this up to you and other readers to figure out on Java forums. Here are 2 places to get you started: link1, link2.

  23. jmarco says:

    Is there a way to color in the slider between the lower bound and the current value? Here’s an example of what I mean: (in case the image doesn’t load, this image is from the Oracle documentation on sliders).

    In MATLAB, the slider track doesn’t have either side colored in. I’ve tried switching the look & feel to every built in option, but none of them gives me something like I see on Oracle’s website. There doesn’t seem to be a property on the slider itself that can be changed to do this.

    • This is not a settable property of the standard Swing JSlider. You need to modify the slider’s look-&-feel properties. These include several color properties, so play around a bit.
      To update the Look-&-Feel in Matlab GUI, look here: https://undocumentedmatlab.com/blog/modifying-matlab-look-and-feel.

    • jmarco says:

      @Yair Altman – Thanks for the quick response. I’ll investigate the color properties some more. I tried changing the look and feel using the directions on your website, but each one (Metal, Nimbus, Motif, and GTK) has an unfilled slider.
      I found an option that looks promising: modifying the client properties to set “isFilled” to true.

      Interestingly, in the application I’m working on, I don’t get a filled JSlider, but as I was putting together an example to show how it didn’t work, I got a filled JSlider!

      So, here’s the working example:

      f = figure;
      jSlider = javaObjectEDT(javax.swing.JSlider(0,100,20));
      jSlider.putClientProperty('JSlider.isFilled', java.lang.Boolean.TRUE)
      [jsl,hsl] = javacomponent(jSlider);

      Now I just have to figure out how to make it work with my application.

  24. Robi says:

    Hi,
    I’d love to use the RangeSlider in my app.
    I came up with 2 solutions:

    1) Using StateChangeCallback:

    function rangeSliderStateChange
    %RANGESLIDERSTATECHANGE
       fh = figure('NumberTitle','off','Name','StateChangeCallback');
       jRangeSlider = com.jidesoft.swing.RangeSlider(0,100,20,70);  % min,max,low,high
       jhgRangeSlider = javacomponent(jRangeSlider, [0,0,200,80], fh);
       jhgRangeSlider.StateChangedCallback = @slide;
    end
     
    function slide(Src,EvtData )
    %SLIDE
       if Src.getValueIsAdjusting
          fprintf('Dragging to %d\n',Src.getValue)
       else
          fprintf('Stopped at %d\n',Src.getValue)
       end
    end

    This has the limitation that I cannot determine if the left or right knob was dragged, which is OK for me.

    2) Using PropertyChangeCallback:

    function rangeSliderPropertyChange
    %RANGESLIDERPROPERTYCHANGE
       fh = figure('NumberTitle','off','Name','PropertyChangeCallback');
       jRangeSlider = com.jidesoft.swing.RangeSlider(0,100,20,70);  % min,max,low,high
       jhgRangeSlider = javacomponent(jRangeSlider, [0,0,200,80], fh);
       jhgRangeSlider.PropertyChangeCallback = @slide;
    end
     
    function slide(Src,EvtData )
    %SLIDE
       if strcmp(EvtData.getPropertyName,'lowValue')
          fprintf('Ended low at %d\n',Src.getLowValue)
       elseif strcmp(EvtData.getPropertyName,'highValue')
          fprintf('High at %d\n',Src.getHighValue)
       %else all kinds of properties I am totally not interested in
       end
    end

    This may have more overhead because there are many events fired we need to filter out.

    Both these solutions do have the drawback that the change events are also fired if the knob values are changed programmatically, which could easily end up in an infinite loop.
    I think the point is, that the sliders do not have an ActionCallback like most of the other swing controls.
    Can you think of a solution which only fires events if the user interacts with the knobs?

    Background is that I like to design my apps in a more or less global MVC pattern: One or more parameter objects with setObservable properties. A listener updates all uicontrols. When the user enters something into an edit textbox for numeric content, for example, the uicontrol callback converts to numeric and tries to update the parameter object. The parameter object checks the value range and updates the corresponding property, which fires the event which updates the uicontrol (-> infinite loop for the RangeSlider).

    • @Robi – you could try to trap MouseDraggedCallback and MouseClickedCallback, which would only trigger if the user interacts with the slider using the mouse (also trap KeyPressedCallback if you want to trap arrow key-clicks etc.).

      Alternatively, you can keep your existing mechanisms and simply add a re-entrancy check – several alternatives are discussed here: https://undocumentedmatlab.com/blog/controlling-callback-re-entrancy.

    • Robi says:

      This topic is already discussed elsewhere: https://groups.google.com/forum/#!topic/jquery-ui-dev/o1CImjd8Wbg
      But the solution already was on my hand:
      Src.getValueIsAdjusting appears to only be true if the user interacted with the slider (and at the _first_ setLowValue/setHighValue call, even if the value hasn’t changed)
      – only trigger global tool parameter update if Src.getValueIsAdjusting=false (that’s equivalent to uicontrol(‘Style’,’slider’) callback)

  25. samina says:

    hi everyone!
    I am developing my app using App designer but not satisfy with the look .. I want my app look like professional UIDesign( Flat design) .In order to fulfill my own requirement I searched for the tools like I did for C# and WPF (Infragistic tool , Bunifu controls) but failed …. so can anyone help me in this regard…hoping that I will find some help

    • @Samina – in Matlab you have a choice between web-based UI (as with App Designer) or using Java-based controls (as I’ve shown in many articles on this website). In either case, if you wish to achieve professional-looking UI, consider using my professional services. More information and sample screenshots here: https://undocumentedmatlab.com/development

Leave a Reply

Your email address will not be published. Required fields are marked *