2011-01-05 6 views
1

これはこのサイトの最初の質問ですが、私の疑問を解決するために初めて入力したのではありません。すばらしいウェブページです。 :)DocumentListenerはDocument.setCharacterAttributesメソッドの速度を落としますか?

JTextPaneのコードをハイライトするJavaプログラムを作成していますが、ハイライトの処理方法を変更しています。私はJTabbedPaneを使用してユーザーが複数のファイルを同時に編集できるようにしていて、Timerを使用してドキュメントハイライトを実行していましたが、別のスレッドで実行されるハイライトキューを作成し、変更が発生したときに文書が表示されます。

しかし、私はDocumentListener経由でドキュメントを追加すると、ハイライトプロセスは本当に長い時間がかかりますが、メインクラスでドキュメントを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(); 
    } 
} 

私はこの方法で2kの線で文書を追加した場合、私は、ドキュメントを追加するとしながら、それは、文書全体を強調するために〜1900ミリ秒かかりますキャレットリスニング方法を使用してハイライトキューに約500msかかる。

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

注:ここでは

は、それらがロードされているときに文書全体を強調するために使用されているキャレットリスニング法の一部だハイライト/ Engine.addDocument()メソッドは、5つのパラメータがあります(StyledDocumentのドキュメント、int start、int end、String tabTitle、String docText)を返します。開始と終了の両方は、強調表示が必要な領域を示します。

私は数日間それを解決しようとしていたので、私はインターネット上で同様の何かを見つけることができないため、この問題に関連する助けを感謝します。 :(

ところで、誰でもDocument.setCharacterAttributesとDocument.setParagraphAttributes間の実際の違いを知っているん:?P

答えて

0

たぶん、あなたが問題を引き起こしているあなたのコード内で再帰のいくつかの種類を持っていたDocumentEventでは、あなたがしなければなりません。

ハイライトのスケジュールを設定するテキストを追加することもできますが、テキストの属性を変更すると別のハイライト表示をスケジュールすることがありますタスク。

+0

返信いただきありがとうございますが、ユーザーがテキスト属性にアクセスすることができないためchangedUpdateメソッドを無視しました。そのため、メソッドが起動すると何も実行されません。 ハイライトは、insertUpdateまたはremoveUpdateが呼び出されたときにのみキューに入れられます。ハイライト方法は、ドキュメントの一部の文字属性を設定することによってテキストを強調表示します。 – escabuchen

0

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

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

+0

私はちょうどテストし、ハイライトが実行されている間は、insertUpdate()とremoveUpdate()は決して呼び出されません。 私は、ハイライトが属性をテキストに設定することによってドキュメントがDoc.setCharacterAttributes()を呼び出すたびにドキュメントリスナーに通知しなければならず、時間がかかるようです。 ハイライトを実行する前にドキュメントリスナーを削除しようとしましたが、ドキュメントのソースがドキュメントリスナーであるため、DocListenerを削除するとそのドキュメントに対する変更は更新されません。 – escabuchen

関連する問題