- Undocumented Matlab - https://undocumentedmatlab.com -

Animated busy (spinning) icon

Posted By Yair Altman On April 16, 2014 | 51 Comments

Matlab includes a wide variety of internal widgets (GUI components) that could be very useful in our GUIs. One such widget is an animated spinning icon, which is often used by Matlab itself and numerous toolboxes to illustrate a running task:

Sample usage of an animated spinning icon
Sample usage of an animated spinning icon

One of the internal widgets that are readily-available for use in our Matlab GUI and displays a similar (but not identical) spinning icon is BusyAffordance, which is included in the built-in com.mathworks.widgets package. BusyAffordance creates a visible panel with an animated spinning icon and optional text label as long as the panel’s object is in the “started” mode (the mode can be started/stopped numerous times).
Animated spinner icon
Animated spinner icon

The usage is very simple:

try
    % R2010a and newer
    iconsClassName = 'com.mathworks.widgets.BusyAffordance$AffordanceSize';
    iconsSizeEnums = javaMethod('values',iconsClassName);
    SIZE_32x32 = iconsSizeEnums(2);  % (1) = 16x16,  (2) = 32x32
    jObj = com.mathworks.widgets.BusyAffordance(SIZE_32x32, 'testing...');  % icon, label
catch
    % R2009b and earlier
    redColor   = java.awt.Color(1,0,0);
    blackColor = java.awt.Color(0,0,0);
    jObj = com.mathworks.widgets.BusyAffordance(redColor, blackColor);
end
jObj.setPaintsWhenStopped(true);  % default = false
jObj.useWhiteDots(false);         % default = false (true is good for dark backgrounds)
javacomponent(jObj.getComponent, [10,10,80,80], gcf);
jObj.start;
    % do some long operation...
jObj.stop;
jObj.setBusyText('All done!');

Note how I’ve used the javacomponent function [1] to place the BusyAffordance object onscreen, at position 10,10 of the current Matlab figure, and gave it an initial size of 80×80 pixels.
When the object is stop()ed, the icon and label are removed by default, but can be displayed un-animated (non-spinning) via the PaintsWhenStopped property:

BusyAffordance started... (animated spinning icon)
BusyAffordance started...
(animated spinning icon)
   
...stopped (PaintsWhenStopped = false)
...stopped
(PaintsWhenStopped = false)
   
...stopped (PaintsWhenStopped = true)
...stopped
(PaintsWhenStopped = true)

The small-icon (16×16) variant of the BusyAffordance control is used by another internal Matlab component, ProgressBarDialog. This control presents an animated progress-bar dialog window, similar to Matlab’s built-in waitbar function but with an animated busy icon:

d = com.mathworks.mlwidgets.dialog.ProgressBarDialog.createProgressBar('test...', []);
d.setValue(0.75);                        % default = 0
d.setProgressStatusLabel('testing...');  % default = 'Please Wait'
d.setSpinnerVisible(true);               % default = true
d.setCircularProgressBar(false);         % default = false  (true means an indeterminate (looping) progress bar)
d.setCancelButtonVisible(true);          % default = true
d.setVisible(true);                      % default = false

ProgressBarDialog with animated BusyAffordance
ProgressBarDialog with animated BusyAffordance

For those interested, the 16×16 animated GIF used here is spinner.gif, which can be found in %matlabroot%/java/jar/mlwidgets.jar (remember that JAR files are simply ZIP files, so they can be opened in WinZip/WinRar etc.). BusyAffordance also includes a 32×32 icon which is not available as a separate icon file. Also, the BusyAffordance spin direction is reversed compared to the spinner icon. From this we learn that BusyAffordance probably creates its spinner image on-the-fly (programmatically), rather than use spinner.gif.
For additional information on BusyAffordance, com.mathworks.widgets and other internal Matlab components, refer to chapter 5 in my Matlab-Java programming book [2].
As with other internal Matlab components, I categorized this feature as “High risk of breaking in a future release“. Still, BusyAffordance has existed in its present form since R2010a (and with a slightly different interface for years before then), so there’s a good chance that it will continue as-is in the foreseeable future. Then again, it might be removed as early as the next upcoming release, without prior warning…
More advanced animated busy indications, including automated percentage and time-remaining labels, can be specified using JBusyComponent [3], which is a JXLayer [4] decorator that can be applied to any displayable component. In R2013b or newer that use Java7, we can also use the built-in JLayer [5] class. We can also simply embed the animated GIF image directly in our GUI, as I explained here [6].
In the past I have already shown how to use other internal components in Matlab’s com.mathworks.widgets package, including syntax-highlighted labels and text panes [7] that can be embedded in our Matlab GUI.
Have you used BusyAffordance or some other internal Matlab component in a neat way in your GUI? if so, please do tell us about it in a comment below [8].

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


