views:

994

answers:

5

I'm an Eclipse newbie and I'm trying to build a mixed AWT/SWT application. Here's my code:

public class HelloWorldSWT {

    public static void main(String[] args) {
        Frame frame = new Frame("My AWT Frame"); // java.awt.Frame
        frame.setLayout( new BorderLayout() );
        Canvas canvas = new Canvas(); // java.awt.Canvas
        frame.add(canvas, BorderLayout.CENTER);
        frame.setVisible(true);

        Display display = new Display(); // display object to manage SWT lifecycle.
        Shell swtShell = SWT_AWT.new_Shell(display, canvas);
        Button m_button = new Button(swtShell, SWT.PUSH);
        m_button.setText( "button" );

        // invoke the AWT frame rendering by making the frame visible
        // This starts the EDT
        frame.setVisible(true);

        // standard SWT dispatch loop
        while(!swtShell.isDisposed())
        {
            if(!display.readAndDispatch())
                display.sleep();
        }
        swtShell.dispose();
    }
}

This compiles fine, but when I run it as application in Eclipse, I get the following error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: sun.awt.SunToolkit.getAppContext(Ljava/lang/Object;)Lsun/awt/AppContext; at sun.awt.SunToolkit.getAppContext(Native Method) at sun.awt.SunToolkit.targetToAppContext(Unknown Source) at sun.awt.windows.WComponentPeer.postEvent(Unknown Source) at sun.awt.windows.WComponentPeer.postPaintIfNecessary(Unknown Source) at sun.awt.windows.WComponentPeer.handlePaint(Unknown Source) at sun.java2d.d3d.D3DScreenUpdateManager.repaintPeerTarget(Unknown Source) at sun.java2d.d3d.D3DScreenUpdateManager.createScreenSurface(Unknown Source) at sun.awt.windows.WComponentPeer.replaceSurfaceData(Unknown Source) at sun.awt.windows.WComponentPeer.replaceSurfaceData(Unknown Source) at sun.awt.windows.WComponentPeer.setBounds(Unknown Source) at sun.awt.windows.WWindowPeer.setBounds(Unknown Source) at sun.awt.windows.WComponentPeer.initialize(Unknown Source) at sun.awt.windows.WCanvasPeer.initialize(Unknown Source) at sun.awt.windows.WPanelPeer.initialize(Unknown Source) at sun.awt.windows.WWindowPeer.initialize(Unknown Source) at sun.awt.windows.WFramePeer.initialize(Unknown Source) at sun.awt.windows.WComponentPeer.(Unknown Source) at sun.awt.windows.WCanvasPeer.(Unknown Source) at sun.awt.windows.WPanelPeer.(Unknown Source) at sun.awt.windows.WWindowPeer.(Unknown Source) at sun.awt.windows.WFramePeer.(Unknown Source) at sun.awt.windows.WToolkit.createFrame(Unknown Source) at java.awt.Frame.addNotify(Unknown Source) at java.awt.Window.show(Unknown Source) at java.awt.Component.show(Unknown Source) at java.awt.Component.setVisible(Unknown Source) at java.awt.Window.setVisible(Unknown Source) at HelloWorldSWT.main(HelloWorldSWT.java:20)

What am I doing wrong?

+1  A: 

The UnsatisfiedLinkError is indicating that a native library that you are relying upon is not found when you are trying to run your app. If you are compiling this in your IDE, then the library is in your build path. If you are running this from with your IDE and getting this error, the libray is not in your Run path. Check your Run Dialog to see that the libraries you have in your build path are in your run path.

akf
+1  A: 

As mentioned, this indicates that the JVM cannot find a native library. Since you're mixing AWT/SWT I assume that the JVM can't find the SWT libraries (.dll for windows, .so for linux, not sure for mac). I'm partial to using an system property to tell java where to look.

-Djava.library.path=<absolute path to the .dll/.so that SWT needs>
basszero
+2  A: 

Since version 3.3, SWT automatically finds its required platform-specific libraries, which are inside the swt.jar (at the top level of the JAR contents). So all you need is swt.jar in the classpath, and it works.

One way to get an UnsatisifiedLinkError is if you're using a swt.jar for another platform -- they're all named "swt.jar"; for example, if you download the one for Linux, and try to use it on Windows. The project will compile OK since all the API-level code is the same Java for every platform, but it will fail when you run because the native libraries are wrong.

However, since the error in this case happens in AWT, it might be something else, not directly related to SWT. First, make sure you've downloaded the Windows SWT release. When you import it into your workspace, it creates an Eclipse project named org.eclipse.swt, which contains the swt.jar. You then make org.eclipse.swt a required project for your project, and nothing else in the Build Path besides a valid, clean JRE (you can try defining a new one [Window -> Preferences -> Java -> Installed JREs], or just use a different one you might have installed).

You can also test it from the shell/command window. Go to your project directory. The command should be as simple as:

java -cp bin;..\org.eclipse.swt\swt.jar HelloWorldSWT

I got your code to run (Vista-32, JDK 6_15), but the window opened really small, and would not close. I don't know anything about the SWT-AWT bridge though, so good luck with that....

Ken
Thanks, I'll give this a try.
Judah Himango
Turns out I was referencing the wrong SWT jar file. Thanks for your help.
Judah Himango
A: 

I have had exactly the same problem, and could only get it resolved by completely removing and re-installing Java. It seems that somehow, one of the DLLs, containing the native AWT methods, had managed to get screwed up.

A: 

I have had solved this problem, I search this information for a long time,but i can't find one to solve my problem, after i check my java version

i found that jdk and jre version is different, for example

i found that one extra document on my file system

jdk 1.4 jre 1.4 jre 1.5(extra)

you should delete the new version of the jre(jre1.5)

then ok,my english is poor,i hope my message will do a favour, if you have some question ,you can connect to me,email:[email protected]