【发布时间】:2013-10-14 03:48:00
【问题描述】:
感谢 Yair Altman 在undocumentedmatlab.com 上出色的post,我尝试使用丰富的编辑框和底层的java 组件来实现一个GUI 日志程序。这是代码的简化版本:
首先是创建面板的代码
function jEditbox = logPanel()
hFig = figure('color', 'w');
hPanel = uipanel(hFig);
% Prepare the log editbox
hLogPanel = uicontrol('style', 'edit', 'max', 5, 'Parent', hPanel, ...
'Units', 'normalized', 'Position', [0, 0.2, 1, 0.8], 'Background', 'w');
% Get the underlying Java editbox, which is contained within a scroll-panel
jScrollPanel = findjobj(hLogPanel);
try
jScrollPanel.setVerticalScrollBarPolicy(jScrollPanel.java.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPanel = jScrollPanel.getViewport();
catch %#ok<CTCH>
% may possibly already be the viewport, depending on release/platform etc.
end
jEditbox = handle(jScrollPanel.getView, 'CallbackProperties');
% Prevent user editing in the log-panel
jEditbox.setEditable(false);
% Set-up a Matlab callback function to handle hyperlink clicks
set(jEditbox,'HyperlinkUpdateCallback',@linkCallbackFcn);
% Ensure we have an HTML-ready editbox
HTMLclassname = 'javax.swing.text.html.HTMLEditorKit';
if ~isa(jEditbox.getEditorKit, HTMLclassname)
jEditbox.setContentType('text/html');
end
end
然后是日志记录代码:
function logMessage(jEditbox, text)
% newText = [iconTxt, msgTxt ' '];
text = [text '<br/>'];
% Place the HTML message segment at the bottom of the editbox
currentHTML = char(jEditbox.getText);
newHTML = strrep(currentHTML, '</body>', text);
jEditbox.setText(newHTML);
endPosition = jEditbox.getDocument.getLength;
jEditbox.setCaretPosition(endPosition);
end
我有两个问题:
-
在需要大量记录消息(即 > 500 条)的应用程序中存在重大性能问题。使用分析器和以下代码(请注意,我已修改
why以返回字符串而不是打印到命令行),我发现瓶颈在于setText()。谁能解释图中的尖峰是什么?h = logPanel(); n = 1e3; time = nan(n, 1); profile on for i = 1:n tic logMessage(h, why) time(i) = toc; end profile viewer avgTime = mean(time); figure('color', 'w') bar(time) hold on plot([0, n], avgTime*ones(1, 2), '-k', 'LineWidth', 2) hold off title(sprintf('Average Time = %f [s]', avgTime));如果我在
toc之后添加pause(0.1),则图表如下所示这是怎么回事?
这会导致非常“华丽”的日志面板。每次我写一条消息时,内容都会闪烁,因为它滚动到顶部然后又回到底部。同样,此缺陷是由于
setText()造成的,它强制插入符号位于文档的开头。
我正在寻找这些问题中的任何一个的解决方案,最好同时解决。
【问题讨论】:
-
在我的 OSX 10.8 和 R2012b 上,平均时间在 4 到 16 毫秒之间,没有
pause(0.1) -
看来R2013b在这个部门的效率不如R2012b。我在 2012b 上试过这个,得到了和你相似的结果。尝试使用更大的
n(例如,5000)运行基准测试。我的速度仍然很慢。 -
我不知道
getText()有什么问题成为瓶颈,但我想在toc之后或tic之前放置一个drawnow你会看到类似的变化。如果我的直觉是正确的,那么差异是因为事件队列(可能是图形对象)在jEditbox方法之一(可能是getText)上被刷新。
标签: java matlab user-interface