# AWT zu SWT



## borobudur (10. Mrz 2009)

Hallo, ich versuche ein AWT Image mit dem SWT framework anzuzeigen. 
Wenn ich das ganze laufen lasse wirft Java folgende exception:


```
Exception in thread "main" java.lang.IllegalArgumentException: Argument not valid [peer not created]
	at org.eclipse.swt.SWT.error(SWT.java:3358)
	at org.eclipse.swt.awt.SWT_AWT.new_Shell(SWT_AWT.java:263)
	at SurfPeaks.main(SurfPeaks.java:18)
```

Kann mir jemand damit helfen? Hier der code:


```
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.awt.SWT_AWT;

public class SurfPeaks 
{
    public static void main(String args[])
    {
        Display display = new Display();
        Shell shell = SWT_AWT.new_Shell(display, new SurfImage());
        shell.setLayout( new RowLayout());

        shell.pack();
        shell.open();
        while( !shell.isDisposed())
        {
                if(!display.readAndDispatch()) 
                display.sleep();
        }
        display.dispose();
    }
}
```


```
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Image;

import com.mathworks.toolbox.javabuilder.Images;
import com.mathworks.toolbox.javabuilder.MWArray;
import com.mathworks.toolbox.javabuilder.MWNumericArray;
import com.mathworks.toolbox.javabuilder.MWException;

import com.mathworks.deploy.peaks.Peaks;

public class SurfImage extends Canvas 
{
    //This method is basically our "business logic" method.  
    //It is responsible for instantiating our MATLAB deployment, 
    //passing in any needed inputs, and dealing with any outputs. 
    //In this example we have no inputs, and the only output is the 
    //figure in hardcopy format (three dimensional MWNumericArray).
    private static Image getSurfImage()
    {
        try
        {
            //Our deployment uses native resources and 
            //should be disposed of as soon as possible. 
            Peaks matlabModel = new Peaks();
            try
            {
                //If we had any inputs to our method 
                //they would be passed in here.  
                Object[] results = matlabModel.getSurfsFigure(1);
                
                //This array uses native resources and 
                //should be disposed of as soon as possible.
                MWArray mwArray = (MWArray)results[0];
                try
                {
                    //Since we want this method to return only 
                    //     non MATLAB data 
                    //  we convert the MATLAB figure to a 
                    //     buffered image and return it.
                    return Images.renderArrayData
                             ((MWNumericArray)mwArray);
                }
                finally
                {
                    MWArray.disposeArray(mwArray);
                }
            }
            finally
            {
                matlabModel.dispose();
            }
        }
        catch(MWException mwe)
        {
            mwe.printStackTrace();
            return null;
        }
    }    
    

	public void paint(Graphics g) {
		g.drawImage(getSurfImage(), 10, 10, null);
	}
	
}
```


----------



## Wildcard (10. Mrz 2009)

Das Canvas hat noch keinen Peer (weil es noch nicht angezeigt wird, bzw addNotify nicht aufgerufen wurde).
Aber was soll das? Ich verstehe das so, das du AWT in SWT anzeigen möchtest, und nicht andersrum.
Dafür würdest du eigentlich auf diese Methode zurückgreifen:
SWT_AWT (Eclipse Platform API Specification)
Das Composite muss dabei vom Style SWT.EMBEDDED sein.

EDIT: wenn es dir nur um ein Bild geht, solltest du unbedingt das Bild konvertieren und nicht AWT embedden.


----------



## borobudur (11. Mrz 2009)

Hallo WildCard, danke für die hilfe!

Ich habe das addNotify hinzugefügt 

```
SurfImage surfImage = new SurfImage();
    	surfImage.addNotify();
```
und erhalte nun eine andere fehlermeldung:

