그러니까 기본적으로 내 응용 프로그램의 GUI를 업데이트됩니다, 그래서 정적 메서드자바는 통지
무효 javax.swing.SwingUtilities.invokeLater (의 Runnable doRun)
를 사용
하지만 초기화 코드를 실행 파일과 논리 코드 외부에 넣고 싶습니다. 그러나 invokeLater
메서드를 호출하면 invokeLater
메서드가 호출 된 직후에 내 주 스레드가 내 논리 코드를 호출하려고하기 때문에 내 주 스레드와 AWT 스레드가 경쟁 상태가되지만 JFrame 이후 (내 case)가 아직 초기화되지 않았으므로 내 메인 스레드가 레이스에서 이기고 예외가 발생합니다.
Event-Dispatching 스레드가 실행 가능한 runnable을 기다렸다가 초기화 코드를 초기화 할 때 runnable에서 알릴 수 있다고 생각했습니다. 그러나 어떤 이유로 든 아래 코드 (약식)가 작동하지 않습니다.
경량 응용 프로그램의 경우 실행 가능 파일이 경쟁 조건에서 이기기 때문에 예외가 발생하지 않지만 응용 프로그램에서 초기화 코드가 길어집니다.
SSCCE : 사전에
public class SSCCE {
private static JFrame frame;
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
synchronized (this) {
frame = new JFrame();
frame.setTitle("JFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
this.notifyAll();
System.out.println("Notified all");
}
}
};
synchronized (r) {
try {
System.out.println("Waiting"); // EDIT this line was after the wait method, and therefore it didn't execute.
r.wait();
} catch (InterruptedException e) {
throw new RuntimeException("Unexpected disruption whilst waiting for the \"Event-Dispatching thread\".",e);
}
}
SwingUtilities.invokeLater(r);
frame.setVisible(true);
frame.getContentPane().add(new JLabel("Hello World!"));
frame.pack();
}
}
감사합니다!
미안하지만이 동기는 무엇입니까? –
모든 Swing GUI 코드는 Event Dispatch Thread에서 실행되어야합니다. invokeLater()를 사용하는 것은 EDT에 코드를 추가하는 것입니다. Runabble을 동기화 할 필요가 없습니다. 나는 정말로 당신이 복잡한 것을 생각합니다. EDT에 모든 코드를 입력하십시오.장기 실행 태스크가있는 경우, GUI가 이미 작성되고 가시화 된 후 init 코드 내에서 해당 태스크를 호출 할 수 있습니다. – camickr
@HovercraftFullOfEels GUI가 업데이트 될 응용 프로그램을 만들고 invokeLater가 AWT 이벤트 디스패치 스레드에서 주 스레드를 비동기 적으로 실행해야하지만 이후 JFrame에 직접 액세스하려고하므로 예외가 발생합니다. 아직 초기화되지 않았기 때문에 – Linus