51 Comments (Open | Close)

51 Comments To "Animated busy (spinning) icon"

#1 Comment By Aurélien On April 17, 2014 @ 00:18

Hi Yair!

How do you close or delete safely the above ProgressBarDialog with animated BusyAffordance ?

Thanks
Aur

#2 Comment By Yair Altman On April 17, 2014 @ 11:15

d.dispose()

(or simply click the <Cancel> button…)

#3 Comment By Aurélien On April 18, 2014 @ 00:04

Thanks Yair!

#4 Comment By peinal On April 18, 2014 @ 11:12

How to make the Figure just frame the spinning icon (in size)?

#5 Comment By Yair Altman On April 19, 2014 @ 10:09

@Peinal – I don’t understand the problem: why don’t you simply resize the figure using its Position property?

#6 Comment By AB On May 1, 2014 @ 06:33

Hi Yair,

Why is it that we don’t need to use javaObjectEDT for this spinner icon?

Kind regards,
AB

#7 Comment By Yair Altman On May 1, 2014 @ 07:39

In general we aught to use javaObjectEDT for all Java components, but since this control is not interactive it makes little difference.

#8 Comment By me On May 10, 2014 @ 08:35

Hi Yair,
How could I delete the BusyAffordance “button”, or set it invisible? (not just stop it)

Thank you!

#9 Comment By Yair Altman On May 10, 2014 @ 10:50

% Alternative 1
[hjObj, hContainer] = javacomponent(jObj.getComponent, [10,10,80,80], gcf);
...
delete(hContainer);

% Alternative 2
jObj.getComponent.setVisible(false)

#10 Comment By me On May 10, 2014 @ 12:26

Thank you very much!

#11 Comment By Johny On May 15, 2014 @ 00:47

Hi, Yair,

The post is quite useful and thanks!

I put the Busy Widget into a panel so that I can make it invisible simply. But even if I set the panel frame color to “none” (thanks for [15]), the widget’s background frame is still visible. Can we make the background of the widget transparent?

#12 Comment By Yair Altman On May 15, 2014 @ 14:58

No, but you can set it to any non-transparent bg color:

jObj.getComponent.setBackground(java.awt.Color(1.0, 0.78, 0.0));  % orange

#13 Comment By Vishal Rane On May 20, 2014 @ 00:18

Doing

 
jObj.setBusyText('All done!');

before stopping the object ensures setBusyText property is updated in the figure.

#14 Comment By Dani On June 5, 2014 @ 07:18

Hi Yair!

First of all, congrats for your amazing blog.

I wanted to know whether it is possible to get the “parent figure” (the handle) of the ProgressBarDialog, in order to prevent it from being accidentally closed. I usually create an empty closerequestfcn on the figure handles for this.

Is it also possible to change the title of a ProgressBarDialog?

Thanks in advance!

#15 Comment By Yair Altman On June 5, 2014 @ 09:11

@Dani – there is no direct way to find the containing frame, but it can be found indirectly:

jProgressFrame = [];
jFrames = java.awt.Frame.getFrames;
for idx = 1 : numel(jFrames)
    if strcmpi(jFrames(idx).getName, 'ProgressBarDialog')
        jProgressFrame = jFrames(idx);
        break;
    end
end

Note that this is a Java Frame, not a Matlab figure window.

To modify the title simply update the Frame’s Title property:

jProgressFrame.setTitle('New title...')

#16 Comment By Charlie On June 5, 2014 @ 21:49

Excellent post, Yair!

Is it posible to include this spinning icon on a figure created with h=figure(…)?

Cheers!

#17 Comment By Yair Altman On June 5, 2014 @ 23:26

@Charlie – that’s exactly what I showed in my article for BusyAffordance, which is placed in a Matlab figure using the javacomponent function. Run the code in the article text and see for yourself.

