SWT SWT plattformunabhängig

eurit25

Mitglied
Hallo zusammen,

ich habe unter Linux ein Programm mit SWT GUI geschrieben. Dieses würde ich nun gerne auch für Windows Anwender bereitstellen ohne für jedes Betriebsystem und jede Architektur ein eigenes Jar File verteilen zu müssen.

Daher meine Frage: ist das überhaupt möglich? Und wenn ja wie?

Das hier habe zwar gefunden: Home - SWTJar - Mchr3k, da ich aber noch relativ frisch in der Java Entwicklung bin, kann ich mit diesem Ant Build nicht so wirklich etwas anfangen :(

Ich hoffe ihr erfahrenen Programmierer könnt mir bei meinem Problem weiter helfen.

Gruß und vielen Dank im Voraus
 

dzim

Top Contributor
Das Problem ist ja, das SWT ein Interface für die Platformspezifischen GUIs ist, das heisst, du musst imemr die jeweilige Jar-Datei für das korrekte System anbieten.

Hier findest du alle (im Moment aktuellen) Jars:
Eclipse Project

(Wenn du hier SWT: The Standard Widget Toolkit schaust, dann findest du dort unter Releases einen Link "more..." und kommst an die aktuelle Seite - im Moment der Link oben.)

Die Einfachste Variante für den Moment wäre für dich, die Lib in classpath explizit zu hinterlegen. Und zwar mit einem generischen Namen. Wenn du dort deine normale swt-4.3.jar rein legst, dann noch so etwas wie swt-4.3-platform.jar (wobei du dann immer die der dazugehörigen Platform reinkopieren müsstest), dann kannst du es sicher mit mässigen Aufwand verteilen. Falls du verstehst, was ich meine... (In meinem Kopf klan ges mal - wenigstens für ein paar Sekunden lang - gut :-D )
 

Androbin

Bekanntes Mitglied
[TIPP]
JAVA ist "Plattform-unabhängig" !!!

[/TIPP]

In deinem Fall bedeutet das :
Deine JAR-File wird auf allen Rechnern funktionieren,
[ solange diese JAVA installiert haben ] !!!
 

turtle

Top Contributor
Ich kenne mich mit SWT nicht gut aus, weiss aber, das SWT NICHT Plattform-unabhängig ist.

Wenn du beispielsweise mal im Eclipse-Ordner stöberst, findest du unter Windows Dateien wie swt-win32-4335.dll. Also bringt Eclipse für jede unterstütze Platttform entsprechende native Bibliotheken mit.

Zwar stimmt die Aussage das JAVA plattform-unabhängig ist, aber SWT definitiv nicht.

Dies hat aber auch den Vorteil, das eine Applikation exakt so aussieht wie eine native Anwendung. Ein Punkt der bei Swing immer wieder kritisiert wurde. Weiterhin ist die Performance üblicherweise sehr hoch, muss aber nicht überall so sein. Hat auch den Nachteil das Deployments schwieriger werden, weil halt native Libs mit installiert werden müssen.

Wohl nicht nur aus diesen Gründen wurde Swing zum Auslaufmodell erklärt. Das neue GUI-Toolkit nennt sich JavaFX und nach meinen ersten Gehversuchen kann ich sagen: Zu Recht.

Da ich SEHR grossen Wert auf absolute Java-Konformität lege, kommt SWT für mich nicht in Frage.
 

dzim

Top Contributor
Ok, @androbin, ich zitiere mich mal selbst:
Das Problem ist ja, das SWT ein Interface für die Platformspezifischen GUIs ist, das heisst, du musst imemr die jeweilige Jar-Datei für das korrekte System anbieten.
Das Interface selbst ist - wie für Java korrekt - plattformunabhängig. Die native GUI, die damit "ferngesteuert" wird, ist es natürlich nicht. Es gibt genausowenig WPF (Windoof) auf Linux, wie Cocoa (Mac) auf Windows. Einzig wie es mit GTK (Linux) ist, bin ich mir nicht sicher, da ja GTK (oder eher X-basierte Oberflächen?) IMHO immer auf Mac laufen sollten und es auch GTK (und andere Toolkits) für Windows gibt.
Wie auch immer es wird hier heftig von JNI Verwendung gemacht und das muss beim besten Willen nicht platformunabhängig sein, sonders ist aber so was von vom angesteuerten Kompilat abhängig!
 

dzim

Top Contributor
@turtle: Danke - ich bin nicht mehr allein hier, als Verteidiger von JavaFX (und nur noch mal für die, die es noch imer nicht verstanden haben: JavaFX 2+ ist nicht mehr der Skriptbasierte Blödsinn aus der Anfangszeit, wobei die Architekurideen (Scene, Stage, ...) anscheinend noch von dort stammen).

Heutzutage bevorzuge ich auch JavaFX vor SWT, aber: Die haben ein gutes Layouting (das ich einfacher verstehe, als das von JavaFX) und ich kann mit RAP (vereinfacht "SWT für's Web") auch Web-GUIs (und via Tabris auch native "Web"-GUIs für mobile Platformen (das widerspricht sich, ich weiss)) bauen. Und dann mit OSGi und man hat ein paar wunderbare allgemeine Frameworks, mit denen man für alles (Desktop, Web und Quasi-Mobile) entwickeln kann! Herrlich ;-)
 

