DocumentListener замедляет метод Document.setCharacterAttributes? - PullRequest
1 голос
/ 05 января 2011

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

Я пишу 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;
}

Примечание. Метод Highlight / Engine.addDocument () имеет пять параметров: (StyledDocument doc, int start, int end, String tabTitle, String docText). Начало и конец указывают на регион, где необходимо выделение.

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

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

Ответы [ 2 ]

0 голосов
/ 05 января 2011

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

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

0 голосов
/ 05 января 2011

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

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

...