3

是的,所以我在这里遇到了一个有趣的问题,涉及运行 java 1.7 的 mac 上的 SWT 和 swing 集成。我试图将 SWT 浏览器小部件作为面板嵌入到我的 Swing 项目中,这在 Java 1.6 版上非常简单。有许多帖子解释了如何使用 SWT_AWT 桥接类以及以下示例来执行此操作:

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class MySWTBrowserTest implements ActionListener {

public JButton addCodeButton;
public JButton launchBrowserButton;
public JTextField inputCode;
public JFrame frame;
static Display display;
static boolean exit;

public MySWTBrowserTest() {
    frame = new JFrame("Main Window");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new FlowLayout());

    inputCode = new JTextField(15);
    inputCode.setText("999");
    addCodeButton = new JButton("Add Code");
    addCodeButton.addActionListener(this);
    addCodeButton.setActionCommand("addcode");

    launchBrowserButton = new JButton("Launch Browser");
    launchBrowserButton.addActionListener(this);
    launchBrowserButton.setActionCommand("launchbrowser");

    mainPanel.add(inputCode);
    mainPanel.add(addCodeButton);
    mainPanel.add(launchBrowserButton);

    frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
    frame.pack();
    frame.setVisible(true);
}

@Override
public void actionPerformed(ActionEvent e) {
    if (e.getActionCommand().equals("addcode")) {
    } else if (e.getActionCommand().equals("launchbrowser")) {
        createAndShowBrowser();
    }

}

public void createAndShowBrowser() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    final Canvas canvas = new Canvas();
    f.setSize(850, 650);
    f.getContentPane().add(canvas);
    f.setVisible(true);
    display.asyncExec(new Runnable() {

        @Override
        public void run() {
            Shell shell = SWT_AWT.new_Shell(display, canvas);
            shell.setSize(800, 600);
            Browser browser = new Browser(shell, SWT.NONE);
            browser.setLayoutData(new GridData(GridData.FILL_BOTH));
            browser.setSize(800, 600);
            browser.setUrl("http://www.google.com");
            shell.open();
        }
    });
}

public static void main(String args[]) {
    //SWT_AWT.embeddedFrameClass = "sun.lwawt.macosx.CEmbeddedFrame";
    display = new Display();

    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            MySWTBrowserTest mySWTBrowserTest = new MySWTBrowserTest();
        }
    });

    while (!exit) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
    display.dispose();
}
}

我使用 swt-3.8M5-cocoa-macosx-x86_64 JAR 文件,显然需要包含这些文件才能运行上述示例。当同时使用 1.6 JDK 的 32 位和 64 位版本时,它运行得非常好,但是当切换到 JDK 1.7 或 1.8 VM 时,会抛出可重现的错误:

2012-05-14 15:11:30.534 java[1514:707] Cocoa AWT: Apple AWT Java VM was loaded on first thread -- can't start AWT. (
0   liblwawt.dylib                      0x00000008db728ad0 JNI_OnLoad + 468
1   libjava.dylib                       0x00000001015526f1 Java_java_lang_ClassLoader_00024NativeLibrary_load + 207
2   ???                                 0x00000001015a4f90 0x0 + 4317663120
)
_NSJVMLoadLibrary: NSAddLibrary failed for /libjawt.dylib
JavaVM FATAL: lookup of function JAWT_GetAWT failed. Exit
Java Result: 255

我检查了 java 1.7 vm 并确实在那里找到了库,所以我努力想看看是什么导致它无法加载该库。当然,我确保使用: -XstartOnFirstThread 作为 VM 参数之一,这是 SWING/AWT 集成所必需的。

进一步说明,我尝试了 DJ Native Widgets 框架,它抛出了完全相同的错误,因为它也使用了底层的 SWT 框架。

为了重现效果,我建议在 mac 上安装 JDK 1.7(不是开发者预览版),下载:http ://www.eclipse.org/downloads/download.php?file=/eclipse/downloads/drops4/S-4.2 M7-201205031800/swt-S-4.2M7-201205031800-cocoa-macosx-x86_64.zip获取库,然后使用 -XstartOnFirstThread -d64 java 1.7 vm 运行它。

真的希望有人能够解决这个问题,因为我确定我不是唯一一个试图将 SWT 集成到 1.7 vm 上的 swing 的人

我还在谷歌上花了 8 个小时来查看这个错误是否已在其他任何地方重现,并且它已经出现在一些 Matlab 邮件列表中,但除此之外,我还没有找到更接近解决方案的东西。

提前致谢。


>> 更新 1

看起来我们可能有赢家:https ://bugs.eclipse.org/bugs/show_bug.cgi?id= 374199 去监控它,看看它的去向。

>> 更新 2

这是一个工作示例:https ://stackoverflow.com/a/27754819/363573

4

1 回答 1

2

不幸的是,这个问题没有好的答案。在 Java 7 中,AWT 已被完全重写为使用 CoreAnimation 层。SWT 假设 AWT Canvas 将由 NSView 支持,但现在不再如此。您现在唯一的选择是坚持使用 Java 6。

AWT 团队已意识到该问题,但您可能希望在 bugs.sun.com 上提交另一个错误。

于 2012-07-06T03:01:46.177 回答