如何处理大型DefaultStyledDocument并捕获取消事件?

时间:2018-10-23 14:06:32

标签: java multithreading swing eventqueue

我有一个JTextPane和一个扩展的DefaultStyledDocument。更新文档大约需要2分钟。目前,我将其分解为多个步骤,并在每个步骤的InvokeAndWait上对swing线程进行更新。我有一个进度栏和一个取消按钮。取消按钮仅在步骤之间有中断时才触发。每个步骤大约需要10秒钟,因此我需要等待10秒钟才能停止处理文档。无论如何,可以使响应速度更快吗?完成后,我在JFrame中显示JTextPaneJScrollPane。最终呈现出来时,滚动响应非常灵敏,我可以查看整个文档。在文档更新之前,我不想显示JFrame,但我想继续显示更新进度。关于如何更新文档以及使Swing和/或“取消”按钮具有更快响应能力的任何想法?

======根据评论进行编辑====== 在使用append(text)方法设置样式的文档中-在附加之前为每行设置样式。

public void append(String text)
{
    append(text, textStyle, paragraphStyle);
}

public void append(String text, Style ts, Style ps)
{
    try
    {
        int start = this.getLength();
        int end = this.getLength()+text.length();
        this.insertString(start, text, ts);
        this.setParagraphAttributes(start, end, ps, true);
    }

    catch (BadLocationException e)
    {
        LOG.log(Level.SEVERE, "Bad location in append", e);
    }
}

========编辑======== 这就是我的文档更新方法。

 public void writeTextOutsideOfSwing(StatusDialog status, float statusPercentage)
  {
    final StringBuilder letter = new StringBuilder();
    final ArrayList<IndexTextEntry>list = new ArrayList<>();
    LOG.log(Level.INFO, "Updating document: {0}", entries.length);
    setText("");
    int step = (int)((status.getMaximum() * statusPercentage) / (double)entries.length);
    for(int j = 0; j < entries.length; j++)
    {
        if(status.cancel) break;
        final int index = j;

        list.add(entries[j]);
        if(list.size() == 100 || index == entries.length -1)
        {
            int first = index - list.size() + 2;
            int last = index + 1;
            status.setStatusBarText("Writing Concordance: Processing " + first + " - " + last + " of " + entries.length);
            try 
            { 
                SwingUtilities.invokeAndWait(()-> 
                {
                    for(int k = 0; k < list.size(); k++)
                    {
                        int i = index-list.size() + k;

                        if(!letter.toString().equals(list.get(k).getSortLetter()))
                        {
                            letter.setLength(0);
                            letter.append(list.get(k).getSortLetter());
                            String title = list.get(k).getSortLetterTitle(letter.toString());
                            appendLetter(title, i == 0);
                        }
                        else if(i > 0)
                        {
                            if(cf.getLineBetweenEntries()) 
                            {
                                clearTextAreaStyles();
                                setFontSize(cf.getLineBetweenEntriesFontSize());
                                append(" \n");
                            }
                        }
                        float indent = appendEntry(0, list.get(k));
                        appendSubEntries(indent, list.get(k));
                    }
                });
            } 
            catch(InterruptedException | InvocationTargetException ex) 
            { LOG.log(Level.SEVERE, "Writing Concorder Interrupted", ex); }
            list.clear();
        }
        status.increment(step);
    }
    LOG.info("Done updating docuemnt");
}

这些方法与write方法一起使用:

 private void appendSubEntries(float indent, IndexTextEntry entry)
 {
    for (IndexTextEntry subEntry : entry.getSubEntries()) 
    {
        float ind = appendEntry(indent, subEntry);
        appendSubEntries(ind, subEntry);
    }
 }

 private float appendEntry(float indent, IndexTextEntry entry)
 {

    setFontFamily(cf.getWordFormat().getFontFamily());
    setFontSize(cf.getWordFormat().getFontSize());
    setFontBold(cf.getWordFormat().getBold());
    setFontItalic(cf.getWordFormat().getItalic());
    switch (cf.getWordFormat().getAlignment()) 
    {
        case TextFormat.ALIGN_CENTER:
            setFontAlignment(EnhancedTextArea.ALIGN_CENTER);
            break;
        case TextFormat.ALIGN_RIGHT:
            setFontAlignment(EnhancedTextArea.ALIGN_RIGHT);
            break;
        default:
            setFontAlignment(EnhancedTextArea.ALIGN_LEFT);
            break;
    }
    float wi = indent + cf.getWordFormat().getIndentJAVA();
    setLeftIndent(wi);
    setFontColor(cf.getWordFormat().getColor());
    append(entry.getConcordance().getTitle());
    append("\n");

    float li = 0;
    for(ConcordanceLine line : entry.getConcordance().getLines())
        li = appendLine(wi, line);

    return li;
}

private float appendLine(float indent, ConcordanceLine line)
{
    setFontFamily(cf.getLineFormat().getFontFamily());
    setFontSize(cf.getLineFormat().getFontSize());
    switch (cf.getLineFormat().getAlignment()) 
    {
        case TextFormat.ALIGN_CENTER:
            setFontAlignment(EnhancedTextArea.ALIGN_CENTER);
            break;
        case TextFormat.ALIGN_RIGHT:
            setFontAlignment(EnhancedTextArea.ALIGN_RIGHT);
            break;
        default:
            setFontAlignment(EnhancedTextArea.ALIGN_LEFT);
            break;
    }
    float li = indent + cf.getLineFormat().getIndentJAVA();
    setLeftIndent(li);
    setFontColor(cf.getLineFormat().getColor());

    setFontBold(cf.getPageBold());
    setFontItalic(cf.getPageItalic());
    append(line.page + " ");
    setFontBold(cf.getLineBold());
    setFontItalic(cf.getLineItalic());
    append(line.lead);
    setFontBold(cf.getWordBold());
    setFontItalic(cf.getWordItalic());
    append(line.word);
    setFontBold(cf.getLineBold());
    setFontItalic(cf.getLineItalic());
    append(line.trail);
    append("\n");

    return li;
}

所有变量在获取方法之前得到解析

0 个答案:

没有答案