developer
developer

Reputation: 9478

Getting java.lang.IllegalStateException: This call must happen in the AWT Event Dispatch Thread! Please refer to

I am trying to implement web browser using Swing. Here is code below.

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();

    }
}

Iam getting below exception .

 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)

I am using below jars in my classpath.

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

Upvotes: 3

Views: 4061

Answers (2)

gav.newalkar
gav.newalkar

Reputation: 302

Further to what "Hover Full Of Eels" said, here is my solution that worked for me on a Mac:

1 - Rather than using the main() method, create a static clock at the very start of your main class and place the open() method there.

2 - At the end of your main method, runEventPump() method, which I think is needed for most systems.

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

  // ... (etc)

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

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Your error message is telling you what's wrong:

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"

You need to start your GUI on the Event Dispatch Thread, the EDT. But having said that, the NativeInterface needs to be started up on the main thread, not the EDT, before your GUI is queued on the EDT. Per the open() method section of the NativeInterface API:

Initialization takes place if the interface was not already initialized. If initialization was not explicitely performed, this method should be called early in the program, the best place being as the first call in the main method.

So your code could look like this:

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();
      }
    });
}

Note that I do not have nor have I used the NativeInterface library so cannot test this code.

Note that I do not see where you add your GUI components to a top-level window such as a JFrame, so I'm not sure how you display the GUI.

Upvotes: 8

Related Questions