#18 Comment By Shannon On July 16, 2014 @ 21:43

Excellent work,Yair! And THX for your sharing.

Is it possible to detect whether the Cancel button is clicked? And how to process this click event?

#19 Comment By Yair Altman On July 18, 2014 @ 01:19

@Shannon – I’m not aware of a way to do this. You will probably need to create your own dialog window for this. It shouldn’t be too difficult, it’s just a few simple controls.

#20 Comment By Aurélien On July 22, 2014 @ 04:40

It seems that the ProgressBarDialog class does not exist anymore in R2014b Prelerelease …

#21 Comment By Hugo Mendonça On July 28, 2014 @ 11:20

Hi, Yair!

First of all, I have to say I have read a few topics of your website and it is amazing! Congrats for it and all your effort to make it possible!

I am a beginner with simulink and I got some problem. I want to display the simulink progress simulation and I am using a fcn block. The alternative to display it in the command view worked perfectly, however this present example with the progress bar have failed.

Do you have any idea how to apply this example in a fcn block in simulink?

Appreciate your help!

#22 Comment By Iain D On September 8, 2014 @ 08:54

Are there any significant advantages to this approach over simply changing the pointer to a spinning circle using code similar to the method below?

set(handles.GUI_main, 'pointer', 'watch'); drawnow;
%code in here that does something...
set(handles.GUI_main, 'pointer', 'arrow')

As a first time poster and relative newcomer to GUIs in MATLAB I’d like to add that your website is an invaluable resource, many thanks.

#23 Comment By Yair Altman On September 8, 2014 @ 08:56

@Iain – the difference is that in some case we may want a static spinning icon embedded in the GUI, not just changing the mouse pointer.

#24 Comment By Arjen On November 12, 2014 @ 20:23

Since you suspect that the spinner image is created programmatically rather than it being a gif, would it be possible to control the spinning speed?

#25 Comment By Kathi K On April 13, 2015 @ 06:08

Hey Yair,

I wondered how you managed to get the animated icon in the cell of a table(?) ?
When using

jTable.setValueAt(str,1,1)

str being a html content, my gif is static; no animation 🙁

Appreciate your help,
Kathi

#26 Comment By Robert Moss On April 23, 2015 @ 13:38

I placed your ProgressBarDialog code above into a little function for my own use. MOST of the time it works fine. SOME of the time, and I can’t figure out what is causing this, all of Matlab will completely hang when calling this function. I happen to be running 2013a. Has anyone else seen this issue? If I put in a break point and step through the code, it all works fine. When I do not put in a break point, it hangs somewhere in the code shown above. Has anyone else had this issue? I’m guessing it’s a Java related thing that I have little control over… feels like a timing issue somehow. It refuses to hang when stepping through in the debugger.

#27 Comment By Yair Altman On April 23, 2015 @ 13:46

@Robert – this sounds like a plain standard Matlab EDT timing problem, whose solutions I described [16] and [17].

#28 Comment By scmg On July 4, 2015 @ 19:21

Hi, i’m trying your example for BusyAffordance in a listbox. When the listbox’s CallbackFcn is called, i want to set listbox’s ‘Enable’ to ‘off’, have a spinning circle, do something which take ~ 3sec, stop the spinning circle, then turn on the listbox again. However, at the first time CallbackFcn is called, nothing appears at first, when process finishes, only the ‘All done!’-circle appears. And after that, nothing changes… Can you give me some suggestions? 🙁

I am using R2015a, and com.mathworks.mlwidgets.dialog.ProgressBarDialog.createProgressBar also does not exist anymore … cannot try your other example 🙁

#29 Comment By Yair Altman On July 7, 2015 @ 11:33

@SCMG – yes, com.mathworks.mlwidgets.dialog.ProgressBarDialog was removed in R2014b.

As to why you don’t see the spinning circle, try to add a call to drawnow and jObj.getComponent.repaint after jObj.start. Also, ensure that the component is visible onscreen when you call jObj.start.

#30 Comment By Paul On October 9, 2015 @ 05:27

Hi, I’m really interested in using the progress bar in my GUI. I’ve managed to make it appear when clicking on a button thanks to you (that’s great, really !)
However I would love it to appear in my main figure, called hfig, and not in a new one.
Also,is it possible to make it disappear when some action is done ? (a parameter going from 0 to 1 for instance) ?

