1

これはこのサイトでの最初の質問ですが、疑問を解消するために入るのは初めてではありません。すばらしい Web ページです。:)

JTextPane でコードを強調表示する Java プログラムを作成しており、強調表示の方法を変更しています。ユーザーが同時に複数のファイルを編集できるように JTabbedPane を使用しています。以前はタイマーを使用してドキュメントのハイライトを実行していましたが、別のスレッドで実行されるハイライト キューを作成し、キューに入れる DocumentListener を実装しました。変更が行われたときのドキュメント。

しかし、大きな問題があります。DocumentListener を介してドキュメントを追加すると、Highlight プロセスに非常に長い時間がかかりますが、JTextPane からドキュメントを直接取得してメイン クラスに追加すると、ほんの数ミリ秒しかかかりません。コードで複数のベンチマークを実行したところ、DocumentListener からドキュメントを追加するときに実行に非常に時間がかかるのは、Document.setCharacterAttributes() メソッドであることがわかりました。

DocumentListener を介してドキュメントを追加するメソッドは次のとおりです。

// eventType: 0 - insertUpdate / 1- removeUpdate
private void queueChange(javax.swing.event.DocumentEvent e, int eventType){
    StyledDocument doc = (StyledDocument) e.getDocument();
    int changeLength = e.getLength();
    int changeOffset = e.getOffset();
    int length = doc.getLength();
    String title = (String) doc.getProperty("title");

    String text;
    try {
        text = doc.getText(0, length);

        if (changeLength != 1) {
            Element element = doc.getDefaultRootElement();
            int startLn = element.getElement(element.getElementIndex(changeOffset)).getStartOffset();
            int endLn = element.getElement(element.getElementIndex(changeOffset + changeLength)).getEndOffset() - 1;

            Engine.addDocument(doc, startLn, endLn, title, text);
        } else {
            if(eventType == 1){
                changeOffset = changeOffset - changeLength;
            }
            int startLn = text.lastIndexOf("\n", changeOffset) + 1;
            int endLn = text.indexOf("\n", changeOffset);

            if (endLn < 0) {
                if (length != startLn) {
                    endLn = length;

                    Engine.addDocument(doc, startLn, endLn, title, text);
                }
            } else if (startLn != endLn && startLn < endLn) {
                Engine.addDocument(doc, startLn, endLn, title, text);
            }
        }
    } catch (BadLocationException ex) {
        Engine.crashEngine();
    }
}

この方法で 2,000 行のドキュメントを追加すると、ドキュメント全体を強調表示するのに約 1900 ミリ秒かかりますが、キャレット リスニング メソッドを使用してドキュメントを強調表示キューに追加すると、約 500 ミリ秒かかります。

以下は、ロード時にドキュメント全体を強調表示するために使用されるキャレット リスニング メソッドの一部です。

if (loadFile == true) {
    isKey = false;
    doc = edit[currentTab].Editor.getStyledDocument();
    try {
        Highlight.addDocument(doc, 0, doc.getLength(),
                Scripts.getTitleAt(currentTab), doc.getText(0, doc.getLength()));
    } catch (BadLocationException ex) {
        ex.printStackTrace();
    }
    loadFile = false;
}

注: Highlight/Engine.addDocument() メソッドには、5 つのパラメーター (StyledDocument doc,int start、int end、String tabTitle、String docText) があります。開始と終了は両方とも、強調表示が必要な領域を示します。

この問題に関連するヘルプをいただければ幸いです。数日間この問題を解決しようとしましたが、インターネット上で同様のものを見つけることができません。:(

ところで、Document.setCharacterAttributes と Document.setParagraphAttributes の実際の違いを知っている人はいますか? :P

4

2 に答える 2

0

ユーザーの変更なのか API の変更なのかを示すフラグを設定してみることができます。Engine.addDocument() の先頭で、フラグを API 状態に設定し、変更が完了したらリセットします。リスナーでフラグを確認し、API からの変更をスキップします。「ドキュメントの一部の文字属性を設定してテキストを強調表示するため、メソッドはそれ以上テキストを挿入しません」と書いています。テキストが挿入されないかどうかはわかりません。たとえば、「太字のテキスト ピースです」があり、「太字」を選択して、属性を太字に変更します。元の要素が分離され、3 つの新しい要素が表示されます。私はそれをテストしませんでしたが、insertUpdate() と removeUpdate() を呼び出す可能性があります

Document.setCharacterAttributes と Document.setParagraphAttributes の実際の違いを知っている人はいますか? 段落属性と文字属性があります。Char 属性は、フォント サイズ、ファミリー、スタイル、色です。段落の属性は、配置、インデント、行間隔です。実際、段落は char 要素の親です。

于 2011-01-05T08:13:09.207 に答える
0

おそらく、コードに何らかの再帰があり、それが問題を引き起こしている可能性があります。DocumentEvent を使用すると、追加と削除のみを気にする必要があります。これらは属性の変更であるため、変更について心配する必要はありません。

強調表示をスケジュールするテキストを追加するかもしれませんが、テキストの属性を変更すると、別の強調表示タスクをスケジュールします。

于 2011-01-05T06:57:03.663 に答える