-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathgetjframe.m
166 lines (151 loc) · 6.04 KB
/
getjframe.m
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
function jframe = getjframe(hFig)
% getjframe Retrieves the underlying Java frame for a figure
%
% Syntax:
% jframe = getjframe(hFig)
%
% Description:
% GETJFRAME retrieves the current figure (gcf)'s underlying Java frame,
% thus enabling access to all 35 figure callbacks that are not exposed
% by Matlab's figure.
%
% Notable callbacks include: FocusGainedCallback, FocusLostCallback,
% KeyPressedCallback, KeyReleasedCallback, MouseEnteredCallback,
% MouseExitedCallback, MousePressedCallback, MouseReleasedCallback,
% WindowActivatedCallback, WindowClosedCallback, WindowClosingCallback,
% WindowOpenedCallback, WindowStateChangedCallback and 22 others.
%
% The returned jframe object also allows access to other useful window
% features: 'AlwaysOnTop', 'CloseOnEscapeEnabled', 'Resizable',
% 'Enabled', 'HWnd' (for those interested in Windows integration) etc.
% Type "get(jframe)" to see the full list of properties.
%
% GETJFRAME(hFig) retrieves a specific figure's underlying Java frame.
% hFig is a Matlab handle, or a list of handles (not necesarily figure
% handle(s) - the handles' containing figure is used).
%
% Examples:
% get(getjframe,'ListOfCallbacks'); %display list of supported callbacks
% set(getjframe,'WindowStateChangedCallback','disp(''Window min/maxed'')')
% set(getjframe,'WindowDeiconifiedCallback',@winMaximizedCallback)
% set(getjframe,'WindowIconifiedCallback',{@winMinimizedCallback,mydata})
% set(getjframe,'CloseOnEscapeEnabled','on')
% jframes = getjframe([gcf,hButton]); % get 2 java frames, from 2 figures
%
% Bugs and suggestions:
% Please send to Yair Altman (altmany at gmail dot com)
%
% Change log:
% 2007-08-05: First version posted on <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&mfx=1&objectId=1096533#">MathWorks File Exchange</a>
% 2007-08-11: Added Matlab figure handle property; improved responsiveness handling; added support for array of handles; added sanity checks for illegal handles
%
% See also:
% gcf, findjobj (on the File Exchange)
% Programmed by Yair M. Altman: altmany(at)gmail.com
% $Revision: 1.0 $ $Date: 2007/08/04 21:39:24 $
try
% Default figure = current (gcf)
if nargin < 1 || ~all(ishghandle(hFig))
if nargin && ~all(ishghandle(hFig))
error('hFig must be a valid GUI handle or array of handles');
end
hFig = gcf;
end
% Require Java engine to run
if ~usejava('jvm')
error([mfilename ' requires Java to run.']);
end
% Initialize output var (needed in case hFig is empty)
jframe = handle([]);
% Loop over all requested figures
for figIdx = 1 : length(hFig)
% Get the root Java frame
jff = getJFrame(hFig(figIdx));
% Add the 'ListOfCallbacks' read-only property to jframe
fields = fieldnames(get(jff));
cb1Idx = find(~cellfun('isempty',strfind(fields,'Callback')));
cb2Idx = find(~cellfun('isempty',strfind(fields,'CallbackData')));
cbIdx = setdiff(cb1Idx, cb2Idx)';
cbNames = fields(cbIdx);
jframe(figIdx) = handle(jff,'callbackproperties');
addReadOnlyProp(jframe(figIdx),'ListOfCallbacks',cbNames);
% Add another read-only property for direct access to the wrapped java object
addReadOnlyProp(jframe(figIdx),'JavaComponent',jff);
% Add another read-only property for direct access to the original Matlab figure handle
addReadOnlyProp(jframe(figIdx),'MatlabFigureHandle',hFig(figIdx));
end
% Error handling
catch
v = version;
if v(1)<='6'
err.message = lasterr; % no lasterror function...
else
err = lasterror;
end
try
err.message = regexprep(err.message,'Error using ==> [^\n]+\n','');
catch
try
% Another approach, used in Matlab 6 (where regexprep is unavailable)
startIdx = findstr(err.message,'Error using ==> ');
stopIdx = findstr(err.message,char(10));
for idx = length(startIdx) : -1 : 1
idx2 = min(find(stopIdx > startIdx(idx))); %#ok ML6
err.message(startIdx(idx):stopIdx(idx2)) = [];
end
catch
% never mind...
end
end
if isempty(findstr(mfilename,err.message))
% Indicate error origin, if not already stated within the error message
err.message = [mfilename ': ' err.message];
end
if v(1)<='6'
while err.message(end)==char(10)
err.message(end) = []; % strip excessive Matlab 6 newlines
end
error(err.message);
else
rethrow(err);
end
end
%% Add a read-only property to an object
function addReadOnlyProp(obj,propName,initValue)
try
sp = schema.prop(obj,propName,'mxArray');
set(obj,propName,initValue);
set(sp,'AccessFlags.PublicSet','off');
catch
% Never mind - property might already exist...
end
%% Get the root Java frame (up to 10 tries, to wait for figure to become responsive)
function jframe = getJFrame(hFigHandle)
% Ensure that hFig is a figure handle...
hFig = ancestor(hFigHandle,'figure');
if isempty(hFig)
error(['Cannot retrieve the figure handle for handle ' num2str(hFigHandle)]);
end
jframe = [];
maxTries = 10;
while maxTries > 0
try
% Get the figure's underlying Java frame
jf = get(hFig,'javaframe');
% Get the Java frame's root frame handle
%jframe = jf.getFigurePanelContainer.getComponent(0).getRootPane.getParent;
jframe = jf.fFigureClient.getWindow; % equivalent to above...
if ~isempty(jframe)
break;
else
maxTries = maxTries - 1;
drawnow; pause(0.1);
end
catch
maxTries = maxTries - 1;
drawnow; pause(0.1);
end
end
if isempty(jframe)
error(['Cannot retrieve the java frame for handle ' num2str(hFigHandle)]);
end