Thanks a lot !

#31 Comment By Yair Altman On October 10, 2015 @ 09:05

@Paul – I assume you mean ProgressBarDialog – this is a dialog window so it naturally appears in its own window, like all dialogs. If you want integrated progress bars, there are multiple alternatives. You can find some examples in the Matlab File Exchange. Or try [18].

Maybe I’ll blog about this someday.

#32 Comment By Tommie Heard On November 12, 2015 @ 08:22

Since com.mathworks.mlwidgets.dialog.ProgressBarDialog was removed in R2014b, is there another way to get the spinning progressbar to work? I loved how it worked.

#33 Comment By Alex On March 14, 2016 @ 17:42

Hello,

Anyway I can change the background color of BusyAffordance? I found the method setBackground under getComponent but it doesn’t work.

No method 'setBackground' with matching signature found for class
'com.mathworks.widgets.BusyAffordance$1'.

Thanks,
A.

#34 Comment By Yair Altman On March 14, 2016 @ 18:42

@Alex – setBackground() is a Java method (function) that accepts Java colors (e.g. java.awt.Color.yellow), not Matlab ones. Whether or not this specific setBackground() method has the desired effect on BusyAffordance I do not know.

#35 Comment By Alex On March 14, 2016 @ 19:20

Well, I did this:

obj.jObj = com.mathworks.widgets.BusyAffordance(Size32x32, 'Processing...');
javaObj = handle(obj.jObj.getComponent);
javaObj.setBackground(java.awt.Color.red);

but It didn’t change the color. Gotta keep trying. Thanks Yair for your quick response, by the way.

#36 Comment By Alex On March 14, 2016 @ 19:36

Actually it does work! I was changing the color in two difference places. For future references, to change the BusyAffordances background color use this:

jObj.getComponent.setBackground(java.awt.Color(0.8, 0.8, 0.8));

#37 Comment By Al On April 18, 2016 @ 16:50

Is there a way to change the BusyText to a different color?
For example, make the ‘testing…’ and ‘All done!’ text under the busy animation to white?
I tried using:

jObj.getComponent.setForeground(java.awt.Color(1, 1, 1));

But this didn’t work and checking

jObj.getComponent.getForeground

Returned

java.awt.Color[r=26,g=26,b=26]

Thanks
Al

#38 Comment By Al On April 18, 2016 @ 16:57

Correction: getForeground Returned

java.awt.Color[r=255,g=255,b=255]

(As expected but no change to font color seen)
Also tried:

jObj.getComponent.repaint

After setting but to no avail
Thanks
Al

#39 Comment By Yair Altman On April 18, 2016 @ 17:43

I do not know that this is possible with BusyAffordance

#40 Comment By Richard On August 13, 2016 @ 00:20

Is there a way to create and use a custom spinning icon? if so, how?

#41 Comment By Malcolm Lidierth On August 14, 2016 @ 12:09

Simplest: put an animated GIF as image in a button.

#42 Comment By Yair Altman On August 14, 2016 @ 12:20

While BusyAffordance and ProgressBarDialog icons cannot be modified externally, but you can create your own animated icon as Malcolm noted or as explained here: [19] (or using one of the other mechanisms that I referenced in my post text above).

#43 Comment By Piyush Khajanji On January 31, 2017 @ 23:20

How to remove the Background Box/Square after the processing automatically, I am able to set invisible property to text but not Background. Thanks in advance.

#44 Comment By BenBen On November 13, 2017 @ 16:14

Is there a way to get multiple text lines in the jObj.setBusyText? Thanks !

#45 Comment By Yair Altman On November 13, 2017 @ 16:47

@Ben – I am not aware of any way to set multi-line text in the BusyAffordance object

#46 Comment By Tobias On July 2, 2018 @ 12:06

Hi,

I’m trying to use the ProgressBarDialog in Matlab R2018a. However, it seems to be missing from the com.mathworks.mlwidgets package.

Do you know if it has been removed completely or just renamed or moved to another package?

Thank you!

#47 Comment By Yair Altman On July 2, 2018 @ 13:40

@Tobias – I do not have an immediate answer. You can easily open the Jar files (for example %matlabroot%/java/jar/mlwidgets.jar) using WinZip or WinRAR and check this. If you would like me to spend time to investigate this for you, then please contact me by email for private consulting.

