我在使用matlab句柄类时面临一个奇怪的问题,在执行某些回调时类的状态不是预期的。
为了显示问题,我过度简化了我的课程定义。这个类的基本思想是在设置之上创建一个用户界面,可以通过代码或用户交互来修改。
问题是我使用 java 组合框会激活已更改的事件,从代码或用户交互中修改选定的索引...好的...非常简单的解决方法我想,因此我决定在我的类中添加一个lockJavaEvent
属性,以便知道是否从代码或用户交互中触发了更改的事件:
% Callback to listen to combo changed events
set(this.jcbFilterType, 'ActionPerformedCallback', @(s, e)this.onFilterTypeChanged(e));
% Code to refresh interface from code
function [] = refreshGuiFromCode(this)
%[
this.lockJavaEvents = this.lockJavaEvents + 1;
this.jcbFilterType.setSelectedIndex(this.filterTypeIndex - 1);
this.lockJavaEvents = this.lockJavaEvents - 1;
%]
end
% Code to respond to combox changed with quick exist in case it is changed from code
function [] = onFilterTypeChanged(this, e)
%[
% Quick exit for events locked
if (this.lockJavaEvents > 0),
disp('Skipping combobox event because we are refreshing from code');
return;
end
...
%]
end
不幸的是,这根本不起作用!调用refreshGuiFromCode
时:
this.lockJavaEvent
增加到1 onFilterTypeChanged
被称为onFilterTypeChanged
回调中this.lockJavaEvent
的值仍然等于零????? !!!! 我显然不明白这里发生了什么?为什么this
对象似乎是旧副本,而我的类被定义为句柄类?
以下是我完整的测试代码:
classdef BugLockJava < hgsetget
%[
methods
function [this] = BugLockJava()
%[
this.lockJavaEvents = 0;
this.filterTypeIndex = 2;
this.buildGui();
this.refreshGuiFromCode();
%]
end
function [] = delete(this)
%[
delete(this.parent);
%]
end
end
methods(Access = private)
function [] = buildGui(this)
%[
this.parent = figure();
this.jcbFilterType = this.addJavaComboBox();
this.jcbFilterType.setModel(javax.swing.DefaultComboBoxModel({'Sphere', 'Cylinder', 'Power', 'N&M'}));
this.jcbFilterType.setEditable(false);
set(this.jcbFilterType, 'ActionPerformedCallback', @(s, e)this.onFilterTypeChanged(e));
%]
end
function [jComponent, hComponent, hContainer] = addJavaComboBox(this)
%[
% Create a matlab container to hold it
% NB: Required for uix, uiextras parents (GUILayout toolbox)
hContainer = uicontainer('Parent', this.parent);
position = getpixelposition(hContainer); position(1) = 0; position(2) = 0;
% Link java component with visual tree in matlab
[jComponent, hComponent] = javacomponent(javaObjectEDT('javax.swing.JComboBox'), position, hContainer);
set(hComponent, 'Units', 'normalized');
% Turns java naked reference into a matlab component
% http://undocumentedmatlab.com/blog/uicontrol-callbacks
jComponent = handle(jComponent, 'CallbackProperties');
%]
end
function [] = refreshGuiFromCode(this)
%[
this.lockJavaEvents = this.lockJavaEvents + 1;
this.jcbFilterType.setSelectedIndex(this.filterTypeIndex - 1);
this.lockJavaEvents = this.lockJavaEvents - 1;
%]
end
function [] = onFilterTypeChanged(this, e)
%[
% Quick exit for events locked
if (this.lockJavaEvents > 0),
disp('Skipping combobox event because we are refreshing from code');
return;
end
% Quick exist for action unknown
cmd = char(e.getActionCommand());
if (~strcmpi(cmd, 'comboBoxChanged')),
disp('Skipping combobox event because we don''t care');
return;
end
disp('Ok combobox changed from user interaction');
this.filterTypeIndex = this.jcbFilterType.getSelectedIndex() + 1;
%]
end
end
properties %%% Keeping public for debugging values (Access = private)
parent;
jcbFilterType;
lockJavaEvents;
filterTypeIndex;
end
%]
end