2011-01-05 4 views
1

это мой первый вопрос на этом сайте, хотя я не первый раз вхожу, чтобы очистить мои сомнения, потрясающую веб-страницу. :)DocumentListener замедляет метод Document.setCharacterAttributes?

Я пишу программу java, которая выделяет код в JTextPane, и я меняю то, как делаются основные моменты. Я использую JTabbedPane, чтобы позволить пользователю редактировать несколько файлов одновременно, и я использовал для выделения документов с использованием таймера, теперь я создал выделенную очередь, которая работает в отдельном потоке, и реализовала 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() имеет пять параметров: (StyledDocument документ , int start, int end, String tabTitle, String docText). Начало и конец показывают регион, в котором требуется подсветка.

Буду признателен за любую помощь, связанную с этой проблемой, потому что я пытался ее решить в течение нескольких дней, и я не могу найти ничего подобного в Интернете. :(

Btw, кто-нибудь знает фактическую разницу между Document.setCharacterAttributes и Document.setParagraphAttributes: P

ответ

0

Может быть, у вас есть какой-то рекурсии в коде, который вызывает проблемы с DocumentEvent вы должны. только беспокоитесь о дополнениях и удалениях. Вам не нужно беспокоиться об изменениях, поскольку это изменения атрибутов.

Возможно, вы добавили текст, который планирует выделение, но затем, когда вы изменяете атрибуты текста, вы планируете еще один высокий уровень громкости

+0

Спасибо за ваш ответ, но я проигнорировал метод changeUpdate, потому что у пользователя нет доступа к текстовым атрибутам, поэтому ничего не поделаешь, когда этот метод срабатывает. Основные моменты помещаются в очередь только при вставке insertUpdate или removeUpdate, а метод выделения, который я использую, выделяет текст, задавая атрибуты символа части документа, поэтому метод не вставляет больше текста. – escabuchen

0

Вы можете t ry установить флаг, указывающий, изменяется ли пользователь или изменяется ваш API. В начале Engine.addDocument() установите флаг в состояние API и сбросьте его после завершения изменений. В вашем слушателе проверьте флаг и пропустите изменения из API. Вы написали «Я использую подсветку текста, задав атрибуты символа части документа, поэтому метод не вставляет больше текста». Я не уверен, что он не вставляет текст. Например. у вас есть «это жирный текст», тогда вы выбираете «жирный» и изменяете атрибуты жирным шрифтом. Исходный элемент отделен и появляются 3 новых элемента. Я не тестировал его, но он мог бы вызвать insertUpdate() и removeUpdate()

Кто-нибудь знает фактическую разницу между Document.setCharacterAttributes и Document.setParagraphAttributes? Есть атрибуты абзаца и символа. Атрибутами Char являются размер шрифта, семья, стиль, цвета. Атрибутами абзаца являются выравнивание, отступы, межстрочный интервал. На самом деле параграфы являются родителями персонажей.

+0

Я только что протестировал и в то время, когда выполняется подсветка insertUpdate() и removeUpdate(), никогда не вызывается. Я предполагаю, что из-за того, что основные моменты выполняются путем установки атрибутов для текста, документ должен уведомлять слушателя документа каждый раз, когда я вызываю Doc.setCharacterAttributes(), и это, кажется, требует много времени. Я попытался удалить прослушиватель документов перед выполнением выделения, но поскольку источником документа является прослушиватель документов, когда я удаляю DocListener, изменения, внесенные в этот документ, не обновляются. – escabuchen

Смежные вопросы