我找到了一个解决方法:在回调中,您可以先将焦点切换到虚拟元素,然后更新感兴趣的元素,最后将焦点切换回感兴趣的元素。该解决方案的缺点:文本全部突出显示。此外,该解决方案有些脆弱:出于非显而易见的原因,必须在单独的set
调用中将虚拟元素的可见性设置为“关闭”。
由于新的回调跨越了几行,它不能再被描述为一个匿名函数。这使得最小示例稍长:
function caret_stuck_hack()
figure
hedit = uicontrol('Style', 'edit', 'String', '0', 'Callback', @edit_cb);
hdummy = uicontrol('Style', 'edit', 'String', 'dummy', ...
'Position', [0, 0, 1, 1]); % Position: HAS to be non-overlapping with other edit field
hdummy.Visible = 'off'; % Don't merge with upper line! HAS to be called seperately!
function edit_cb(h, e)
uicontrol(hdummy);
h.String = num2str(rand(1));
uicontrol(h);
drawnow;
end
end
结果:
附录
您可以通过操作底层 Java Swing 对象来更改插入符号的位置。使用Yair Altman 的优秀 findjobj
功能,代码变为:
function caret_stuck_hack()
figure
hedit = uicontrol('Style', 'edit', 'String', '0', 'Callback', @edit_cb);
hdummy = uicontrol('Style', 'edit', 'String', 'dummy', ...
'Position', [0, 0, 1, 1]); % Position: HAS to be non-overlapping with other edit field
hdummy.Visible = 'off'; % Don't merge with upper line! HAS to be called seperately!
jhedit = findjobj(hedit, 'nomenu');
function edit_cb(h, e)
caret_pos = get(jhedit, 'CaretPosition');
uicontrol(hdummy);
h.String = num2str(rand(1));
uicontrol(h);
drawnow;
set(jhedit, 'CaretPosition', caret_pos)
end
end
您可以(也许应该)添加额外的代码来检查插入符索引在字符串长度更改时是否非法。但是对于这个最小的例子,结果看起来已经很不错了: