如何获得';图';a';控制';添加了';javacomponent';常规
背景 单击MatlabGUI中的某个按钮后显示如何获得';图';a';控制';添加了';javacomponent';常规,java,matlab,user-interface,Java,Matlab,User Interface,背景 单击MatlabGUI中的某个按钮后显示msgbox时,对话框总是神奇地出现在保存单击按钮的图形顶部。。。这与图形的位置无关,即使未向msgbox调用传递对此图形的引用 好吧,看看msgbox的代码,这不仅仅是魔术。实际上,在代码中有一个调用,它返回回调正在执行的控件和包含该控件的图(通过调用figure类型) 问题 当使用javacomponent例程添加自定义控件时,只要使用uicontrol例程添加控件,gcbo机制工作良好, GCBO < /代码>机制找不到图形,而 MSGBOS显
msgbox
时,对话框总是神奇地出现在保存单击按钮的图形顶部。。。这与图形的位置无关,即使未向msgbox
调用传递对此图形的引用
好吧,看看msgbox
的代码,这不仅仅是魔术。实际上,在代码中有一个调用,它返回回调正在执行的控件和包含该控件的图(通过调用figure类型)
问题
当使用javacomponent
例程添加自定义控件时,只要使用uicontrol
例程添加控件,gcbo
机制工作良好,<代码> GCBO < /代码>机制找不到图形,而function [] = gcboDemo()
%[
% Create figure
fig = figure('Name', 'Hello', 'units', 'normalized', 'Position', [1/5, 0.5, 1/5, 1/5]);
% Add standard matlab button
matlabBtn = uicontrol('Parent', fig, 'units', 'normalized', 'Position', [1/5, 0.5, 1/5, 1/5], 'String', 'Matlab');
set(matlabBtn, 'Callback', @(sender, args)onBtnClicked())
% Add java button
[javaBtn, jContainer] = javacomponent('javax.swing.JButton', [0 0 1 1], fig);
set(jContainer, 'units', 'normalized', 'position', [3/5, 0.5, 1/5, 1/5]);
javaBtn.setText('Java');
set(javaBtn, 'ActionPerformedCallback', @(sender, args)onBtnClicked())
%]
end
function [] = onBtnClicked()
%[
% This is what 'msgbox' is doing to find nice position for where to draw on screen
% 1) It looks for control intiating the callback and the figure containing it
% 2) It changes 'msgbox' position so it will appear over the figure
% NB: If no figure is found, 'msgbox' appear in middle of the screen
[controlOriginatingCallback, figureContainingObjectOriginatingCallback] = gcbo();
if (~isempty(figureContainingObjectOriginatingCallback))
msg = sprintf('Control = `%s` in Figure = `%s`', class(controlOriginatingCallback), get(figureContainingObjectOriginatingCallback, 'Name'));
else
msg = sprintf('Control = `%s` in Figure = `???`', class(controlOriginatingCallback));
end
uiwait(msgbox(msg, 'modal'));
%]
end
问题
我喜欢gcbo
的行为,并希望为我用javacomponent
添加的控件复制它(不仅是为msgbox
而且为我自己创建的自定义对话框)
有没有一种简单的方法可以让我返回对图的引用,该图包含添加了javacomponent
的控件
NB1:目前我可以通过ctrl=get(0,'CallbackObject')
获取其回调正在执行的对象,我可以通过ctrl.getParent()
访问该图,但返回的引用是java对象,我不知道如何在Matlab世界中获取对等引用
NB2:我知道我可以使用[jControl,hContainer]=javacomponent(…)
语法并将hContainer
传递给回调iin,以便跟踪对包含图的引用
,但我更愿意保留与gcbo
类似的机制(例如,覆盖gcbo
的实现,并让所有例程使用它来处理javacomponent
对象)。经过几次尝试,我找到了一个解决方案:
- 我使用
thisFigure=get(control,'topLevelAgentor')
- 我临时逐个修改maltab图形句柄的
Name
属性,直到thisfigure.getTitle()
与我设置的临时名称匹配
注意:最好更改java端标题
并使用findobj
查找matlab端名称
,但更改java端不会更新matlab端(反之亦然,所以…)
以下是覆盖的代码:
%
% PURPOSE:
%
% Gets handle to current callback control and
% handle to the figure containing that control.
%
% SYNTAX:
%
% [control] = gcboex();
% [control, fig] = gcboex();
%
% DESCRIPTION:
%
% Works exactly the same way as native `gcbo` routine except
% that it is also working for controls created with `javacomponent`.
%
%% ---
function [control, fig] = gcboex()
%[
% Obtain graphical element whose callback is executing
control = get(0, 'CallbackObject');
% Case not executing from callback on a graphical element
if (isempty(control) || ~(ishghandle(control) || ishandle(control)))
control = [];
fig = [];
return;
end
% Obtain the figure containing the graphical element
if (isempty(strfind(class(control), 'javahandle_withcallbacks')))
fig = ancestor(control, 'figure'); % Do the same as native `gcbo` routine
else
try
% Obtain the containing figure as a java handle
thisFigure = get(control, 'TopLevelAncestor');
if (isempty(strfind(class(thisFigure), 'FigureFrameProxy'))), error('Not inside a figure'); end
% Obtain all figures as matlab handles
allFigures = findobj(0, 'Type', 'figure');
% Temporarly modify figure names one by one and check
% from the java side that this our title that has changed
%
% NB: Would be easier to do modify java-side title or ToolTipString
% and use 'findobj' but when we modify java-side the changes are not
% reported on matlab side even with forceGuiUpdate, so we do the reverse (which is working) ...
fig = [];
searchedName = char(java.util.UUID.randomUUID);
for fi = 1:length(allFigures)
currentFig = allFigures(fi);
oldName = get(currentFig, 'Name');
set(currentFig, 'Name', searchedName); forceGuiUpdate();
if (strfind(char(thisFigure.getTitle()), searchedName))
fig = currentFig;
end
set(currentFig, 'Name', oldName); forceGuiUpdate();
if (~isempty(fig)), break; end
end
catch
fig = [];
end
end
%]
end
function [] = forceGuiUpdate()
%[
try
drawnow nocallbacks;
catch
drawnow; % Force update (not sure 'nocallbacks' option was introduced very recently ...)
end
%]
end
以下是带有gcboex
补丁的完整示例代码:
function [] = gcboDemo()
%[
% Create figure
fig = figure('Name', 'Hello', 'units', 'normalized', 'Position', [1/5, 0.5, 1/5, 1/5]);
% Add check box
cb =uicontrol('Parent', fig, 'Style', 'Checkbox', 'units', 'normalized', 'Position', [1/5, 4/5, 1/3, 1/5], 'String', 'Use modified gcbo');
% Add standard matlab button
matlabBtn = uicontrol('Parent', fig, 'units', 'normalized', 'Position', [1/5, 0.5, 1/5, 1/5], 'String', 'Matlab');
set(matlabBtn, 'Callback', @(sender, args)onBtnClicked(cb))
% Add java button
[javaBtn, jContainer] = javacomponent('javax.swing.JButton', [0 0 1 1], fig);
set(jContainer, 'units', 'normalized', 'position', [3/5, 0.5, 1/5, 1/5]);
set(jContainer, 'Tag', char(java.util.UUID.randomUUID));
javaBtn.setText('Java');
set(javaBtn, 'ActionPerformedCallback', @(sender, args)onBtnClicked(cb))
%]
end
function [] = onBtnClicked(cb)
%[
% Check if using 'gcboex'
useGcboex = (get(cb, 'Value') ~= 0);
if (useGcboex)
[controlOriginatingCallback, figureContainingObjectOriginatingCallback] = gcboex();
else
[controlOriginatingCallback, figureContainingObjectOriginatingCallback] = gcbo();
end
if (~isempty(figureContainingObjectOriginatingCallback))
msg = sprintf('Control = `%s` in Figure = `%s`', class(controlOriginatingCallback), get(figureContainingObjectOriginatingCallback, 'Name'));
else
msg = sprintf('Control = `%s` in Figure = `???`', class(controlOriginatingCallback));
end
b = msgbox(msg, 'modal');
if (useGcboex)
moveguiex(b, 'Over', figureContainingObjectOriginatingCallback);
end
uiwait(b);
%]
end
%% ----
function [control, fig] = gcboex()
%[
% Obtain graphical element whose callback is executing
control = get(0, 'CallbackObject');
% Case not executing from callback on a graphical element
if (isempty(control) || ~(ishghandle(control) || ishandle(control)))
control = [];
fig = [];
return;
end
% Obtain the figure containing the graphical element
if (isempty(strfind(class(control), 'javahandle_withcallbacks')))
fig = ancestor(control, 'figure'); % Do the same as native `gcbo` routine
else
try
% Obtain the containing figure as a java handle
thisFigure = get(control, 'TopLevelAncestor');
if (isempty(strfind(class(thisFigure), 'FigureFrameProxy'))), error('Not inside a figure'); end
% Obtain all figures as matlab handles
allFigures = findobj(0, 'Type', 'figure');
% Temporarly modify figure names one by one and check
% from the java side that this our title that has changed
%
% NB: Would be easier to do modify java-side title or ToolTipString
% and use 'findobj' but when we modify java-side the changes are not
% reported on matlab side even with forceGuiUpdate, so we do the reverse (which is working) ...
fig = [];
searchedName = char(java.util.UUID.randomUUID);
for fi = 1:length(allFigures)
currentFig = allFigures(fi);
oldName = get(currentFig, 'Name');
set(currentFig, 'Name', searchedName); forceGuiUpdate();
if (strfind(char(thisFigure.getTitle()), searchedName))
fig = currentFig;
end
set(currentFig, 'Name', oldName); forceGuiUpdate();
if (~isempty(fig)), break; end
end
catch
fig = [];
end
end
%]
end
function [] = forceGuiUpdate()
%[
try
drawnow nocallbacks;
catch
drawnow; % Force update (not sure 'nocallbacks' option was introduced very recently ...)
end
%]
end
%% ---
function [] = moveguiex(h, positionDescription, varargin)
%[
% Check arguments
if (nargin < 2), error('Not enough input arguments.'); end
if (~ischar(positionDescription)), error('Invalid position identifier.'); end
if (~ishandle(h)), error('Invalid graphic handle.'); end
% 'CenterOf'
if (strcmpi(strtrim(positionDescription), 'CenterOf') || ...
strcmpi(strtrim(positionDescription), 'Over'))
% Additional checks
if (nargin < 3), error('Not enough input arguments.'); end
if (nargin ~= 3), error('Too many input arguments.'); end
p = varargin{1}; if (~ishandle(p)), error('Invalid graphic handle.'); end
% Work
if (isempty(p))
pp = get(0,'screensize'); pl = pp(1); pb = pp(2); pw = pp(3); ph = pp(4);
else
pp = getpixelposition(p); pl = pp(1); pb = pp(2); pw = pp(3); ph = pp(4);
end
tp = getpixelposition(h); tw = tp(3); th = tp(4);
switch(lower(strtrim(positionDescription)))
case 'centerof',
tl = pl + (1/2)*(pw - tw);
tb = pb + (1/2)*(ph - th);
case 'over',
tl = pl + (1/2)*(pw - tw);
tb = pb + (2/3)*(ph - th);
otherwise,
error('Out of range');
end
setpixelposition(h, [tl tb tw th]);
% End
return;
end
% Oops
error('Position = `%s` is not supported', positionDescription);
%]
end
function[]=gcboDemo()
%[
%塑造形象
图=图(‘名称’、‘你好’、‘单位’、‘标准化’、‘位置’、[1/5,0.5,1/5,1/5]);
%添加复选框
cb=uicontrol('Parent',fig',Style','Checkbox','units','normalized','Position',[1/5,4/5,1/3,1/5],'String','Use modified gcbo');
%添加标准matlab按钮
matlabBtn=uicontrol('Parent',fig','units','normalized','Position',[1/5,0.5,1/5,1/5],'String','Matlab');
在BTNClicked(cb)上设置(matlabBtn,'回调',@(发送方,参数)
%添加java按钮
[javaBtn,jContainer]=javacomponent('javax.swing.JButton',[0 0 1 1],图);
集合(jContainer,'units','normalized','position',[3/5,0.5,1/5,1/5]);
set(jContainer,'Tag',char(java.util.UUID.randomUUID));
setText('Java');
设置(javaBtn,'ActionPerformedCallback',@(发送方,参数)onBtnClicked(cb))
%]
结束
函数[]=onBtnClicked(cb)
%[
%检查是否使用“gcboex”
useGcboex=(get(cb,'Value')~=0);
如果(使用GCBOEX)
[controlOriginatingCallback,FigureContainingObjectorigingCallback]=gcboex();
其他的
[controlOriginatingCallback,FigureContainingObjectorigingCallback]=gcbo();
结束
if(~isempty(图中包含ObjectorigingCallback))
msg=sprintf('Control=`s`in Figure=`s`',class(controloriginingcallback),get(figureContainingObjectoriginingCallback,'Name');
其他的
msg=sprintf('Control=`%s`在图中=`?`',类(controloriginingcallback));
结束
b=msgbox(msg,‘模态’);
如果(使用GCBOEX)
moveguiex(b,“结束”,FigureContainingObjectorigingCallback);
结束
uiwait(b);
%]
结束
%% ----
函数[控制,图]=gcboex()
%[
%获取其回调正在执行的图形元素
control=get(0,'CallbackObject');
%不从图形元素上的回调执行大小写
如果(isempty(控制)| | ~(ishghandle(控制)| | ishandle(控制)))
控制=[];
图=[];
返回;
结束
%获取包含图形元素的图形
if(isempty(strfind(类(控件),'javahandle_with callbacks'))
fig=祖先(控制,'figure');%执行与本机'gcbo'例程相同的操作
其他的
尝试
%获取包含的图形作为java句柄
thisFigure=get(控件“TopLevelAgentor”);
if(isempty(strfind(class(thisFigure),'figureFlameProxy'))),error('notinthefigure');end
%获取所有图形作为matlab句柄
allFigures=findobj(0,'类型','图形');
%逐个临时修改地物名称并选中
%从java的角度来看,这是我们的标题已经改变了
%
%注意:修改java端标题或ToolTipString会更容易
%并使用'findobj',但当我们修改java端时,更改不会发生
%在matlab端报告,即使使用forceGuiUpdate,我们也会执行相反的操作(正在工作)。。。
图=[];
searchedName=char(java.util.UUID.randomUUID);
对于fi=1:长度(所有数字)