Dieser Artikel soll über die Möglichkeiten der Entwicklung grafischer Anwendungen mit der Swing-Bibliothek [1] informieren, Anfängern eine Starthilfe geben und Kenner zumindest mit Hintergrundinformationen versorgen.
Redaktioneller Hinweis: Es empfiehlt sich, den ersten Teil dieses Artikels („Java, Teil 1 – Einführung in eine moderne Sprache“, freiesMagazin 10/2009 [2]) nachzulesen, falls die Grundlagen von Java noch nicht verinnerlicht sind.
Swing – Was ist das?
Bei Swing handelt es sich um eine vorprogrammierte Klassenbibliothek, mit deren Hilfe grafische Anwendungen unter Java entwickelt werden können. Es ist also nicht erforderlich zu definieren, was ein Fenster oder was ein Textfeld ist und wie sich solche Elemente verhalten können. Sie werden einfach „benutzt“, in dem ein Objekt erzeugt wird, das beispielsweise vom Typ „Fenster“ ist. Ungeduldige können sich bei Sun direkt die vielen vordefinierten Elemente ansehen [3].
Vorbereitung
Es sollte auf eine Entwicklungsumgebung zurückgegriffen werden, um die Vorzüge der automatischen Vervollständigung und der Syntaxprüfung zu genießen. So lassen sich Tippfehler sehr leicht aufspüren. Wie im ersten Teil bereits erläutert, bieten sich für die in diesem Artikel beschriebenen Zwecke besonders Netbeans und Eclipse an, die beide frei und gleichberechtigt sind.
In diesem Artikel wird aber die Einrichtung von Eclipse beschrieben. Bei vielen Distributionen kann das Paket eclipse installiert werden oder direkt die binären Dateien der aktuellen Version von der Homepage [4] heruntergeladen werden.
Es handelt sich um einen Ordner, in dem die Startdatei direkt ausführbar ist. Dieser wird dann zum Beispiel mit root-Rechten in das Verzeichnis /opt verschoben. Einen Starter im Menü muss man dann allerdings manuell angelegen. Beim ersten Starten erscheint die Aufforderung, einen Workspace anzulegen. Das ist das Verzeichnis, in dem alle relevanten Dateien der Projekte abgelegt werden.
Sollte sich in diesem Fenster bereits Eclipse beschweren, dass lediglich eine „gij“-Version von Java gefunden wurde, könnten Fehler auftreten, da diese Version nicht offiziell von Eclipse unterstützt wird. Keine Probleme treten auf, wenn das offizielle sun-java6-jdk und die sun-java6-jre installiert sind. Eine „openjdk“-Variante tut es aber auch, falls großer Wert auf freie Lizenzen gelegt wird. Mit dem Befehl
$ java -version |
kann geprüft werden, ob die Installation geglückt ist und auch erkannt wird. Sollte nicht die gewünschte Ausgabe erscheinen, kann es sein, dass mehrere Compiler und Laufzeitumgebungen parallel installiert sind. Da hilft meist die manuelle Einstellung durch den Befehl
# update-alternatives --config java |
sofern das Alternativensystem [5] unter der benutzten Distribution verfügbar ist.
Nach Bestätigung des Pfades zum Workspace öffnet sich ein Begrüßungsbildschirm. Ist dieser oben rechts weggeklickt, öffnet sich zum ersten Mal die Java-Ansicht und die Programmierung kann beginnen. Es ist wichtig, die Dateien im Workspace nie direkt zu manipulieren, sondern nur über Eclipse. Ansonsten stimmen die Metadaten nicht mehr, und der Workspace kann zerstört werden.
Die Programmierung mit Swing
Zunächst muss ein neues Projekt erstellt werden. Dies gelingt unter „File » New » Java Project“. Nun wird dem Projekt noch ein Name gegeben (z. B. „SwingApp“) und gegebenenfalls die JRE eingestellt, zum Beispiel auf java-6-sun-1.6.0.16 oder welche JRE auch immer installiert ist. Der nächste Dialog kann ohne Änderungen bestätigt werden. Jetzt wird dem Projekt eine Klasse hinzugefügt, indem mit rechts auf das Projekt geklickt und „New » Class“ auswählt wird. Die Klasse wird in diesem Beispiel View gegannt, da sie eine grafische Oberfläche bereitstellen soll. Achtung: Klassennamen beginnen immer mit einem Großbuchstaben.
Wie werden nun Fenster mit Java erzeugt? Zunächst muss eine Instanz von JFrame erzeugt werden, welche das Hauptfenster darstellt. JFrame ist die gängigste Klasse, um ein Fenster mit Java zu erzeugen. Es werden bereits Grundfunktionen wie Fensterdekorationen bereitgestellt, ohne dies explizit zu programmieren. Bei Betrachtung des Quellcodes sollten alle Befehle problemlos nachvollziehbar sein:
public class View extends JFrame { View() { setSize(300, 300); setTitle("Minimal JFrame"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null); setVisible(true); } } |
View ist also direkt von JFrame abgeleitet. Das bedeutet, dass jede Instanz der Klasse View auch eine Instanz der Klasse JFrame ist. Im Konstruktor kann deshalb nun direkt die Größe und der Titel des Fensters festlegt werden, da die Klasse diese Variablen und Methoden von JFrame geerbt hat. Des Weiteren wird bestimmt, dass die Anwendung ordnungsgemäß beendet wird, sobald das Fenster geschlossen wird – ansonsten würde die Anwendung für immer als Hintergrundprozess weiterlaufen. Letztlich wird der Ort des Fensters in die Mitte des Bildschirms und das Fenster sichtbar gesetzt.
Wenn der obige Quelltext einfach eingefügt wird, wird sich Eclipse beschweren, da die Klasse JFrame und deren Eigenschaften nicht bekannt sind. Durch Bewegung des Cursors hinter das Wort JFrame und Druck von „Strg“ + „Space“ wird die Umgebung angewiesen, automatisch den passenden Import hinzuzufügen. Sollte dies aus irgendwelchen Gründen nicht funktionieren, können für das Beispiel einfach
import javax.swing.*; import java.awt.*; import java.awt.event.*; |
oben in die View Klasse als erste Zeilen eingefügt werden.
Die Klasse ist für sich allein nicht ausführbar, da sie keinen Einstiegspunkt hat, welcher immer die main-Methode sein muss. Es wird also noch eine Klasse hinzugefügt, etwa mit dem Namen Start. Aus Bequemlichkeit kann dabei das Häkchen „public static void main (String[]args)“ gesetzt werden und dieser Methodenkopf muss nicht mehr von Hand eingetippt werden. Die Klasse Start soll nichts anderes tun, als eine Instanz der Klasse View ohne Parameter zu erzeugen:
public class Start { public static void main(String[] args) { View myView = new View(); } } |
Das Programm wird nun gestartet, indem die Klasse Start markiert und „Strg“ + „F11“ gedrückt wird. Es erscheint ein leeres Fenster mit der Größe 300×300 Pixel. In diesem könnten nun direkt weitere Elemente – dies ist erst seit neueren Versionen möglich – oder neue Container platziert werden, die wiederum atomare Elemente aufnehmen können. Als atomar werden Komponenten bezeichnet, die keine anderen Komponenten enthalten können, wie zum Beispiel Buttons, Beschriftungen oder Rahmen.
An dieser Stelle wird auf den Stolperstein Layout-Management hingewiesen. Dabei sind frustrierende Erlebnisse bei Einsteigern leider an der Tagesordnung. Würde im Beispiel einfach ein Button hinzugefügt werden, so würde er das gesamte Fenster füllen. Würde die manuelle Größenangabe des Frames weggelassen werden, wäre das Fenster trotz des Buttons 0px groß. Doch gibt es reichlich Möglichkeiten, die Elemente ansehnlich automatisch anordnen zu lassen. Sollten die vorgegebenen Layouts nicht genutzt werden, kann jedes Element pixelgenau positioniert werden. Es muss zunächst das Layout des Fensters auf null gesetzt werden (null ist in diesem Zusammenhang ein Schlüsselwort, kein numerischer Wert). Nun wird als erstes atomares Element ein Button erzeugt und bestimmt, an welcher Position er gezeichnet werden und wie groß er sein soll. Schließlich wird er dem Fenster hinzugefügt. Es werden folgende Zeilen im Konstruktor der View-Klasse ergänzt:
setLayout(null); JButton Button=new JButton("Test"); Button.setBounds(10, 10, 80, 25); add(Button); |
Wichtig ist, dass wirklich jedes Element absolut positioniert werden muss, sofern das null-Layout verwendet wird. Das gilt aber nicht für die Elemente in hierarchisch untergeordneten Containern, die ihr eigenes Layout benutzen. Container sind die wohl wichtigste Struktur innerhalb von JFrames. Sie sind sozusagen Meta-Elemente, die wiederum eigene Elemente enthalten. Dies soll nun ausprobiert werden. Soll zum Beispiel der Name und das Passwort eines Nutzers abgefragt und ihm die Möglichkeit gegeben werden, die Eingabe abzuschicken oder zu löschen, werden dafür zwei beschriftete Eingabefelder für Text benötigt. Die Textfelder für die Eingabe des Namens und Passworts sollen mit ihrem Label (Beschriftung) nebeneinander stehen und darunter sollen die Buttons angeordnet werden. Die Klasse könnte etwa so aussehen:
public class View extends JFrame { View() { // Erzeugung der Elemente JLabel nameLB= new JLabel("Name:"); JLabel passLB= new JLabel("Pass:"); JTextField nameTf= new JTextField(5); JPasswordField passPF= new JPasswordField(5); JButton resBut= new JButton("Reset"); JButton sendBut= new JButton("Send"); // Erzeugen der Panels JPanel tfPanel= new JPanel(); JPanel butPanel= new JPanel(); // Hinzufuegen der Elemente zum oberen Panel tfPanel.add(nameLB); tfPanel.add(nameTf); tfPanel.add(passLB); tfPanel.add(passPF); // Hinzufuegen der Elemente zum unteren Panel butPanel.add(resBut); butPanel.add(sendBut); // Einstellungen des Fensters setSize(300, 300); setTitle("Minimal JFrame"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null); setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); // Hinzufuegen der Panels zum Fenster add(tfPanel); add(butPanel); pack(); setVisible(true); } } |
Listing: View.class
Das JPasswordfield erlaubt die Eingabe von Text mit anonymisiertem Feedback. Unter Windows würden Sternchen angezeigt werden, unter GNOME Kreise, doch prinzipiell kann je nach Geschmack jedes Feedbacksymbol festlegt werden. Der Parameter 5 bei der Erzeugung der Textfelder gibt die Breite der Felder in Zeichen an. Als Container wird im Beispiel JPanel gewählt, welcher eigene Komponenten aufnimmt. Es wurde kein Layout für die Panels vorgegeben, da das Standardlayout gut passt. Es wird standardmäßig ein FlowLayout verwendet, welches die Elemente von links nach rechts, mit 5 Pixel vertikalem sowie horizontalem Puffer mittig ausrichtet. Dem Hauptfenster wurde ein – syntaktisch leider kompliziertes – BoxLayout entlang der vertikalen Achse zugewiesen. Das sorgt dafür, dass die beiden Panels untereinander angeordnet werden. Die Anweisung setSize(300, 300) wird nun ignoriert, da auch pack() auftaucht. Das bezweckt, dass das Fenster genauso groß wird, wie es die Elemente und das Layout erfordern. Da Puffer in den FlowLayouts vorhanden sind, führt dies nicht zu unschönen Berührungen von Elementen mit dem Rand des Hauptfensters.
Weitere interessante Layouts sind das GridLayout und das BorderLayout. Ersteres ordnet die Elemente, wie der Name vermuten lässt, in einer gleichmäßigen Gitterstruktur an. Letzteres kennt fünf Positionen für seine Elemente: Norden, Osten, Süden, Westen und Mitte. Das mag auf den ersten Blick wenig sinnvoll erscheinen. Doch verglichen mit dem Aufbau moderner Webseiten mit Header, linker Navigation, Inhalt, rechter Navigation und Fußzeile, lassen sich schnell die Parallelen erkennen.
Ein Element, das gezielt eingesetzt werden sollte, ist der Rahmen. Um einen Rahmen um ein Element oder auch um ein Panel zu zeichnen, wird zum Beispiel geschrieben:
Element.setBorder(BorderFactory. createEtchedBorder(EtchedBorder.RAISED)); |
Es würde ein erhobener dreidimensionaler Rahmen um das Element mit dem Namen Element gezeichnet werden. Dieser könnte auch noch beschriftet werden.
Um ein Element mit einem Tooltip auszustatten (ein kurzer informativer Text), wird z. B. um den Button in der View-Klasse damit zu erweitern, folgende Zeile eingefügt:
sendBut.setToolTipText("Sendet die Daten ab"); |
Schwebt nun der Mauszeiger für einige Zeit über dem Button, wird der Text eingeblendet. Sind die wesentlichen Konzepte der Layouts verinnerlicht und die Funktionsweise von pack(), setSize() und setLayout() nachvollzogen, können ohne grafischen GUI-Builder ansehnliche Applikationen erstellt werden, wobei diese auch nicht verteufelt werden sollen. Tatsächlich sind bei komplexen Projekten GUI-Builder sehr populär.
Benutzerinteraktion
Als Beispiel dafür, wie nun Buttons zum „Leben“ erweckt werden, wird der Reset-Button so implementiert, dass er beide Eingabefelder wirklich löscht. Das Ereignis des Klicks auf den Button muss abgefangen werden. Dies erledigt ein EventListener. Dieser kann als anonyme Klasse direkt in die Klasse geschrieben werden, in der der größte Zusammenhang zur Funktionalität besteht. Fortgeschrittene verwenden eine eigene „Controller“-Klasse, welche sich ausschließlich um solche Funktionen kümmert. In diesem Fall wird diese neue Klasse in die Klasse View geschrieben.
resBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { nameTf.setText(); passPF.setText(); } }); |
Damit innerhalb dieser Klasse auf die Textfelder zugegriffen werden kann, müssen sie zuvor als final deklariert werden. Also ist final in den beiden Zeilen zu ergänzen:
final JTextField nameTf= new JTextField(5); final JPasswordField passPF= new JPasswordField(5); |
Es wird also dem Button einen ActionListener hinzugefügt, der die Methode actionPerformed implementiert. Dort kommt die gewünschte Anweisung, in diesem Falle das Löschen der Eingabefelder, hinzu.
Historisches
Um direkt die wichtigste Frage vorweg zu klären: Der Name „Swing“ war der Arbeitstitel dieser Klassenbibliothek (eine logisch zusammengehörige Gruppe von Klassen), weil einer der Entwickler glaubte, dass diese Musikrichtung wieder modern werden würde.
Blickt man auf die Entstehungsgeschichte der „Java Foundation Classes“ (JFC [6]), zu denen Swing gehört, lässt sich eine deutliche Entwicklung zum Positiven feststellen. Während die ersten Versionen von Java noch mit dem unzureichenden „Abstract Windowing Toolkit“ (AWT [7]) ausgeliefert wurden, wurde aus den Fehlern gelernt und eine nahezu vollständig neue Implementierung vorgenommen. Das AWT brachte nur wenige GUI-Elemente mit (einzelne Teile einer grafischen Anwendung wie Buttons, Scrollbalken oder Schieberegler), war zum Teil unhandlich zu programmieren und nur in einem geringen Maße plattformunabhängig, da der Programmierer auf die grafischen Grundelemente beschränkt war, die auf jedem Betriebssystem vorhanden waren. Somit wurde auch teilweise der Speicher des Betriebssystems beansprucht und die Elemente sahen oftmals doch sehr unterschiedlich auf den verschiedenen Plattformen aus. Durch die Folgen der noch nicht ganz durchdachten Ereignisbehandlung – mit Ereignissen sind zum Beispiel das Klicken auf einen Button oder die Eingabe von Text gemeint – war eine saubere Strukturierung des Quellcodes noch nicht richtig möglich.
An dieser Stelle verfolgt Swing einen radikaleren Ansatz. Die Komponenten werden nun größtenteils von Swing selbst gezeichnet, so dass Aufrufe an das darunter liegende Betriebssystem seltener nötig sind. Damit steht eine Vielzahl neuer, komplexer und bereits definierter Elemente zur Verfügung. Dadurch werden die Applikationen noch unabhängiger von der ausführenden Plattform. Die nun mögliche „MVC“-Architektur (Model-View-Controller [8]) macht es dem Entwickler heute leichter, den Code, der jeweils für die Grafikelemente, die Interaktion des Benutzers mit dem Programm und die eigentliche Programmlogik verantwortlich ist, zu modularisieren. Dies erhöht die Lesbarkeit und Wartbarkeit des Codes ungemein. Elemente, die von Swing selbst gezeichnet werden, heißen auch leichtgewichtige Komponenten und analog dazu heißen Elemente, die z. B. durch Aufruf an den Windows-UI-Manager gezeichnet werden, schwergewichtige Komponenten. Letztere sind auch heute noch nötig: Insbesondere die Fenster der höchsten Ebene und Dialoge arbeiten auf diese Weise. Heute verfügen die JFC über sämtliche gängigen Elemente wie Auswahllisten, Buttons, Labels, Checkboxen, Radiobuttons, sowie über komplexe Elemente wie Dateiauswahldialoge.
Als Hauptproblem muss erwähnt werden, dass die Swing-Methoden weitestgehend nicht threadsicher sind, sodass sich der Entwickler selbst um Parallelitätsprobleme kümmern muss.
Performance – Halbwahrheiten und Trugschlüsse
Es ist wahr: Java ist nicht immer die performanteste Lösung. Die Plattformunabhängigkeit wird durch eine relativ hungrige JVM (Java Virtual Machine, die Schicht zwischen dem Bytecode und dem Betriebssystem) teuer erkauft – das ist allerdings eine grundsätzliche Frage, die bei allen derartigen Laufzeitumgebungen eine Rolle spielt, nicht nur bei Java. Es sind die Schritte zu bedenken, die erforderlich sind, um eine Swing-Applikation darstellen zu können. Der Quellcode wird zunächst in einen binären Zwischencode kompiliert. Dieser ist jetzt bereits plattformunabhängig. Soll das Programm nun ausgeführt werden, muss die JVM das Programm in die jeweils plattformkonforme Maschinensprache übersetzen. Und wer jemals grafische Anwendungen in Assembler geschrieben hat, wird sicherlich die Problematik erkennen. Hinter vermeintlich einfachen Fensterelementen können sich immens aufwendige Speicheroperationen verbergen.
Look and Feel
Eine große Stärke von Swing ist die Unterstützung sowohl nativer, als auch freier optischer Themen. Während die Themen von proprietären Betriebssystemen nur auf der jeweiligen Plattform zur Verfügung stehen, gibt es auch freie Java-Themen, die auf jeder Plattform genau gleich aussehen. Namentlich zum Beispiel das moderne „Metal“-Theme, welches noch unterschiedliche Farbschemata enthält, und das etwas altertümliche „Motif“-Theme. Zu den Farbschemata sei gesagt, dass farblich ohnehin völlige Freiheit bei nahezu allen Swing-Elementen besteht. Auf diesem Wege bieten sich sowohl dem Entwickler als auch dem Nutzer Auswahlmöglichkeiten.
Der Entwickler kann ein bestimmtes „Look and Feel“ (L&F) vorgeben, anderenfalls kann der Nutzer das Erscheinungsbild der Anwendung nachträglich durch Parameter im Aufruf beeinflussen. Besonders interessant für Linux-Anwender ist das GTK-L&F, welches originalgetreu wiedergegeben wird. So lassen sich Swing-Anwendungen unter Linux nahtlos in jedes Desktop-Thema integrieren, mitsamt Fensterdekoration und eventuellen Hotkey-Einstellungen.
Darüber hinaus lassen sich eigene Themes erstellen und sogar eine Kombination aus verschiedenen Themes nutzen. Möchte der Entwickler beispielsweise eine Darstellung, die dem jeweils aktuellen Systemthema entspricht, so wird folgende Anweisung, möglichst als ersten Schritt, der Anwendung hinzugefügt. (Ansonsten erzeugt der erste Konstruktoraufruf einer Swing-Komponente bereits implizit eine Instanz der Klasse ComponentUI und gibt damit ein L&F vor.):
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); |
Die Anweisung kann Fehler verursachen, die behandelt werden müssen. Für einen schnellen Test wird lediglich die Import-Anweisung hinzugefügt, die Maus auf den rot markierten Code bewegt und auf „Surround with try/catch“ geklickt.
Andersherum kann der Benutzer mit folgendem Aufruf beispielsweise das GTK-L&F erzwingen, wenn er das Programm aus der Konsole und nicht aus einer Entwicklungsumgebung startet – falls kein anderes explizit vorgegeben ist (MyApp steht im Beispiel für die aufgerufene Klasse):
$ java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp |
Es sei angemerkt, dass manche Komponenten – milde gesagt – unerwartet dargestellt werden können, wenn während des Design-Prozesses ein anderes L&F angenommen wurde. So kann zum Beispiel der Text auf Buttons im mitgelieferten Metal-L&F manchmal nicht dargestellt werden, da die Schriftgröße zu groß für den Button wird. In diesem Falle würde auf dem Button nur „..“ , anstatt der korrekten Beschriftung angezeigt werden. Diese Feinheiten sollten stets beachtet werden und die unterschiedlichen L&F-Einstellungen vorher getestet werden. Im Zweifelsfall ist es am sichersten, das Metal-L&F vorzugeben.
Eine weitere interessante Möglichkeit ist das Ändern des L&F zur Laufzeit der Anwendung. Es sollte darauf geachtet werden, dass eventuelle Änderungen der Proportionen nicht zu unschönen freien Flächen führen. Es sollte daher nach Änderung des L&F ausgeführt werden (MyFrame steht für den entsprechenden MyFrame.pack()). Das gilt natürlich nur, wenn sich das mit dem verwendeten Layout verträgt. Es lassen sich optische Effekte bis zur völligen Individualisierung des Aussehens jedes einzelnen Elements erzielen, was zum Beispiel für Spiele sehr oft zur Anwendung kommt.
Design
Jeder hat sich schon einmal über eine verwirrende, unzureichend dokumentierte oder schlicht unzureichend funktionale GUI geärgert. Dies sollte genug Motivation sein, es selbst besser zu machen. GUI-Design erfordert Vorüberlegungen, gute Strukturierung des Codes und eine Testphase. Gerade wegen den zahllosen Möglichkeiten, die Elemente anzuordnen, muss die Übersicht bewahrt werden und eine sinnvolle Einteilung festgelegt werden.
Zunächst muss beantwortet werden, wozu die GUI genau dienen soll. Ist sie ein Monitor, eine Kontrollschnittstelle, eine Desktopanwendung oder erfüllt sie gar mehrere Aufgaben? Soll ein Desktopanwendung, die aus mehreren Elementen besteht, erstellt werden, so bietet sich die Nutzung von internen Frames an. In einem großen Hauptfenster können dann beliebig viele weitere Fenster geöffnet werden, welche aber immer noch vom Hauptfenster abhängen. Mit einer Minimierung des Hauptfensters verschwinden also auch alle zusätzlichen Fenster in der Taskleiste. Beispiele für derartige Anwendungen sind Bildbearbeitungsprogramme, Texteditoren oder Chatprogramme. Wenn eine klare Abgrenzung zwischen verschiedenen Aufgaben einer GUI möglich ist, sollte die GUI auch unterteilt werden. Um den Nutzer nicht mit einem Wust aus Daten und Interaktionsmöglichkeiten zu überfrachten, können auch mehrere Fenster erstellt werden, die jeweils bei Bedarf sichtbar geschaltet, fokussiert oder aktiviert werden können.
Eine andere Möglichkeit ist die Nutzung von Tabs (Karteikarten), mit denen eine GUI in sinnvolle Bereiche unterteilt werden kann.
Soll die GUI ohnehin nicht sehr viele Komponenten enthalten, ist es sinnvoller, lediglich Rahmen um einzelne Gruppen von Elementen zu implementieren. In jedem Falle sollte eine intuitive Beschriftung gewählt und die Unicode-Unterstützung von Swing nicht zu stark missbraucht werden. Elemente, die mit kryptischen Pfeilen, Regenschirmen, Sternen oder sonstigen Dingbats beschriftet sind, erschließen sich dem Nutzer nicht ohne weiteres. Zur Bedienfreundlichkeit tragen noch Tooltips bei, die nahezu für jede Komponente implementiert werden können.
Schlusswort
Mit den JFC steht unter Java eine mächtige Bibliothek zur Entwicklung von grafischen Anwendungen bereit. In einigen Bereichen zeigen sich jedoch Schwächen in der Syntax. Zum Teil sind die Konstruktionen nicht immer einheitlich und intuitiv schlicht nicht zu erfassen. Auch kann die Performance leiden, wenn nicht die integrierten Themes benutzt werden. An der Verbesserung der Performance wird allerding aktuell hart gearbeitet (Stichwort: Just-In-Time-Compiler [9]), sodass noch einige Verbesserungen in Aussicht sind.
Die erste Anlaufstelle für weitere Informationen ist die Tutorial-Page von Sun [10].
Links
- http://de.wikipedia.org/wiki/Swing_(Java)
- http://www.freiesmagazin.de/freiesMagazin-2009-10
- http://java.sun.com/docs/books/tutorial/ui/features/components.html
- http://www.eclipse.org
- http://wiki.ubuntuusers.de/Alternativen-System
- http://en.wikipedia.org/wiki/Java_Foundation_Classes
- http://en.wikipedia.org/wiki/Abstract_Windowing_Toolkit
- http://de.wikipedia.org/wiki/Model_View_Controller
- http://en.wikipedia.org/wiki/Just-in-time_compilation
- http://java.sun.com/docs/books/tutorial/uiswing/components/index.html