eurit25

Mitglied
Schonmal Danke für eure Antworten.

Es sollte doch eigentlich machbar sein, die swt.jar für die jeweilige Plattform erst zur Laufzeit in den Classpath einzubinden oder?
Ich habe dazu diesen Blog gefunden, der das Vorgehen beschreibt: Select correct SWT jar for your OS and JVM at runtime.
Ich habe dabei nur das Problem, dass ich beim compilieren mit Eclipse den Ordner mit den einzelnen swt.jars nicht in meine .jar bekomme ohne gleich alle swt.jars in den Classpath mit aufzunehmen. Dann aber compiled Eclipse mit der obersten swt.jar und der obige Workaround funktioniert erst wieder nicht ^^ Wie beziehe ich also ein Verzeichnis innerhalb meines Projekts mit in die compilierte .jar ein um das Programm darauf zugreifen zu lassen?

Hat vielleicht jemand eine Idee wie das Vorhaben so umgesetzt werden könnte?

Gruß
 

Ruzmanz

Top Contributor
Damit du das Programm entwickeln kannst, führt kein Weg daran vorbei zumindest eine Library in dein Projekt einzubinden. Unter der Annahme, dass du dein Projekt manuell baust:

- In der MANIFEST.MS musst du den Link zur SWT.jar entfernen
- Alle nötigen SWT.jars musst du in das spezielle Verzeichnis stellen (== Verzeichnis, dass im Quellcode angegeben ist)
- Für den Programmstart brauchst du eine Klasse / Datei, die nicht auf SWT zugreift (== nichts davon importiert). In der main-Methode bindest du die richtige JAR-Datei ein (Select correct SWT jar for your OS and JVM at runtime) und dann startest du dein Programm mit
Code:
new Anwendung()
.

Habe jetzt keine Zeit das selbst zu testen, aber müsste prinzipiell funktionieren.
 

eurit25

Mitglied
Also es klappt jetzt fast so wie ich es mir vorstelle.
Ich habe über Eclipse mit einer swt.jar im Classpath compiliert, damit es zu keinen Compilierfehlern kommt. In der so erstellten .jar habe ich dann den Link zur swt.jar in der manifest.mf wieder herausgenommen und die Dateien wieder neu in die .jar verpackt.
Wenn nun meine diversen swt.jars in einem Ordner "lib" neben dem Programm liegen, klappt die Geschichte auch wunderbar.

