2

我正在尝试使用 Swing 实现 Web 浏览器。这是下面的代码。

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

    }
}

我越来越低于异常。

 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)

我在我的类路径中使用下面的罐子。

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

2 回答 2

8

您的错误消息告诉您出了什么问题:

在 Mac 上,不应在 AWT 静态初始化程序运行后调用“NativeInterface.initialize()”/“NativeInterface.open()”,否则可能会出现各种副作用(非功能性模式对话框等)。通常,问题是当“main(String[])”方法位于 AWT 组件子类中时,解决方法是将该 main 方法移动到独立类中。这里有问题的类是“WebPageDisplay”

您需要在 EDT 事件调度线程上启动您的 GUI。但是话虽如此,在您的 GUI 在 EDT 上排队之前,需要在主线程而不是 EDT上启动 NativeInterface 。根据NativeInterface APIopen()方法部分:

如果接口尚未初始化,则进行初始化。如果没有显式执行初始化,则应在程序的早期调用此方法,最好的位置是在 main 方法中的第一次调用。

因此,您的代码可能如下所示:

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

请注意,我没有也没有使用过 NativeInterface 库,因此无法测试此代码。

请注意,我看不到您将 GUI 组件添加到 JFrame 等顶级窗口的位置,因此我不确定您如何显示 GUI。

于 2012-09-17T17:52:54.987 回答
0

除了“Hover Full Of Eels”所说的之外,这是我在 Mac 上为我工作的解决方案:

1 - 不要使用该main()方法,而是在主类的最开始创建一个静态时钟并将该open()方法放置在那里。

2 - 在您的主要方法结束时runEventPump(),我认为大多数系统都需要该方法。

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

  // ... (etc)

  public static void main(String[] args) {
    // ... (etc)
    NativeInterface.runEventPump();
  }
}
于 2013-07-24T07:17:05.523 回答