사용자 클릭 이외의 다른 곳에서 내 스윙 GUI를 업데이트하는 모든 프로세서는 EventQueue.invokeLater (예 : 장기 실행 백그라운드 비 EDT 스레드 프로세스에서 생성 된 출력)를 사용하여 수행됩니다.장기 실행 JEditorPane 처리를위한 모범 사례 setText process
현재 시나리오에서는 JEditorPane 개체를 업데이트해야하는 데이터를 반환하는 TCPIP 소켓 읽기 백그라운드 스레드 프로세스가 있습니다. JEditorPane setText 호출을 사용합니다. 문제는 invokeLater 루틴에 setText 호출을 배치하면 대용량 파일 (예 : 19,790KB)에 GUI가 고정됩니다.
이 문제를 해결하기위한 시도는 비 EDT 백그라운드 스레드에서 setText 동작을 수행하는 것입니다. 이것은 문제를 해결하는 것으로 보입니다. 다만, JEditorPane setText (Java JDK)는 thread 세이프가 아니기 때문에, 베스트 프랙티스가 걱정됩니다.
그러나 JDK 코드를 통해 트롤링하는 동안 여기에서 수행되는 긴 프로세스는 JDK DefaultEditorKit.read에 있으며 그 메소드 내에서 GUI에 영향을주는 유일한 코드는 doc.insertString 호출에 있습니다 (단, 오전). 이제는 JDK PlainDocument.java insertString 메소드를 보면 스레드 안전성을 문서화하므로이 솔루션이 건전하다고 생각할 것입니다. 그러나이
...
스트레스가 내 응용 프로그램을 테스트, 나는 GUI 주위에 어떤 임의의 클릭을하고, 현재 트리 노드 애니메이션이 실행되고, 아래의 큰로드하는 동안, 애니메이션을 느리게 나타납니다 않습니다 조금, 따라서 내가 가장 좋은 해결책을 수행하지 못했다는 나의 관심사 (또한 미래의 JRE가 나를 여기까지 망가 뜨리고 따라서 현재 스레드 세이프 상태 인 insertString에 의존하지 않는 것에 대해 매우 우려하고있다).
나는이 질문이 "오래 실행되는 JEditorPane setText를 처리하는 방법"에 대해 이전에 질문되었지만 적합한 대답이없는 것으로 조사했습니다.
질문 1) 내 현재 관측에 대한 생각을 가진 사람이 있습니까?
질문 2) 누구나 내가 이걸 어떻게 달성 할 수 있을지에 대한 아이디어가 있습니까?
참고 IDE 모양의 동적 글꼴을 지원하고 자연을 느낄 수 있기 때문에 JEditorPane 만 선택할 수 있습니다.
또한 아래의 호출은 EventQueue.invokeLater 루틴 내에서 호출되므로 초기 editorPane 작업은 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에 필요한 모든 게시 작업이 완료된 메서드에서 수행됩니다. 나는 그것이 당신이 의미하는 것이라고 가정합니다. 그렇지 않으면 setText를 SwingWorker done 메소드에 두는 것이 원래의 문제 코드와 동일한 효과를 가지므로 EDT에서 setText를 수행하면 GUI가 정지됩니다. 생각? –
아니요. SwingWoker는 EDT와 업데이트를 동기화 할 수있는 게시/프로세스 방법을 제공합니다. 사실, UI를 업데이트하기 위해 EDT 내에서 호출되는 done 메소드를 사용하면됩니다. Swing은 일반적으로 스레드로부터 안전하지 않습니다. – MadProgrammer