# Problem mit relativen Pfaden in einem RCP-Plugin



## otxws (2. Jun 2010)

Guten Tag!


Ich habe eine kleine JAVA-Applikation geschrieben, deren GUI ist SWT basiert. In der GUI werden Grafiken im PNG-Format verwendet. Wie folgt werden die Grafiken eingebunden:

```
org.eclipse.jface.resource.ImageRegistry image_registry = new org.eclipse.jface.resource.ImageRegistry();
try
{
    image_registry.put("WINDOW_ICON", org.eclipse.jface.resource.ImageDescriptor.createFromURL(new java.net.URL("file:icons/window_connect.png")));
}
catch(java.net.MalformedURLException exception)
{
    // ...
}
this.shell_.setImage(image_registry.get("WINDOW_ICON"));
```

Der Befehl „Run As“ -> „Java Application“ startet die Anwendung und die Grafik wird korrekt eingebunden. Das Projekt befindet sich lokal an folgender absoluter Stelle:
C:\Dokumente und Einstellungen\christianps\Eigene Dateien\My Projects\gui\remote_control\com.mydomain.remctrl.widget
Die Grafiken liegen in einem Unterordner Namens icons mit dem absoluten Pfad:
C:\Dokumente und Einstellungen\christianps\Eigene Dateien\My Projects\gui\remote_control\com.mydomain.remctrl.widget\icons

Die gleiche Anwendung habe ich auch als RCP-Plugin ausgeprägt. Auch hier funktioniert alles tadellos, bis auf eine Ausnahme: Keine der Grafiken wird eingebunden, weil Eclipse an der falschen Stelle nach den Grafiken sucht. Eclipse sucht in dem Ordner nach dem Unterordenr icons, in dem das Binary von Eclipse liegt. Bei mir unter diesem absolutem Pfad:
C:\Programme\Eclipse

Ich starte das RCP-Plugin aus Eclipse heraus in dem ich die MANIFEST.MF Datei in Eclipse lade und dann den grünen Play-Button oben rechts anklicke.

Das Projekt habe ich auch schon als ausführbare JAR-Datei exportiert mit „File“ -> „Export ...“ -> „Plug-in Development“ -> Deployable plug-ins and fragments“. Es wurde eine JAR-Datei erstellt, die sich auch korrekt ausführen ließ, nur eben wieder ohne eine einzige Grafik. Die JAR-Datei habe ich dann auch noch mit einem Packprogramm (bei mir 7-Zip) geöffnet und wie zu erwarten war, existiert innerhalb dieser JAR-Datei der Ordner icons mit allen Grafik-Dateien.

Meine build.properties sehen wie folgt aus:

```
source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
               META-INF/,\
               .,\
               icons/,\
               .classpath

src.includes = icons/,\
               plugin.xml,\
               .classpath,\
               META-INF/
```

Das Programm-Icon das ich unter „Extension Element Details“ eingetragen habe wird korrekt geladen und angezeigt.

Wie bringe ich JAVA bzw. Eclipse dazu an der richtigen Stelle nach den Grafiken zu suchen, ohne absolute Pfade verwenden zu müssen?


Bernd


----------



## Wildcard (2. Jun 2010)

AbstractUIPlugin.imageDescriptorFromPlugin


----------



## otxws (2. Jun 2010)

Guten Tag!


Vielen Dank für den Hinweis! Damit hat das Plugin funktioniert, jedoch trat dann der Fehler in der Standalone-Version auf. ;(

Ich habe mich vorläufig dann so gerettet:

```
org.eclipse.jface.resource.ImageRegistry image_registry = new org.eclipse.jface.resource.ImageRegistry();
try
{
   org.eclipse.ui.plugin.AbstractUIPlugin.imageDescriptorFromPlugin("com.mydomain.remctrl.widget", "file:icons/window_connect.png").createImage();
   image_registry.put("WINDOW_ICON", org.eclipse.ui.plugin.AbstractUIPlugin.imageDescriptorFromPlugin("com.mydomain.remctrl.widget", "file:icons/window_connect.png"));
}
catch(java.lang.NullPointerException exceptiona)
{
   try
   {
       image_registry.put("WINDOW_ICON", org.eclipse.jface.resource.ImageDescriptor.createFromURL(new java.net.URL("file:icons/window_connect.png")));
   }
   catch(java.net.MalformedURLException exception)
   {
       // ...
   }
}
this.shell_.setImage(image_registry.get("WINDOW_ICON"));
```
Schöner Source-Code sieht anders aus. Kann man das irgendwie effektiver gestalten? Kann ich an dieser Stelle das System befragen ob ich ein Plugin oder eine Standalone Anwendung bin?


Bernd


----------



## Wildcard (2. Jun 2010)

Ich würde dir Vorschlagen Dependency Injection zu verwenden (Guice zum Beispiel). Du definierst dann ein Interface über das du ImageDescriptors/Resourcen über einen Pfad/Key Abfragen kannst.
Dieses Interface hat zwei Ausprägungen:
-RCP
-Standalone
Dann machst du zwei Guice Modules. Bei einem Module wird das Interface an die RCP Ausprägung gebunden, bei dem anderen in der Standalone Ausprägung. Bei einer Anwendung die sowohl Standalone als auch als RCP läuft wirst du noch mehrere solche Fälle haben wo bestimmte Funktionalität anders ablaufen musst, DI wird dir also vermutlich an weiteren Stellen zu gute kommen.


----------



## otxws (2. Jun 2010)

Guten Tag!


In diese Richtung habe ich auch schon gedacht, war mir aber zu aufwendig. Wenn es nichts schlankeres gibt, ist das Thema denke ich erledigt. Mit schlanker meine ich in der Art java.lang.BinIchPluginOderNicht() und bekomme einen boolschen Wert zurück.


Bernd


----------



## Wildcard (2. Jun 2010)

Pack das hier in deinen Activator:


```
public static boolean isRunningAsPlugin(){
	//entweder so:
	return getDefault()==null;
	//oder so
	return Platform.isRunning();
}
```

DI halte ich dennoch für die bessere Lösung und Guice ist ein sehr schlankes (aber mächtiges) Framework.


----------