```
Exception in thread "main" java.lang.NullPointerException
	at sun.awt.X11.XWindow.initGraphicsConfiguration(XWindow.java:133)
	at sun.awt.X11.XWindow.preInit(XWindow.java:142)
	at sun.awt.X11.XComponentPeer.preInit(XComponentPeer.java:124)
	at sun.awt.X11.XCanvasPeer.preInit(XCanvasPeer.java:32)
	at sun.awt.X11.XBaseWindow.init(XBaseWindow.java:165)
	at sun.awt.X11.XBaseWindow.<init>(XBaseWindow.java:243)
	at sun.awt.X11.XWindow.<init>(XWindow.java:104)
	at sun.awt.X11.XWindow.<init>(XWindow.java:115)
	at sun.awt.X11.XComponentPeer.<init>(XComponentPeer.java:119)
	at sun.awt.X11.XCanvasPeer.<init>(XCanvasPeer.java:28)
	at sun.awt.X11.XToolkit.createCanvas(XToolkit.java:768)
	at java.awt.Canvas.addNotify(Canvas.java:74)
	at SurfImage.addNotify(SurfImage.java:17)
	at SurfPeaks.main(SurfPeaks.java:11)
```
Das sieht nach linux X11 aus oder muss ich vielleicht das canvas noch auf ein window klatschen? 

org.eclipse.swt.awt.SWT_AWT verwende ich doch!? Würdest du das anders machen?

```
Shell shell = SWT_AWT.new_Shell(display, new SurfImage());
```



> Das Composite muss dabei vom Style SWT.EMBEDDED sein.
> 
> EDIT: wenn es dir nur um ein Bild geht, solltest du unbedingt das Bild konvertieren und nicht AWT embedden.


Kannst du hierzu mehr sagen? Verstehe nicht ganz was du meinst.


----------



## Wildcard (11. Mrz 2009)

Hmm, der Link funktioniert nicht so richtig...
Mir ging es eigentlich darum, das du (da bin ich ziemlich sicher) SWT_AWT#new_Frame verwenden willst, und nicht new_Shell.


----------



## borobudur (12. Mrz 2009)

Nein, ich will von AWT nach SWT, da muss ich new_Shell verwenden.

Edit: okay, ich glaube, ich habe dich nun verstanden. Habe dieses beispiel gefunden, habe aber immer noch das gleiche problem:

```
final Display display = new Display();
		final Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		Composite composite = new Composite(shell, SWT.EMBEDDED);
		
		/* Draw an X using AWT */
		Frame frame = SWT_AWT.new_Frame(composite);
		Canvas canvas = new Canvas() {
			public void paint (Graphics g) {
				Dimension d = getSize();
				g.drawLine(0, 0, d.width, d.height);
				g.drawLine(d.width, 0, 0, d.height);
			}
		};
		frame.add(canvas);
```


----------



## Wildcard (12. Mrz 2009)

Stacktrace bitte und am besten eine vollständige Klasse, damit ich verstehe was du da versuchst.


----------



## borobudur (13. Mrz 2009)

Mit dieser version funktionierts:

```
Frame frame = SWT_AWT.new_Frame(composite);
```
ich sehe den test-string:

