2011-01-05 2 views
1

이것은 나의 의심, 굉장한 웹 페이지를 깨끗하게하기 위해 들어가는 처음이 아니지만이 사이트의 나의 첫번째 질문이다. :)DocumentListener가 Document.setCharacterAttributes 메서드의 속도를 느리게합니까?

JTextPane의 코드를 강조하는 자바 프로그램을 작성 중이며 하이라이트 처리 방식을 변경하고 있습니다. 저는 JTabbedPane을 사용하여 사용자가 동시에 두 개 이상의 파일을 편집 할 수있게하고 Timer를 사용하여 문서 하이라이트를 수행 했었습니다. 이제는 별도의 스레드에서 실행되는 강조 표시 대기열을 작성하고 대기열에있는 DocumentListener를 구현했습니다. 변경 사항이 문서화됩니다.

하지만 정말 큰 문제가 있습니다. 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 밀리 초 소요 캐럿 듣기 방법을 사용하여 강조 표시 대기열로 이동하는 데는 약 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; 
} 

참고 : 여기에

들이로드 할 때 전체 문서를 강조하는 데 사용되는 캐럿 청취 방법의 일부 하이라이트/Engine.addDocument() 메소드는 5 개 개의 매개 변수가 있습니다 : (인 StyledDocument의 문서 , int start, int end, String tabTitle, String docText). 시작과 끝 모두 강조 표시가 필요한 영역을 나타냅니다.

나는 며칠 동안 문제를 해결하려고 노력했기 때문에이 문제와 관련된 도움을 주실 것이며 인터넷에서 비슷한 것을 찾을 수 없습니다. :(

, BTW 사람이 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 요소의 부모입니다.

+0

방금 ​​테스트했는데 하이라이트가 수행되는 동안 insertUpdate() 및 removeUpdate()가 호출되지 않습니다. 내 생각 엔 하이라이트는 텍스트에 속성을 설정하여 수행되기 때문에 문서가 Doc.setCharacterAttributes()를 호출 할 때마다 문서 수신기에 통지해야하고 시간이 많이 걸리는 것으로 보인다. 강조 표시를 수행하기 전에 문서 수신기를 제거하려고 시도했지만 문서 원본이 문서 수신기이므로 DocListener를 제거하면 해당 문서에 대한 변경 내용이 업데이트되지 않습니다. – escabuchen

관련 문제