Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
function statusbarHandles = statusbar(varargin)
%statusbar set/get the status-bar of Matlab desktop or a figure
%
% statusbar sets the status-bar text of the Matlab desktop or a figure.
% statusbar accepts arguments in the format accepted by the <a href="matlab:doc sprintf">sprintf</a>
% function and returns the statusbar handle(s), if available.
%
% Syntax:
% statusbarHandle = statusbar(handle, text, sprintf_args...)
%
% statusbar(text, sprintf_args...) sets the status bar text for the
% current figure. If no figure is selected, then one will be created.
% Note that figures with 'HandleVisibility' turned off will be skipped
% (compare <a href="matlab:doc findobj">findobj</a> & <a href="matlab:doc findall">findall</a>).
% In these cases, simply pass their figure handle as first argument.
% text may be a single string argument, or anything accepted by sprintf.
%
% statusbar(handle, ...) sets the status bar text of the figure
% handle (or the figure which contains handle). If the status bar was
% not yet displayed for this figure, it will be created and displayed.
% If text is not supplied, then any existing status bar is erased,
% unlike statusbar(handle, '') which just clears the text.
%
% statusbar(0, ...) sets the Matlab desktop's status bar text. If text is
% not supplied, then any existing text is erased, like statusbar(0, '').
%
% statusbar([handles], ...) sets the status bar text of all the
% requested handles.
%
% statusbarHandle = statusbar(...) returns the status bar handle
% for the selected figure. The Matlab desktop does not expose its
% statusbar object, so statusbar(0, ...) always returns [].
% If multiple unique figure handles were requested, then
% statusbarHandle is an array of all non-empty status bar handles.
%
% Notes:
% 1) The format statusbarHandle = statusbar(handle) does NOT erase
% any existing statusbar, but just returns the handles.
% 2) The status bar is 20 pixels high across the entire bottom of
% the figure. It hides everything between pixel heights 0-20,
% even parts of uicontrols, regardless of who was created first!
% 3) Three internal handles are exposed to the user (Figures only):
% - CornerGrip: a small square resizing grip on bottom-right corner
% - TextPanel: main panel area, containing the status text
% - ProgressBar: a progress bar within TextPanel (default: invisible)
%
% Examples:
% statusbar; % delete status bar from current figure
% statusbar(0, 'Desktop status: processing...');
% statusbar([hFig1,hFig2], 'Please wait while processing...');
% statusbar('Processing %d of %d (%.1f%%)...',idx,total,100*idx/total);
% statusbar('Running... [%s%s]',repmat('*',1,fix(N*idx/total)),repmat('.',1,N-fix(N*idx/total)));
% existingText = get(statusbar(myHandle),'Text');
%
% Examples customizing the status-bar appearance:
% sb = statusbar('text');
% set(sb.CornerGrip, 'visible','off');
% set(sb.TextPanel, 'Foreground',[1,0,0], 'Background','cyan', 'ToolTipText','tool tip...')
% set(sb, 'Background',java.awt.Color.cyan);
%
% % sb.ProgressBar is by default invisible, determinite, non-continuous fill, min=0, max=100, initial value=0
% set(sb.ProgressBar, 'Visible','on', 'Minimum',0, 'Maximum',500, 'Value',234);
% set(sb.ProgressBar, 'Visible','on', 'Indeterminate','off'); % indeterminate (annimated)
% set(sb.ProgressBar, 'Visible','on', 'StringPainted','on'); % continuous fill
% set(sb.ProgressBar, 'Visible','on', 'StringPainted','on', 'string',''); % continuous fill, no percentage text
%
% % Adding a checkbox
% jCheckBox = javax.swing.JCheckBox('cb label');
% sb.add(jCheckBox,'West'); % Beware: East also works but doesn't resize automatically
%
% Notes:
% Statusbar will probably NOT work on Matlab versions earlier than 6.0 (R12)
% In Matlab 6.0 (R12), figure statusbars are not supported (only desktop statusbar)
%
% Warning:
% This code heavily relies on undocumented and unsupported Matlab
% functionality. It works on Matlab 7+, but use at your own risk!
%
% Bugs and suggestions:
% Please send to Yair Altman (altmany at gmail dot com)
%
% Change log:
% 2007-May-04: Added partial support for Matlab 6
% 2007-Apr-29: Added internal ProgressBar; clarified main comment
% 2007-Apr-25: First version posted on MathWorks file exchange: <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=14773">http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=14773</a>
%
% See also:
% ishghandle, sprintf, findjobj (on the <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=14317">file exchange</a>)
% License to use and modify this code is granted freely without warranty to all, as long as the original author is
% referenced and attributed as such. The original author maintains the right to be solely associated with this work.
% Programmed and Copyright by Yair M. Altman: altmany(at)gmail.com
% $Revision: 1.0 $ $Date: 2007/04/25 16:43:24 $
% Check for available Java/AWT (not sure if Swing is really needed so let's just check AWT)
if ~usejava('awt')
error('YMA:statusbar:noJava','statusbar only works on Matlab envs that run on java');
end
% Args check
if nargin < 1 | ischar(varargin{1}) %#ok for Matlab 6 compatibility
handles = gcf; % note: this skips over figures with 'HandleVisibility'='off'
else
handles = varargin{1};
varargin(1) = [];
end
% Ensure that all supplied handles are valid HG GUI handles (Note: 0 is a valid HG handle)
if isempty(handles) | ~all(ishandle(handles)) %#ok for Matlab 6 compatibility
error('YMA:statusbar:invalidHandle','invalid GUI handle passed to statusbar');
end
% Retrieve the requested text string (only process once, for all handles)
if isempty(varargin)
deleteFlag = (nargout==0);
updateFlag = 0;
statusText = '';
else
deleteFlag = 0;
updateFlag = 1;
statusText = sprintf(varargin{:});
end
% Loop over all unique root handles (figures/desktop) of the supplied handles
rootHandles = [];
if any(handles) % non-0, i.e. non-desktop
try
rootHandles = ancestor(handles,'figure');
if iscell(rootHandles), rootHandles = cell2mat(rootHandles); end
catch
errMsg = 'Matlab version is too old to support figure statusbars';
% Note: old Matlab version didn't have the ID optional arg in warning/error, so I can't use it here
if any(handles==0)
warning([errMsg, '. Updating the desktop statusbar only.']); %#ok for Matlab 6 compatibility
else
error(errMsg);
end
end
end
rootHandles = unique(rootHandles);
if any(handles==0), rootHandles(end+1)=0; end
statusbarObjs = handle([]);
for rootIdx = 1 : length(rootHandles)
if rootHandles(rootIdx) == 0
setDesktopStatus(statusText);
else
thisStatusbarObj = setFigureStatus(rootHandles(rootIdx), deleteFlag, updateFlag, statusText);
if ~isempty(thisStatusbarObj)
statusbarObjs(end+1) = thisStatusbarObj;
end
end
end
% If statusbarHandles requested
if nargout
% Return the list of all valid (non-empty) statusbarHandles
statusbarHandles = statusbarObjs;
end
%end % statusbar %#ok for Matlab 6 compatibility
%% Set the status bar text of the Matlab desktop
function setDesktopStatus(statusText)
try
% First, get the desktop reference
try
desktop = com.mathworks.mde.desk.MLDesktop.getInstance; % Matlab 7+
catch
desktop = com.mathworks.ide.desktop.MLDesktop.getMLDesktop; % Matlab 6
end
% Schedule a timer to update the status text
% Note: can't update immediately, since it will be overridden by Matlab's 'busy' message...
try
t = timer('Name','statusbarTimer', 'TimerFcn',{@setText,desktop,statusText}, 'StartDelay',0.05, 'ExecutionMode','singleShot');
start(t);
catch
% Probably an old Matlab version that still doesn't have timer
desktop.setStatusText(statusText);
end
catch
%if any(ishandle(hFig)), delete(hFig); end
error('YMA:statusbar:desktopError',['error updating desktop status text: ' lasterr]);
end
%end %#ok for Matlab 6 compatibility
%% Utility function used as setDesktopStatus's internal timer's callback
function setText(varargin)
if nargin == 4 % just in case...
targetObj = varargin{3};
statusText = varargin{4};
targetObj.setStatusText(statusText);
else
% should never happen...
end
%end %#ok for Matlab 6 compatibility
%% Set the status bar text for a figure
function statusbarObj = setFigureStatus(hFig, deleteFlag, updateFlag, statusText)
try
jFrame = get(hFig,'JavaFrame');
jFigPanel = get(jFrame,'FigurePanelContainer');
jRootPane = jFigPanel.getComponent(0).getRootPane;
% If invalid RootPane, retry up to N times
tries = 10;
while isempty(jRootPane) & tries>0 %#ok for Matlab 6 compatibility - might happen if figure is still undergoing rendering...
drawnow; pause(0.001);
tries = tries - 1;
jRootPane = jFigPanel.getComponent(0).getRootPane;
end
jRootPane = jRootPane.getTopLevelAncestor;
% Get the existing statusbarObj
statusbarObj = jRootPane.getStatusBar;
% If status-bar deletion was requested
if deleteFlag
% Non-empty statusbarObj - delete it
if ~isempty(statusbarObj)
jRootPane.setStatusBarVisible(0);
end
elseif updateFlag % status-bar update was requested
% If no statusbarObj yet, create it
if isempty(statusbarObj)
statusbarObj = com.mathworks.mwswing.MJStatusBar;
jProgressBar = javax.swing.JProgressBar;

Mark Lawford
committed
jProgressBar.setVisible(false);
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
statusbarObj.add(jProgressBar,'West'); % Beware: East also works but doesn't resize automatically
jRootPane.setStatusBar(statusbarObj);
end
statusbarObj.setText(statusText);
jRootPane.setStatusBarVisible(1);
end
statusbarObj = handle(statusbarObj);
% Add quick references to the corner grip and status-bar panel area
if ~isempty(statusbarObj)
addOrUpdateProp(statusbarObj,'CornerGrip', statusbarObj.getParent.getComponent(0));
addOrUpdateProp(statusbarObj,'TextPanel', statusbarObj.getComponent(0));
addOrUpdateProp(statusbarObj,'ProgressBar', statusbarObj.getComponent(1).getComponent(0));
end
catch
try
title = jFrame.fFigureClient.getWindow.getTitle;
catch
title = get(hFig,'Name');
end
error('YMA:statusbar:figureError',['error updating status text for figure ' title ': ' lasterr]);
end
%end %#ok for Matlab 6 compatibility
%% Utility function: add a new property to a handle and update its value
function addOrUpdateProp(handle,propName,propValue)
try
if ~isprop(handle,propName)
schema.prop(handle,propName,'mxArray');
end
set(handle,propName,propValue);