Все процессоры, обновляющие мой графический интерфейс swing из мест, отличных от пользовательских кликов, выполняются с использованием EventQueue.invokeLater (например, вывод, созданный в результате длинного ходового процесса, не связанного с EDT).Наилучшая практика для работы с длительным запуском процесса setText JEditorPane
В моем текущем сценарии у меня есть процесс чтения сокетов TCPIP, который возвращает данные, которые необходимо обновить объект JEditorPane. Я использую вызов setText JEditorPane. Проблема заключается в том, что размещение вызова setText в процедуре invokeLater замораживает GUI для больших файлов (пример case case 19,790 KB).
Моя попытка разрешить это - выполнить действие setText в фоновом потоке, отличном от EDT. Это, похоже, решает проблему, НО, меня беспокоят лучшие практики, потому что JEditorPane setText в java 7 (JDK, который я использую) НЕ является потокобезопасным.
HOWEVER, проходящий через код JDK, мне кажется, что длительный процесс, выполняемый здесь, находится в JDKs DefaultEditorKit.read, и внутри этого метода единственный код, который будет влиять на графический интерфейс, находится в вызовах doc.insertString (если только я ошибаюсь). Теперь, когда вы смотрите на метод InsertString JDKs PlainDocument.java, он документирует, что это потокобезопасно, поэтому можно подумать, что это решение является надежным.
ОДНАКО ...
нагрузочного тестирования моего приложения, я несколько случайных кликов вокруг GUI, и в настоящее время есть анимация работает дерево узлов, и при большой нагрузке ниже, он появляется, чтобы замедлить анимацию немного, поэтому я обеспокоен тем, что я не выполнил наилучшее разрешение (также очень обеспокоены будущими JRE, которые меня заворачивают и поэтому не полагаются на insertString, которые в настоящее время являются потокобезопасными).
Я исследовал и увидел, что этот вопрос «как обращаться с давно запущенным JEditorPane setText» был задан раньше, но без подходящих ответов.
ВОПРОС 1) У кого-нибудь есть мысли о моих текущих наблюдениях?
ВОПРОС 2) Есть ли у кого-нибудь идеи о том, как я мог бы достичь этого?
ПРИМЕЧАНИЕ JEditorPane - мой единственный выбор здесь, потому что я буду в конечном итоге поддерживать динамические шрифты в стиле IDE.
Обратите внимание, что вызов ниже вызывается в рамках процедуры EventQueue.invokeLater, поэтому начальная работа в редакторе находится в EDT.
public void updateBigDataEditorPane(final JEditorPane editorPane, final String inStr) {
// Update editor object and content.
editorPane.setContentType("text/plain");
editorPane.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
editorPane.setDocument(editorPane.getEditorKit().createDefaultDocument());
// Content update. NOTE in non-EDT thread to stop GUI freeze with large content.
new Thread(new Runnable() {
@Override
public void run() {
//// synchronized
synchronized(tabsLock) {
// Set content.
editorPane.setText(inStr);
} //// synchronized
}
}).start();
}
Используйте SwingWorker для загрузки текста и используйте его метод, чтобы применить его ... – MadProgrammer
@MadProgrammer SwingWorker применяет тот же принцип, что и выше (и как только я установил правильность выше, я изменю его на используйте SwingWorker). То есть, setText выполняется в фоновом режиме, а не в EDT (по сути, что такое SwingWorker, правильно?), То любые действия, требуемые для EDT, выполняются в методе done. Я предполагаю, что это то, что вы имеете в виду, потому что в противном случае установка setText в методе SwingWorker будет иметь тот же эффект, что и мой исходный код проблемы - выполнение setText в EDT зависает от GUI. Мысли? –
№ SwingWoker предоставляет вам методы публикации/процесса, которые позволяют синхронизировать обновления с EDT. Дело в том, что вы можете просто использовать метод done, который также вызывается в EDT для обновления пользовательского интерфейса. Помните, что Swing, как правило, не защищен потоком. – MadProgrammer