Java DocumentListener减慢Document.setCharacterAttributes方法的速度?

Java DocumentListener减慢Document.setCharacterAttributes方法的速度?,java,swing,jtextpane,documentlistener,Java,Swing,Jtextpane,Documentlistener,这是我在这个网站上的第一个问题,虽然这不是我第一次进入这个网站来澄清我的疑问,这是一个很棒的网页 我正在编写一个java程序,突出显示JTextPane中的代码,并改变突出显示的方式。我使用JTabbedPane让用户可以同时编辑多个文件,并且我曾经使用计时器执行文档高亮显示,现在我构建了一个高亮显示队列,在单独的线程中运行,并实现了一个DocumentListener,在发生更改时对文档进行排队 但是我有一个很大的问题,如果我通过DocumentListener添加文档,突出显示过程会花费很长

这是我在这个网站上的第一个问题,虽然这不是我第一次进入这个网站来澄清我的疑问,这是一个很棒的网页

我正在编写一个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();
    }
}
注意:Highlight/Engine.addDocument()方法有五个参数:(StyledDocument doc、int start、int end、String tabTitle、String docText)。“开始”和“结束”都表示需要高亮显示的区域

我将感谢任何与此问题相关的帮助,因为我已经尝试解决它几天了,但在互联网上找不到任何类似的帮助(


顺便说一句,有人知道Document.setCharacterAttributes和Document.setParagraphAttributes之间的实际区别吗?:p

也许您的代码中存在某种导致问题的递归。对于DocumentEvent,您应该只关心添加和删除。您不需要担心更改,因为这些都是属性变化


可能您添加了一些文本来安排高亮显示,但是当您更改文本属性时,您会安排另一个高亮显示任务。

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

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

谢谢您的回复,但我忽略了changedUpdate方法,因为用户无法访问文本属性,所以在该方法激发时无需执行任何操作。只有在激发insertUpdate或removeUpdate时,高亮显示才会排队,并且我使用的高亮显示方法会按sett高亮显示文本重新设置文档部分的字符属性,这样该方法就不会插入更多的文本。我刚刚测试过,在执行高亮显示时插入了insertUpdate()和removeUpdate()我的猜测是,由于高亮显示是通过设置文本属性来执行的,因此每次调用Doc.setCharacterAttributes()时,文档都必须通知文档侦听器,这似乎很耗时。在执行突出显示之前,我已尝试删除文档侦听器,但由于文档的源是文档侦听器,因此在删除文档侦听器时,对该文档所做的更改不会更新。
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;
}