📄 uiinspect.m
字号:
function hFig = uiinspect(obj)
% uiinspect Inspect an object handle (Java/COM/HG) and display its methods/props/callbacks in a unified window
%
% Syntax:
% hFig = uiinspect(obj)
%
% Description:
% UIINSPECT inspects an object handle (e.g., Java, COM, Handle Graphics
% etc.) and displays the inspection results in a unified Matlab window.
% UIINSPECT displays a unified window with all relevant object methods
% (as can be displayed via Matlab's methodsview function), properties
% (as can be displayed via Matlab's inspect function), and callbacks.
% UIINSPECT also displays properties that are not normally displayed
% with Matlab's inspect function. Property meta-data such as type,
% accessibility, visibility and default value are also displayed.
%
% Unlike Matlab's inspect function, multiple UIINSPECT windows can be
% opened simultaneously.
%
% Object properties and callbacks may be modified interactively within
% the UIINSPECT window.
%
% hFig = UIINSPECT returns a handle to the created figure window.
% UIINSPECT opens a regular Matlab figure window which may be accessed
% via hFig (unlike Matlab's methodsview function which opens a Java frame
% that is not easily accessible from Matlab).
%
% Examples:
% hFig = uiinspect(0); % root (desktop)
% hFig = uiinspect(handle(0)); % root handle
% hFig = uiinspect(gcf); % current figure
% hFig = uiinspect(handle(gcf)); % current figure handle
% uiinspect(get(gcf,'JavaFrame')); % current figure's Java Frame
% uiinspect(classhandle(handle(gcf))); % a schema.class object
% uiinspect(findprop(handle(gcf),'MenuBar')); % a schema.prop object
% uiinspect('java.lang.String') % a Java class name
% uiinspect(java.lang.String('yes')); % a Java object
% uiinspect(actxserver('Excel.Application')); % a COM object
%
% Known issues/limitations:
% - Fix: some fields generate a Java Exception, or a Matlab warning
% - other future enhancements may be found in the TODO list below
%
% 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:
% 2009-03-05: Fixed single property edge-case; fixed prop name case sensitivity problem; fixed properties tooltip; accept class names; added display of class interfaces & static fields
% 2008-01-25: Fixes for many edge-cases
% 2007-12-08: First version posted on <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&mfx=1&objectId=1096533#">MathWorks File Exchange</a>
%
% See also:
% ishandle, iscom, inspect, methodsview, FindJObj (on the File Exchange)
% License to use and modify this code is granted freely to all interested, 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 by Yair M. Altman: altmany(at)gmail.com
% $Revision: 1.3 $ $Date: 2009/03/05 04:03:12 $
try
% Arg check
error(nargchk(1,1,nargin));
if ~ischar(obj) && ~ishandle(obj)
myError('YMA:uiinspect:notAHandle','Input to uiinspect must be a valid object as defined by ISHANDLE');
elseif ~ischar(obj) && numel(obj) ~= 1
myError('YMA:uiinspect:notASingleton','Input to uiinspect must be a single object handle');
end
% Get object data
objMethods = getObjMethods(obj);
objProps = getObjProps(obj);
objCallbacks = getObjCallbacks(obj);
objChildren = getObjChildren(obj);
% Display object data
fig = displayObj(obj, objMethods, objProps, objCallbacks, objChildren, inputname(1));
if nargout, hFig = fig; 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
% }
%% Internal error processing
function myError(id,msg)
v = version;
if (v(1) >= '7')
error(id,msg);
else
% Old Matlab versions do not have the error(id,msg) syntax...
error(msg);
end
%end % myError %#ok for Matlab 6 compatibility
%% Get object data - methods
function objMethods = getObjMethods(obj)
% The following was taken from Matlab's methodsview.m function
if ischar(obj)
qcls = obj; % Yair
else
qcls = builtin('class', obj);
end
[m,d] = methods(obj,'-full');
dflag = 1;
ncols = 6;
if isempty(d),
dflag = 0;
d = cell(size(m,1), ncols);
for i=1:size(m,1),
t = find(m{i}=='%',1,'last');
if ~isempty(t),
d{i,3} = m{i}(1:t-2);
d{i,6} = m{i}(t+17:end);
else
d{i,3} = m{i};
end;
end;
end;
r = size(m,1);
t = d(:,4);
d(:,4:ncols-1) = d(:,5:ncols);
d(:,ncols) = t;
[y,x] = sort(d(:,3));%#ok
cls = '';
clss = 0;
w = num2cell(zeros(1,ncols));
for i=1:r,
if isempty(cls) && ~isempty(d{i,6}),
t = find(d{i,6}=='.', 1, 'last');
if ~isempty(t),
if strcmp(d{i,3},d{i,6}(t+1:end)),
cls = d{i,6};
clss = length(cls);
end;
end;
end;
for j=1:ncols
if isnumeric(d{i,j}),
d{i,j} = '';
end;
if j==4 && strcmp(d{i,j},'()'),
d{i,j} = '( )';
else
if j==6,
d{i,6} = deblank(d{i,6});
if clss > 0 && ...
(strncmp(d{i,6},qcls,length(qcls)) || ... %Yair
(strncmp(d{i,6},cls,clss) &&...
(length(d{i,6}) == clss ||...
(length(d{i,6}) > clss && d{i,6}(clss+1) == '.'))))
d{i,6} = '';
else
if ~isempty(d{i,6}),
t = find(d{i,6}=='.', 1, 'last');
if ~isempty(t),
d{i,6} = d{i,6}(1:t-1);
end;
end
end;
end;
end;
end;
end;
if ~dflag,
for i=1:r,
d{i,6} = d{i,5};
d{i,5} = '';
end;
end;
datacol = zeros(1, ncols);
for i=1:r,
for j=1:ncols
if ~isempty(d{i,j}),
datacol(j) = 1;
w{j} = max(w{j},length(d{i,j}));
end;
end;
end;
% Determine the relevant column headers (& widths)
ch = {};
hdrs = {'Qualifiers', 'Return Type', 'Name', 'Arguments', 'Other', 'Inherited From'};
for i=ncols:-1:1,
if datacol(i),
datacol(i) = sum(datacol(1:i));
ch{datacol(i)} = hdrs{i}; %#ok
w{i} = max([length(ch{datacol(i)}),w{i}]);
end;
end;
if isempty(ch)
ch = ' ';
d = {'(no methods)'};
w = {100};
x = 1;
datacol = 1;
end
% Return the data
objMethods.headers = ch;
objMethods.methods = d(:,find(datacol)); %#ok for ML6 compatibility
objMethods.widths = [w{find(datacol)}]; %#ok for ML6 compatibility
objMethods.sortIdx = x;
%end % getObjMethods
%% Get object data - properties
function objProps = getObjProps(obj)
objProps = obj; %TODO - merge with getPropsData() below
%end % getObjProps
%% Get object data - callbacks
function objCallbacks = getObjCallbacks(obj)
objCallbacks = obj; %TODO - merge with getCbsData() below
%end % getObjCallbacks
%% Get object data - children
function objChildren = getObjChildren(obj)
objChildren = obj; %TODO - merge with getPropsData() below
%end % getObjChildren
%% Display object data
function hFig = displayObj(obj, objMethods, objProps, objCallbacks, objChildren, objName)
% Prepare the data panes
methodsPane = getMethodsPane(objMethods, obj);
[callbacksPanel, cbTable] = getCbsPane(objCallbacks, false);
[propsPane, inspectorTable] = getPropsPane(objProps);
childrenPane = getChildrenPane(objChildren, inspectorTable);
% Prepare the top-bottom JSplitPanes
import java.awt.* javax.swing.*
rightPanel = JSplitPane(JSplitPane.VERTICAL_SPLIT, propsPane, childrenPane);
leftPanel = JSplitPane(JSplitPane.VERTICAL_SPLIT, methodsPane, callbacksPanel);
set(rightPanel, 'OneTouchExpandable','on', 'ContinuousLayout','on', 'ResizeWeight',0.8);
set(leftPanel, 'OneTouchExpandable','on', 'ContinuousLayout','on', 'ResizeWeight',0.7);
% Prepare the left-right JSplitPane
hsplitPane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
set(hsplitPane,'OneTouchExpandable','on','ContinuousLayout','on','ResizeWeight',0.6);
% Display on-screen
globalPanel = JPanel(BorderLayout);
globalPanel.add(hsplitPane, BorderLayout.CENTER);
hFig = figure;
if isempty(objName), objName = 'object'; end
if ischar(obj)
className = obj;
else
className = builtin('class', obj);
end
title = ['uiinspect: ' objName ' of class ' className];
set(hFig, 'Name',title, 'NumberTitle','off', 'units','pixel', 'toolbar','none');
pos = get(hFig,'position');
[obj, hcontainer] = javacomponent(globalPanel, [0,0,pos(3:4)], hFig);
set(hcontainer,'units','normalized');
drawnow;
% this only works after the JSplitPane is displayed...
hDivPos = 0.6;
if length(objMethods.widths) < 3
hDivPos = 0.4;
end
hsplitPane.setDividerLocation(hDivPos);
vDivPos = 0.8; try vDivPos = max(0.2,min(vDivPos,inspectorTable.getRowCount/10)); catch end
rightPanel.setDividerLocation(vDivPos);
vDivPos = max(0.8, 1-cbTable.getRowCount/10);
try vDivPos = max(0.3,min(vDivPos,length(objMethods.methods)/10)); catch end
leftPanel.setDividerLocation(vDivPos);
%restoreDbstopError(identifiers);
return; % debugable point
%end % displayObj
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -