0

사용자 지정 대화 상자가 나타납니다. 나는 EDT에 나는 다음과 같은 오류 얻을 할 메서드를 호출하려고하면 이클립스에서 내 프로젝트를 정리하고, 나는 EDT에 메소드를 호출하는 것을 알아 냈 일부 절연 테스트를 수행 한 후EDT에서이 메서드를 호출하면 컴파일 오류가 발생하는 이유는 무엇입니까?

Exception in thread "AWT-EventQueue-0" java.lang.Error: Unresolved compilation problem: 

at danind.com.gmail_coem.ui.CredentialEditor.promptPossibleDialog(CredentialEditor.java:29) 
at danind.com.gmail_coem.ui.HomeScreen$ConfigureDatabase.<init>(HomeScreen.java:281) 
at danind.com.gmail_coem.ui.HomeScreen.configureDatabase(HomeScreen.java:230) 
at danind.com.gmail_coem.ui.HomeScreen.lambda$1(HomeScreen.java:105) 
at danind.com.gmail_coem.ui.HomeScreen$$Lambda$7/2092062410.actionPerformed(Unknown Source) 
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source) 
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source) 
at javax.swing.DefaultButtonModel.setPressed(Unknown Source) 
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source) 
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source) 
at java.awt.AWTEventMulticaster.mouseReleased(Unknown Source) 
at java.awt.Component.processMouseEvent(Unknown Source) 
at javax.swing.JComponent.processMouseEvent(Unknown Source) 
at java.awt.Component.processEvent(Unknown Source) 
at java.awt.Container.processEvent(Unknown Source) 
at java.awt.Component.dispatchEventImpl(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source) 
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source) 
at java.awt.Container.dispatchEventImpl(Unknown Source) 
at java.awt.Window.dispatchEventImpl(Unknown Source) 
at java.awt.Component.dispatchEvent(Unknown Source) 
at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
at java.awt.EventQueue.access$400(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.awt.EventQueue$3.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.awt.EventQueue$4.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
at java.awt.EventQueue.dispatchEvent(Unknown Source) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
at java.awt.EventDispatchThread.run(Unknown Source) 

무엇 문제가 발생했습니다. 내가 배경 스레드로 메서드를 옮겼을 때 효과적 이었지만 EDT에서 대화 상자 GUI를 만들고 싶지 않았기 때문에이 메서드를 사용하고 싶지 않습니다.

//Creates compilation error 
private class ConfigureDatabase extends SwingWorker<Void, String[]> 
{ 
    private CredentialEditor instance; 
    public ConfigureDatabase() 
    { //Runs on EDT 
     this.instance = CredentialEditor.promptPossibleDialog(true); 
    } 

    @Override 
    protected Void doInBackground() 
    { //Runs in background thread 
     try(Database database = CredentialEditor.getCredentials(instance)) 
     { 
      //code 
     } 
    } 
} 

문제

//Runs just fine, but dialog GUI is not on EDT 
private class ConfigureDatabase extends SwingWorker<Void, String[]> 
{ 
    @Override 
    protected Void doInBackground() 
    { //Runs in background thread 
     try(Database database = CredentialEditor.getCredentials(CredentialEditor.promptPossibleDialog(true))) 
     { 
      //code 
     } 
    } 
} 

방법 대 :

public static CredentialEditor promptPossibleDialog(boolean reset) 
{ 
    if(reset || ConnectionPool.getInstance() == null) 
    { //Checks to see if a dialog box needs to be created. 
     if(SwingUtilities.isEventDispatchThread()) 
     { //Checks to make sure the thread is on the EDT. 
      return new CredentialEditor(); 
     } 
     else 
     { //If it's not on the EDT throw an exception warning. 
      throw new IllegalStateException("Must run on EDT!"); 
     } 
    } 
    return null; //If no dialog box needs to be created return nothing. 
} 

은 단순히 방법이 문제가 발생를 호출하는 것 같다 문제에 대한 자세한한다. 인스턴스 변수 나 메서드 안의 어떤 것도 설정하지 않고 있습니다. 이것은 단지 EDT에서 정적 메서드를 호출하는 것입니다. 사실, 그것은 단순히 같이 방법을 알리는 것 라인에 스택 트레이스 포인트가

그래서 무슨 일이 오류의 원인이되고 공공 정적 CredentialEditor promptPossibleDialog (부울 재설정)라는 라인이 경우 그럴 수 없어 주위에 그것을 얻을 방법에 대한 내 GUI 코드를 실행할 수 있습니다 EDT에 대한 경우에도 백그라운드 스레드에서 호출되고있다?

+0

@VinceEmigh 그의 게시물에서 가장 먼저 다루는 것들 중 하나입니다 :'Unresolved compilation problem ' –

+0

'CredentialEditor' 클래스의 나머지 코드를 볼 수 있습니까? –

+0

@VinceEmigh 그것이 저에게이 문제를 흥미롭게 만듭니다 :) 그의 컴파일러는 정확히 어떤 오류를 말하지 않습니다. 컴파일 오류가 있다고합니다. –

