如何获取活动对象 MATLAB GUI 的句柄

How to get handle to active object MATLAB GUI

我正在尝试使用 MATLAB GUI 创建日历。 我有两个 Edit Text 对象 - edittext1edittext2.

我想做这个: 我将光标放在日历的 edittext1 然后 select 日期,它进入 edittext1 的文本字段。 edittext2 也是如此:如果我将光标放入 edittext2 和 select 日期,它将放入 edittext2 编辑文本。

我知道我可以通过这种方式使用日历回调。

问题:

如何将回调函数处理程序放入 ACTIVE 编辑文本对象? 如何获取光标所在位置的对象句柄?

关于 focus 的问题,点击 java 日历上的日期时没有 active 文本框,因为此时 active 组件 java 日历。

要知道哪个文本框最后处于活动状态,您只需跟踪它即可。一种方法是向编辑框添加回调,这将使用最新活动文本框的句柄更新变量(存储在 appdata 中)。

有了它,日历的回调将只检索日期,然后将其放入上次活动 文本框。

注意:如果文本框 'enable' 属性,文本框的 ButtonDownFcn 事件只会在左侧 右键单击​​时触发是 'off''inactive'。 (如果是'on',则只检测右键)。这就是我将文本框声明为 inactive 的原因。这不会阻止您以编程方式更新文本,所以我认为这不是问题。


testcalendar.m的代码:

function testcalendar
handles.f = figure;

commonEditProperties = {'Style', 'edit', 'String', '', ...
    'Units', 'Normalized', ...
    'Enable','inactive' , ...
    'callback',@EditBoxFcn , ...
    'ButtonDownFcn',@EditBoxFcn } ;

handles.ledit = uicontrol( commonEditProperties{:}, 'Position', [0.1 0.1 0.3 0.1], 'Tag','ledit'  );
handles.redit = uicontrol( commonEditProperties{:}, 'Position', [0.5 0.1 0.3 0.1], 'Tag','redit' );

% preallocate a variable to hold the active text box handle
setappdata(handles.f,'activeTextBox',[]) ;

com.mathworks.mwswing.MJUtilities.initJIDE;
% Put calendar to my figure
handles.jPanel = com.jidesoft.combobox.DateChooserPanel;
[handles.hPanel,handles.hContainer] = javacomponent(handles.jPanel,[100,100,200,200], handles.f);

juiFunHandle = handle(handles.jPanel, 'CallbackProperties');
set(juiFunHandle, 'MousePressedCallback', ...
   @(src, evnt)CellSelectionCallback(src, evnt, handles));
set(juiFunHandle, 'KeyPressedCallback', ...
   @(src, evnt)CellSelectionCallback(src, evnt, handles));

% store gui handles in application data
guidata(handles.f , handles)
end

function EditBoxFcn(hobj,~)
    handles = guidata(hobj) ;
    ActiveTextBox = get(hobj,'Tag') ;
    setappdata( handles.f , 'activeTextBox', handles.(ActiveTextBox) ) ;
end

function CellSelectionCallback(~, ~, handles)

    % retrieve the handle of the active text box
    ActiveTextBox = getappdata(handles.f,'activeTextBox') ;

    % assign a default active text box if none was selected before
    if isempty(ActiveTextBox) ; ActiveTextBox = handles.ledit ; end

    numRetry = 10 ;
    for k=1:numRetry
        pause(0.1)
        dateString = char( javaMethodEDT('getSelectedDate', handles.jPanel) ) ;
        if ~isempty(dateString) ; break ; end
    end

    set(ActiveTextBox , 'String' , dateString ) ;
end

查看实际效果:


编辑

没有纯 Matlab 方法可以让您的 Matlab 编辑框完全可编辑 对单击任何鼠标按钮做出反应(触发事件)。
您可以通过使用 java 对象下面的文本框来获得此功能。这个 java 对象暴露了很多事件,你可以选择你需要的一个。

收获:
要获取底层 java 对象的句柄,您需要使用 Yair Altman 的全能 findjobj 实用程序。您可以从此处的文件交换下载最新版本:findjobj

一旦将其保存在 Matlab 路径中,只需将上面示例中定义编辑框的第一行代码替换为:

commonEditProperties = {'Style', 'edit', 'String', '', 'Units', 'Normalized', 'Enable','on' } ;

handles.ledit = uicontrol( commonEditProperties{:}, 'Position', [0.1 0.1 0.3 0.1] );
handles.redit = uicontrol( commonEditProperties{:}, 'Position', [0.5 0.1 0.3 0.1] );
% preallocate a variable to hold the active text box handle
setappdata(handles.f,'activeTextBox',[]) ;

% Find the java underlying object for the text boxes
ledit = findjobj(handles.ledit) ;
redit = findjobj(handles.redit) ;
% assign a callback to the java object (which CAN detect single click)
set(ledit,'MouseClickedCallback',@(h,e) setappdata( handles.f , 'activeTextBox', handles.ledit ) ) ;
set(redit,'MouseClickedCallback',@(h,e) setappdata( handles.f , 'activeTextBox', handles.redit ) ) ;

并且您可以完全注释或删除子功能EditBoxFcn,因为回调操作是直接完成的。