2 votes

Obtention de l'exception java.lang.IllegalStateException : Cet appel doit avoir lieu dans le thread de répartition des événements de l'AWT ! Veuillez vous référer à

J'essaie d'implémenter un navigateur web en utilisant Swing. Voici le code ci-dessous.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.JPanel;
import javax.swing.JScrollPane;

import chrriis.dj.nativeswing.swtimpl.NativeInterface;
import chrriis.dj.nativeswing.swtimpl.components.JWebBrowser;

public class WebPageDisplay extends JPanel{

    public WebPageDisplay() {

         super(new BorderLayout());  
         try{
         NativeInterface.open();

        JPanel webBrowserPanel = new JPanel(new BorderLayout());   
        final JWebBrowser webBrowser = new JWebBrowser();
        webBrowser.setBarsVisible(false);   
        webBrowser.setStatusBarVisible(true);   
        webBrowserPanel.add(webBrowser, BorderLayout.CENTER);   
        add(webBrowserPanel, BorderLayout.CENTER);
            webBrowser.navigate("www.google.com);
        JScrollPane scrollPane = new JScrollPane();
            Dimension preferredSize = scrollPane.getPreferredSize();
        preferredSize.height += 20;
        scrollPane.setPreferredSize(preferredSize);
        add(scrollPane,new GridBagConstraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER,
            GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
           }catch(Exception e){
        e.printStackTrace();
        }
      }

    public static void main(String[] args){
        WebPageDisplay display = new WebPageDisplay();

    }
}

Je reçois l'exception ci-dessous.

 On Mac, "NativeInterface.initialize()"/"NativeInterface.open()" should not be called after AWT static initializers have run, otherwise there can be all sorts of side effects (non-functional modal dialogs, etc.). Generally, the problem is when the "main(String[])" method is located inside an AWT component subclass and the fix is to move that main method to a standalone class. The problematic class here is "WebPageDisplay"
    ***WARNING: Display must be created on main thread due to Cocoa restrictions.
    2012-09-17 22:48:04.943 java[248:407] _createMenuRef called with existing principal MenuRef already associated with menu
    2012-09-17 22:48:05.134 java[248:407] (
        0   CoreFoundation                      0x00007fff96568286 __exceptionPreprocess + 198
        1   libobjc.A.dylib                     0x00007fff9244dd5e objc_exception_throw + 43
        2   CoreFoundation                      0x00007fff965680ba +[NSException raise:format:arguments:] + 106
        3   CoreFoundation                      0x00007fff96568044 +[NSException raise:format:] + 116
        4   AppKit                              0x00007fff8fea7597 -[NSCarbonMenuImpl _createMenuRef] + 64
        5   AppKit                              0x00007fff8fea6e82 -[NSCarbonMenuImpl _instantiateCarbonMenu] + 148
        6   AppKit                              0x00007fff8fe7bb43 -[NSApplication finishLaunching] + 878
        7   libawt.jnilib                       0x0000000106a6a157 -[NSApplicationAWT finishLaunching] + 641
        8   libswt-pi-cocoa-3730.jnilib         0x00000001080f9eb2 Java_org_eclipse_swt_internal_cocoa_OS_objc_1msgSendSuper__Lorg_eclipse_swt_internal_cocoa_objc_1super_2J + 89
        9   ???                                 0x0000000102abdd6e 0x0 + 4339785070
    )
    java.lang.IllegalStateException: This call must happen in the AWT Event Dispatch Thread! Please refer to http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html and http://java.sun.com/javase/6/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)
        at chrriis.dj.nativeswing.swtimpl.core.MessagingInterface.checkUIThread(MessagingInterface.java:161)
        at chrriis.dj.nativeswing.swtimpl.core.SWTNativeInterface.checkUIThread(SWTNativeInterface.java:475)
        at chrriis.dj.nativeswing.swtimpl.core.SWTNativeComponent.runSync(SWTNativeComponent.java:184)
        at chrriis.dj.nativeswing.swtimpl.components.core.NativeWebBrowser.navigate(NativeWebBrowser.java:728)
        at chrriis.dj.nativeswing.swtimpl.components.JWebBrowser.navigate(JWebBrowser.java:315)
        at chrriis.dj.nativeswing.swtimpl.components.JWebBrowser.navigate(JWebBrowser.java:305)
        at WebPageDisplay.<init>(WebPageDisplay.java:31)
        at WebPageDisplay.main(WebPageDisplay.java:54)

J'utilise les jarres suivantes dans mon classpath.

DJNativeSwing-SWT.jar
DJNativeSwing.jar
swt-3.7M7-cocoa-macosx-x86_64.jar

8voto

Hovercraft Full Of Eels Points 161146

Votre message d'erreur vous indique ce qui ne va pas :

Sur Mac, "NativeInterface.initialize()"/"NativeInterface.open()" ne doit pas être appelé après l'exécution des initialisateurs statiques AWT, sinon il peut y avoir toutes sortes d'effets secondaires (dialogues modaux non fonctionnels, etc.). En général, le problème se pose lorsque la méthode "main(String[])" se trouve dans une sous-classe de composant AWT et la solution consiste à déplacer cette méthode principale vers une classe autonome. La classe qui pose problème ici est "WebPageDisplay".

Vous devez lancer votre interface graphique sur le fil de distribution des événements, l'EDT. Cela dit, la NativeInterface doit être démarrée sur le thread de l'EDT. principal avant que votre interface graphique ne soit mise en file d'attente sur l'EDT. Selon le open() de la section méthode de l API NativeInterface :

L'initialisation a lieu si l'interface n'a pas déjà été initialisée. Si l'initialisation n'a pas été explicitement effectuée, cette méthode doit être appelée tôt dans le programme, le meilleur endroit étant le premier appel de la méthode main.

Votre code pourrait donc ressembler à ceci :

public static void main(String[] args){

    // start your NativeInterface here!
    NativeInterface.open(); // not sure what else may be needed for this

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        WebPageDisplay display = new WebPageDisplay();
      }
    });
}

Notez que je ne possède pas et n'ai pas utilisé la bibliothèque NativeInterface et que je ne peux donc pas tester ce code.

Notez que je ne vois pas où vous ajoutez vos composants GUI à une fenêtre de niveau supérieur comme un JFrame, donc je ne suis pas sûr de la façon dont vous affichez le GUI.

0voto

Ranayna Points 779

Suite à ce que "Hover Full Of Eels" a dit, voici ma solution qui a fonctionné pour moi sur un Mac :

1 - Plutôt que d'utiliser le main() créez une horloge statique au tout début de votre classe principale et placez la méthode open() de cette méthode.

2 - A la fin de votre méthode principale, runEventPump() qui, à mon avis, est nécessaire pour la plupart des systèmes.

public class Something {
  static {
    NativeInterface.open();
    UIUtils.setPreferredLookAndFeel();
  }

  // ... (etc)

  public static void main(String[] args) {
    // ... (etc)
    NativeInterface.runEventPump();
  }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X