gpt4 book ai didi

java - 提高 GUI 日志的性能

转载 作者:行者123 更新时间:2023-11-30 11:27:43 24 4
gpt4 key购买 nike

感谢Yair Altman的精彩postundocumentedmatlab.com ,我尝试使用丰富的编辑框和底层 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

我有两个问题:

  1. 需要大量记录消息(即 > 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));

    benchmark

    如果我在 toc 之后添加一个 pause(0.1),那么图表看起来像

    benchmark_pause

    这是怎么回事?

  2. 这会产生一个非常“华丽”的日志面板。每次我写一条消息时,内容会在滚动到顶部然后回到底部时闪烁。再次强调,此缺陷是由于 setText() 造成的,它强制插入符位于文档的开头。

我正在寻找解决这些问题中的任何一个的方法,最好是同时解决这两个问题。

最佳答案

当然,使用getText()String操作和setText()是一个瓶颈。您强制编辑器组件将其全部内容转换为 HTML 表示,并在更改后重新解析整个 HTML 表示。编辑器无法检测到您刚刚添加了一些文本。您的组件包含的内容越多,性能损失就越大。

如果您有一个 Swing 文本组件并想在末尾附加一些文本,您可以使用:

  1. (简单的)用于纯文本:

    textComp.setCaretPosition(textComp.getDocument().getLength());
    textComp.replaceSelection("\nMore Text");
  2. (不太难)用于内容类型中的文本,例如HTML:

    Document doc = textComp.getDocument();
    textComp.getEditorKit().read(
    new StringReader("More <i>styled</i> text"), doc, doc.getLength());

在第二种情况下,如果您想将插入符号移动到末尾,您必须像第一种情况一样添加 setCaretPosition 调用。

关于java - 提高 GUI 日志的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19227073/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com