#48 Comment By Marc On September 4, 2018 @ 16:03

Hi,

How could we increase the size of the text below (“testing…”) ?

Thanks

#49 Comment By Yair Altman On September 5, 2018 @ 00:52

I am not aware of a way to modify the text font. You might have thought that jObj.getComponent.setFont(jObj.getComponent.getFont.deriveFont(20)) would do the trick, but in fact it just shifts the text label without modifying its font.

#50 Comment By Collin Pecora On September 6, 2018 @ 11:21

Marc,

I don’t understand why, but BusyAffordance uses the MJPanel‘s font to measure the busy text, but uses the UIManager’s Label.font to draw it.
So, you can do something like below, have not tested on the 2009 and below version.

jOldFont = javax.swing.UIManager.getFont('Label.font'); % get Label.font
jNewFont = jOldFont.deriveFont(20);                     % derive a new font with size 20
javax.swing.UIManager.put('Label.font',jNewFont)        % set Label.font to the new font

try
    % R2010a and newer
    iconsClassName = 'com.mathworks.widgets.BusyAffordance$AffordanceSize';
    iconsSizeEnums = javaMethod('values',iconsClassName);
    SIZE_32x32 = iconsSizeEnums(2);  % (1) = 16x16,  (2) = 32x32
    jObj = com.mathworks.widgets.BusyAffordance(SIZE_32x32, 'testing...');  % icon, label
catch
    % R2009b and earlier
    redColor   = java.awt.Color(1,0,0);
    blackColor = java.awt.Color(0,0,0);
    jObj = com.mathworks.widgets.BusyAffordance(redColor, blackColor);
end

jPanel = jObj.getComponent;       % get the MJPanel 
jPanel.setFont(jNewFont)          % set the panel's font to the new font

jObj.setPaintsWhenStopped(true);  % default = false
jObj.useWhiteDots(false);         % default = false (true is good for dark backgrounds)
javacomponent(jObj.getComponent, [10,10,80,80], gcf);
jObj.start;
    % do some long operation...
jObj.stop;
jObj.setBusyText('All done!');

javax.swing.UIManager.put('Label.font',jOldFont) % undo what we changed
 

#51 Comment By marc On September 7, 2018 @ 16:42

Thank you very much ! It did the job 😉


Article printed from Undocumented Matlab: https://undocumentedmatlab.com

URL to article: https://undocumentedmatlab.com/articles/animated-busy-spinning-icon

URLs in this post:

[1] javacomponent function: http://undocumentedmatlab.com/blog/javacomponent

[2] Matlab-Java programming book: http://undocumentedmatlab.com/matlab-java-book

[3] JBusyComponent: http://code.google.com/p/jbusycomponent

[4] JXLayer: https://java.net/projects/JXLayer

[5] JLayer: http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html#animating

[6] as I explained here: http://undocumentedmatlab.com/blog/displaying-animated-gifs

[7] syntax-highlighted labels and text panes: http://undocumentedmatlab.com/blog/syntax-highlighted-labels-panels

[8] a comment below: http://undocumentedmatlab.com/blog/animated-busy-spinning-icon#respond

[9] Icon images & text in Matlab uicontrols : https://undocumentedmatlab.com/articles/icon-images-in-matlab-uicontrols

[10] Displaying animated GIFs : https://undocumentedmatlab.com/articles/displaying-animated-gifs

[11] Font selection components : https://undocumentedmatlab.com/articles/font-selection-components

[12] Uitable sorting : https://undocumentedmatlab.com/articles/uitable-sorting

[13] Builtin PopupPanel widget : https://undocumentedmatlab.com/articles/builtin-popuppanel-widget

[14] uigetfile/uiputfile customizations : https://undocumentedmatlab.com/articles/uigetfile-uiputfile-customizations

[15] : https://undocumentedmatlab.com/blog/transparent-uipanels

[16] : https://undocumentedmatlab.com/blog/solving-a-matlab-hang-problem

[17] : https://undocumentedmatlab.com/blog/matlab-and-the-event-dispatch-thread-edt

[18] : http://stackoverflow.com/questions/5368861/how-to-add-progress-bar-control-to-matlab-gui

[19] : https://undocumentedmatlab.com/blog/displaying-animated-gifs

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.