DocumentListener是否会降低Document.setCharacterAttributes方法的速度?

时间:2011-01-05 03:51:08

标签: java swing jtextpane documentlistener

这是我在这个网站上的第一个问题,虽然这不是我第一次进入清除我的怀疑,令人敬畏的网页。 :)

我正在编写一个突出显示JTextPane中代码的java程序,我正在改变突出显示的方式。我正在使用JTabbedPane让用户同时编辑多个文件,我曾经使用Timer执行文档高亮,现在我已经构建了一个在单独的线程中运行的高亮队列,并实现了一个队列的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();
    }
}

如果我使用此方法添加带有2k行的文档,则需要~1900 ms来突出显示整个文档,而如果我使用插入符号侦听方法将文档添加到突出显示队列,则需要~500 ms。

以下是插入符号侦听方法的一部分,用于在加载时突出显示整个文档:

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 :(得分:0)

也许你的代码中有一些导致问题的递归。使用DocumentEvent,您应该只担心添加和删除。您不必担心更改,因为这些是属性更改。

也许您添加了一些用于安排突出显示的文本,但是当您更改文本的属性时,您会安排另一个高级任务。

答案 1 :(得分:0)

您可以尝试设置一个标记,指示用户是更改还是API更改。在Engine.addDocument()的开头,将标志设置为API状态,并在完成更改后将其重置。 在您的侦听器中,检查标志并跳过API中的更改。 您写了“我使用通过设置文档的一部分的字符属性来突出显示文本,因此该方法不会插入更多文本”。我不确定它是否插入文字。例如。你有“它是一个大胆的文本块”然后你选择“粗体”并将属性更改为粗体。原始元素分开,出现3个新元素。我没有测试它,但可能会调用insertUpdate()和removeUpdate()

有谁知道Document.setCharacterAttributes和Document.setParagraphAttributes之间的实际区别? 有段落和字符属性。 Char属性是字体大小,族,样式,颜色。段落属性是对齐,缩进,行间距。 实际上段落是char元素的父母。