Ich möchte die swt.jars aber eigentlich gerne in meine .jar mit hinein nehmen um eben nur die eine .jar verteilen zu müssen.
Hier (Select correct SWT jar for your OS and JVM at runtime) werden ja die swt.jar mit Hilfe einer URL zur Laufzeit in den Classpath eingebunden (siehe unnten). Hat jemand vielleicht eine Idee, ob man die URL auch so gestalten kann, dass sie auf einen Order und Datei innerhalb meines .jars zeigt?

Vermutlich müsste man diesen Part umschreiben:
Java:
public static void addJarToClasspath(File jarFile) 
{ 
   try 
   { 
       URL url = jarFile.toURI().toURL(); 
       URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
       Class<?> urlClass = URLClassLoader.class; 
       Method method = urlClass.getDeclaredMethod("addURL", new Class<?>[] { URL.class }); 
       method.setAccessible(true);         
       method.invoke(urlClassLoader, new Object[] { url });             
   } 
   catch (Throwable t) 
   { 
       t.printStackTrace(); 
   } 
}
Das File "jarFile" aus obigem Code sieht z.B. so aus: "lib/swt_linux_x64.jar"

Nur wie mach ich das? :D
Leider hört dort bei mir mein noch recht frisches Java Wissen auf.
 

Androbin

Bekanntes Mitglied
Ich zitiere aus Wikipedia:
SWT:
SWT wurde im Jahr 2001 von IBM für die Entwicklungsumgebung Eclipse entwickelt und wird kontinuierlich gepflegt. SWT nutzt dabei im Gegensatz zu Swing die nativen grafischen Elemente des Betriebssystems – wie das AWT von Sun – und ermöglicht somit die Erstellung von Programmen, die eine Optik vergleichbar mit „nativen“ Programmen aufweisen.

Allerdings leidet SWT auf einigen Nicht-Windows-Plattformen unter Effizienzproblemen, da es viele Merkmale eines Basistoolkits voraussetzt, welche – wenn nicht vorhanden – emuliert werden müssen (z. B. Z-Ordnung auf GTK+). Zudem sind die SWT-Bibliotheken nicht standardmäßig auf dem ausführenden System verfügbar und müssen mit der Anwendung ausgeliefert werden, während Swing Bestandteil der Java-Laufzeitumgebung (Java Runtime Environment, JRE) ist.

Bei SWT werden native Widgets durch dünne Wrapper eingebunden, anstatt Teile der Funktionalität in native Peer-Klassen auszulagern. Wegen der Verwendung dieser Ressourcen werden die SWT-Elemente „schwergewichtig“ genannt, im Gegensatz zu den „leichtgewichtigen“ Komponenten der Swing-Technik, die alle grafischen Elemente selbst erzeugt.

SWT kommt in einer ganzen Reihe von Anwendungen zum Einsatz, beispielsweise Eclipse selbst, Vuze und RSSOwl.

Geschwindigkeit:
SWT wurde als reaktionsschnellere und kompaktere Konkurrenz zu Swing entwickelt. Leistungsvergleiche zeigen allerdings, dass SWT nicht schneller als Swing ist und die Resultate stark vom Kontext und der Testumgebung abhängen.
 

eurit25

Mitglied
Und wie genau hilft mir das Zitat bei meinem konkreten Problem? Dass die Bibliotheken nicht standardmäßig dabei sind weiß ich ja. Und dass es verschiedene Versionen für verschieden Plattformen gibt auch.
Es geht ja darum die entsprechende swt.jar zur Laufzeit einzubinden, bevor die erste geladene Klasse SWT Elemente importiert.
 

Ruzmanz

Top Contributor
Ich bin mir nicht sicher, wie die Pfade in der JAR-Datei aussehen müssen ... Versuch einfach die URL in deine JAR-Datei zu setzen. Google hilft da weiter ... anstatt
Code:
URL url = jarFile.toURI().toURL();
sowas wie
Code:
URL url = new URL("jar:file:/meinPfad/meineJar.jar!/lib/")
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Swing Plattformunabhängig? AWT, Swing, JavaFX & SWT 11

Ähnliche Java Themen

Neue Themen


Oben