How to process large DefaultStyledDocument and catch a cancel event?

41 Views Asked by At

I have a JTextPane with an extended DefaultStyledDocument. Updating the document takes about 2 minutes. Currently I am breaking it up into steps and updating on the swing thread with InvokeAndWait for each step. I have a progress bar and a cancel button. The cancel button only triggers when there is a break between steps. Each step takes about 10 seconds so I need to wait up to 10 seconds to stop the processing of the document. Is there anyway to make this more responsive? I am displaying a JFrame with the JTextPane in a JScrollPane when it is done. When it is finally rendered the scroll is very responsive and I can view the whole document. I do not want to display the JFrame until the document is updated yet I want to continue to show the progress of the update. Any ideas on how to update the document and have Swing and/or the cancel button more responsive?

====== Edit in response to comments ====== In styled document using the append(text) method - setting styles for each line before appending.

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);
    }
}

======== Edit ======== This is what my document update method looks like.

 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");
}

And these methods go with the write method:

 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;
}

ALL VARIABLES are resolved before get methods

0

There are 0 best solutions below