답변

0

EDT에서 대화 상자를 직접 실행 해보십시오.

public ConfigureDatabase() 
{ 
    //some code 
    this.instance = CredentialEditor.promptPossibleDialog(true); //This is line 281 
} 

이것은 작업자 스레드에서 대화 상자를 실행하고 있음을 의미하므로 이는 좋지 않습니다. 작업자 스레드는 비 대화식 백그라운드 작업의 경우 대부분 afaik입니다. 당신은 작업자 스레드 내에서 대화 상자를 실행해야하는 경우, 별도로 같은 EDT의의를 시작해야합니다

public ConfigureDatabase() 
{ 
    SwingUtilities.invokeLater(new Runnable() { //or if you must wait for its end, use invokeAndWait 

     public void run() { 
       CredentialEditor.promptPossibleDialog(true); //This is line 281 
     } 
    }); 
} 

이 작동합니다. 처음에 전체 SSCE를 제공하는 것이 더 도움이 될 것입니다.

또한 대화 상자는 사용자와 상호 작용하고 결과를 되돌리기위한 것입니다. 대화 상자를 인스턴스에 저장하는 것이 가장 좋은 방법은 아닙니다. 대신 결과를 저장하거나 디자인을 다시 생각해보십시오.

Note: calling get on the Event Dispatch Thread blocks all events, including repaints, from being processed until this SwingWorker is complete.

When you want the SwingWorker to block on the Event Dispatch Thread we recommend that you use a modal dialog.

For example:

class SwingWorkerCompletionWaiter extends PropertyChangeListener { 
    private JDialog dialog; 

    public SwingWorkerCompletionWaiter(JDialog dialog) { 
     this.dialog = dialog; 
    } 

    public void propertyChange(PropertyChangeEvent event) { 
     if ("state".equals(event.getPropertyName()) 
       && SwingWorker.StateValue.DONE == event.getNewValue()) { 
      dialog.setVisible(false); 
      dialog.dispose(); 
     } 
    } 
} 

으로 실행 :

 JDialog dialog = new JDialog(owner, true); 
    swingWorker.addPropertyChangeListener(
     new SwingWorkerCompletionWaiter(dialog)); 
    swingWorker.execute(); 
    //the dialog will be visible until the SwingWorker is done 
    dialog.setVisible(true); 

Specified by: get in interface Future Returns: the computed result Throws: InterruptedException - if the current thread was interrupted while waiting ExecutionException - if the computation threw an exception

0

당신은 그것을 컴파일 경우에도 코드를 실행할 수의 Eclipse 기능을 통해 비틀 거리고있다

는, 예를 here 참조 오류는 어떤 선보다 더 해롭다. 당신은 그것을 끄는 것을 고려할지도 모른다. 그러나 스택 트레이스의 라인 번호를 살펴 보는 것은 컴파일 에러의 라인 번호는 아니지만 런타임에 예외가 생성 된 라인 번호를 알려주지 않으므로 이해해야합니다 .

코드를 실행할 때 컴파일하려고하지 않습니다.대신 컴파일러는 Eclipse가 컴파일 할 수없는 코드 조각에 도달하면 무조건 해당 예외를 throw하는 코드를 생성합니다. 그래서 코드가 실행되는 쓰레드와 아무런 관계가 없습니다. 가짜 컴파일러 오류가 CredentialEditor에 나타나기 때문에 호출자가 수정 한 내용이 올바르게 컴파일되는지 여부가 변경된다는 것은 믿기지 않습니다. 그러나 백그라운드 스레드에서 호출 할 때 코드가 IllegalStateException을 던지기는하지만 두 번째 시나리오에서 작동한다고하면 변경 사항으로 알려주지 않습니다.

반면에 버그로 인해 동작이 논리적으로 보일 필요는 없습니다. 일반적으로 예외에는 컴파일러 오류가 있지만 스택 추적의 빈 줄은 IDE에서 오류에 대해 알려주지 않은 관찰 된 동작과 완벽하게 일치합니다. 따라서 컴파일러 오류가 존재하지 않는 곳이나 메시지가 누락 된 컴파일러 오류가있는 곳에서 버그를 발견했습니다.

컴파일러 버그를 치는 것은 당신이 언급하지 못한 것을 고려할 때 놀랄만 한 것이 아니라, Java 8을 사용하고 적극적으로 새로운 기능을 사용하는 것입니다. 이클립스의 자바 8 지원은 ... 개선의 여지가 충분하다. 가장 최근의 Eclipse 버전을 실제로 사용하고 있는지 확인하십시오. 사용중인 경우 또는 업데이트 후 문제가 남아있는 경우 문제를 재현하고 다른 (제 3 자) 클래스에 의존하지 않고 Eclipse 팀에 버그 보고서를 제출하는 최소한의 예제를 만드는 것이 좋습니다.