У меня JTextPane
с расширенным DefaultStyledDocument
. Обновление документа занимает около 2 минут. В настоящее время я разбиваю его на шаги и обновляю нить качелей с InvokeAndWait
для каждого шага. У меня есть индикатор выполнения и кнопка отмены. Кнопка отмены срабатывает только при перерыве между шагами. Каждый шаг занимает около 10 секунд, поэтому мне нужно подождать до 10 секунд, чтобы остановить обработку документа. Есть ли способ сделать это более отзывчивым? Я показываю JFrame
с JTextPane
в JScrollPane
, когда это будет сделано. Когда он наконец отображается, прокрутка очень отзывчива, и я могу просмотреть весь документ. Я не хочу отображать 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");
}
И эти методы идут с методом записи:
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;
}
ВСЕ ПЕРЕМЕННЫЕ разрешаются до получения методов
..with an extended DefaultStyledDocument. Updating the document takes about 2 minutes
- Почему все так долго? Мы понятия не имеем, что вы изменили, возможно, вам следует поработать над этим процессом.with InvokeAndWait for each step.
- возможно, вам следует использовать invokeLater(). Я предполагаю, что invokeAndWait() заблокирует EDT, пока он ожидает завершения процесса. - person camickr   schedule 23.10.2018in my test case it is 10251 lines
- так что, если вы удвоите строку и экстраполируете мою подсветку синтаксиса, это будет около 7 секунд.In my current test this is about 13 times - each step varies due to the recursion needed to flow through the text
- поэтому время, затрачиваемое на вашу логику обработки, а не логику добавления подсветки. Мы не можем догадаться, что вы делаете, поэтому мы не можем предложить. - person camickr   schedule 23.10.2018SimpleAttributeSet
для группировки нескольких атрибутов. - person camickr   schedule 23.10.2018