```
g.drawString("Hallo Welt!", 100, 100);
```
Nun hänge ich aber an etwas anderem fest! Ich versuche, eine von Matlab generierte Kurve anzuzeigen (mit Matlab Javabuilder). 
Was sagt dir die fehlermeldung? Die bibliothek und die klassen sind im klassenpfad :-(

```
java.lang.Exception: Failed to find the runtime libraries, required by MATLAB Builder JA, on system path

	at com.mathworks.toolbox.javabuilder.internal.MWMCR.getMLorMCRRuntimeLibDir(MWMCR.java:1564)
	at com.mathworks.toolbox.javabuilder.internal.MWMCR.<clinit>(MWMCR.java:1461)
	at com.mathworks.deploy.peaks.PeaksMCRFactory.<clinit>(PeaksMCRFactory.java:99)
	at com.mathworks.deploy.peaks.Peaks.<init>(Peaks.java:50)
	at SurfImage.getSurfImage(SurfImage.java:25)
	at SurfImage.paint(SurfImage.java:63)
	at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
	at sun.awt.X11.XRepaintArea.paintComponent(XRepaintArea.java:56)
	at sun.awt.RepaintArea.paint(RepaintArea.java:224)
	at sun.awt.X11.XComponentPeer.handleEvent(XComponentPeer.java:688)
	at java.awt.Component.dispatchEventImpl(Component.java:4577)
	at java.awt.Component.dispatchEvent(Component.java:4331)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: com.mathworks.toolbox.javabuilder.internal.MWMCR.mclIsStandaloneMode()Z
	at com.mathworks.toolbox.javabuilder.internal.MWMCR.mclIsStandaloneMode(Native Method)
	at com.mathworks.toolbox.javabuilder.internal.MWMCR.getNativeMCR(MWMCR.java:773)
	at com.mathworks.deploy.peaks.PeaksMCRFactory.createComponentData(PeaksMCRFactory.java:120)
	at com.mathworks.deploy.peaks.PeaksMCRFactory.<clinit>(PeaksMCRFactory.java:99)
	at com.mathworks.deploy.peaks.Peaks.<init>(Peaks.java:50)
	at SurfImage.getSurfImage(SurfImage.java:25)
	at SurfImage.paint(SurfImage.java:63)
	at sun.awt.RepaintArea.paintComponent(RepaintArea.java:248)
	at sun.awt.X11.XRepaintArea.paintComponent(XRepaintArea.java:56)
	at sun.awt.RepaintArea.paint(RepaintArea.java:224)
	at sun.awt.X11.XComponentPeer.handleEvent(XComponentPeer.java:688)
	at java.awt.Component.dispatchEventImpl(Component.java:4577)
	at java.awt.Component.dispatchEvent(Component.java:4331)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
```


----------



## Wildcard (13. Mrz 2009)

Du lädst eine native Bibliothek? Die muss dann entweder im library path (nicht classpath) liegen, oder explizit per absolutem Pfad referenziert werden.
Kannst du sicherlich in der MATLAB Doku nachlesen wie das richtig zu konfigurieren ist.


----------



## borobudur (19. Mrz 2009)

Ich mache es genau so wie in der Dukumentation. Ich habe ein bestehendes beispiel abgeändert (welches auf meinem system funktioniert) und habe damit das problem. 

Vermutlich ist das problem das hinzufügen neuer libs (SWT), was einen konflikt auslöst: (arbeite unter Ubuntu Intrepid)

Zuerst mache ich diese exports:

```
matlab_root="/etc/matlab/"
export PATH=$PATH":"$matlab_root"bin/:"$matlab_root"toolbox/compiler/mcr/compiler"
export CLASSPATH=$matlab_root"toolbox/javabuilder/jar/javabuilder.jar"
export JAVA_HOME="/usr/lib/jvm/java-6-sun"
export XAPPLRESDIR=$matlab_root"X11/app-defaults"
export LD_LIBRARY_PATH=$matlab_root"sys/os/glnxa64:"$matlab_root"bin/glnxa64:"$matlab_root"extern/lib/glnxa64:"$matlab_root"sys/java/jre/glnxa64/jre/lib/amd64/native_threads:"$matlab_root"sys/java/jre/glnxa64/jre/lib/amd64/server:"$matlab_root"sys/java/jre/glnxa64/jre/lib/amd64"
```
Und dann rufe ich java auf

```
java -cp $matlab_root"toolbox/javabuilder/jar/javabuilder.jar:./lib/peaks.jar:/usr/lib/eclipse/plugins/org.eclipse.swt.gtk.linux.x86_64_3.2.2.v3236.jar:./bin/" -Djava.library.path=/usr/lib/jni/ -Xmx256m SurfPeaks
```

Ist es evt. dies das problem: -Djava.library.path=/usr/lib/jni/


----------



## borobudur (19. Mrz 2009)

Wildcard! Du hast mich auf die richtige spur gebracht!!

Ich denke mit dem (-Djava.library.path=/usr/lib/jni/) überschreibe ich meine system variable. 

Mit hinzufügen zur LD_LIBRARY_PATH funktionierts!


----------

