2

undocumentedmatlab.comでの Yair Altman の優れた投稿のおかげで、豊富な編集ボックスと基礎となる 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

2 つの問題があります。

  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));
    

    基準

    pause(0.1)の後に を追加するとtoc、グラフは次のようになります

    ベンチマーク一時停止

    何が起きてる?

  2. これにより、非常に「派手な」ログ パネルが表示されます。メッセージを書くたびに、上にスクロールしてから下に戻ると、内容がちらつきます。繰り返しますが、この欠陥はsetText()、キャレットをドキュメントの先頭に強制する によるものです。

これらの問題のいずれか、できれば両方の解決策を探しています。

4

1 に答える 1