Swing (Java)
Swing ist ein plattformunabhängiges „Model-View-Controller“ GUI-Framework für Java, das einem Single-Thread-Programmiermodell folgt. Zusätzlich bietet dieses Framework eine Abstraktionsebene zwischen der Codestruktur und der grafischen Darstellung einer Swing-basierten GUI.
FoundationsEdit
Swing ist plattformunabhängig, da es komplett in Java geschrieben ist. Die vollständige Dokumentation für alle Swing-Klassen finden Sie im Java API Guide für Version 6 oder in der Java Platform Standard Edition 8 API Specification für Version 8.
ExtensibleEdit
Swing ist eine hochgradig modular aufgebaute Architektur, die das „Einstecken“ verschiedener benutzerdefinierter Implementierungen von spezifizierten Framework-Schnittstellen ermöglicht: Benutzer können ihre eigene(n) benutzerdefinierte(n) Implementierung(en) dieser Komponenten bereitstellen, um die Standardimplementierungen mit Hilfe von Javas Vererbungsmechanismus über javax.swing.LookAndFeel
zu überschreiben.
Swing ist ein komponentenbasiertes Framework, dessen Komponenten letztlich alle von der javax.swing.JComponent
-Klasse abgeleitet sind. Swing-Objekte feuern asynchron Ereignisse ab, haben gebundene Eigenschaften und reagieren auf einen dokumentierten Satz von komponentenspezifischen Methoden. Swing-Komponenten sind JavaBeans-Komponenten, die mit der JavaBeans-Spezifikation konform sind.
ConfigurableEdit
Da Swing stark auf Laufzeitmechanismen und indirekte Kompositionsmuster angewiesen ist, kann es zur Laufzeit auf grundlegende Änderungen seiner Einstellungen reagieren. Zum Beispiel ist eine Swing-basierte Anwendung in der Lage, ihre Benutzeroberfläche während der Laufzeit im laufenden Betrieb zu wechseln. Darüber hinaus kann der Benutzer seine eigene Look-and-Feel-Implementierung bereitstellen, was einheitliche Änderungen des Look-and-Feel bestehender Swing-Anwendungen ohne programmatische Änderungen am Anwendungscode ermöglicht.
Lightweight UI
Das hohe Maß an Flexibilität von Swing spiegelt sich in seiner inhärenten Fähigkeit wider, die nativen GUI-Steuerelemente des Host-Betriebssystems (OS) für die Anzeige zu überschreiben. Swing „malt“ seine Steuerelemente mithilfe der Java 2D-APIs, anstatt ein natives Benutzeroberflächen-Toolkit aufzurufen. Daher hat eine Swing-Komponente keine entsprechende native GUI-Komponente des Betriebssystems und kann sich selbst auf jede Art und Weise darstellen, die mit den zugrundeliegenden Grafik-GUIs möglich ist.
Im Kern basiert jedoch jede Swing-Komponente auf einem AWT-Container, da (Swings) JComponent
den (AWT-)Container erweitert. Dadurch kann sich Swing in das GUI-Management-Framework des Host-Betriebssystems einklinken, einschließlich der wichtigen Geräte-/Bildschirmzuordnungen und Benutzerinteraktionen, wie z. B. Tastendrucke oder Mausbewegungen. Swing „transponiert“ einfach seine eigene (betriebssystem-agnostische) Semantik über die zugrunde liegenden (betriebssystemspezifischen) Komponenten. So malt z. B. jede Swing-Komponente ihre Darstellung auf dem Grafikgerät als Reaktion auf einen Aufruf von component.paint(), der in (AWT-)Container definiert ist. Aber im Gegensatz zu AWT-Komponenten, die das Malen an ihr OS-natives „schwergewichtiges“ Widget delegiert haben, sind Swing-Komponenten für ihr eigenes Rendering verantwortlich.
Diese Umsetzung und Entkopplung ist nicht nur visuell, sondern erstreckt sich auch auf die Verwaltung und Anwendung von Swings eigener OS-unabhängiger Semantik für Ereignisse, die innerhalb seiner Komponentenhierarchien ausgelöst werden. Im Allgemeinen delegiert die Swing-Architektur die Aufgabe, die verschiedenen Varianten der Betriebssystem-GUI-Semantik auf ein einfaches, aber verallgemeinertes Muster abzubilden, an den AWT-Container. Aufbauend auf dieser verallgemeinerten Plattform wird eine eigene, reichhaltige und komplexe GUI-Semantik in Form des JComponent
-Modells etabliert.
Los gekoppelt und MVCEdit
Die Swing-Bibliothek macht regen Gebrauch vom Model-View-Controller-Software-Design-Pattern, das die Daten, die angezeigt werden, konzeptionell von den Bedienelementen der Benutzeroberfläche entkoppelt, über die sie angezeigt werden. Aus diesem Grund haben die meisten Swing-Komponenten zugehörige Modelle (die in Form von Java-Schnittstellen spezifiziert sind), und die Programmierer können verschiedene Standardimplementierungen verwenden oder ihre eigenen bereitstellen. Das Framework bietet Standardimplementierungen von Modellschnittstellen für alle seine konkreten Komponenten. Die typische Verwendung des Swing-Frameworks erfordert nicht die Erstellung eigener Modelle, da das Framework eine Reihe von Standardimplementierungen bereitstellt, die standardmäßig transparent mit der entsprechenden JComponent
-Unterklasse in der Swing-Bibliothek verbunden sind. Im Allgemeinen benötigen nur komplexe Komponenten, wie Tabellen, Bäume und manchmal Listen, die benutzerdefinierten Modellimplementierungen um die anwendungsspezifischen Datenstrukturen. Um ein gutes Gefühl für das Potenzial zu bekommen, das die Swing-Architektur ermöglicht, betrachten Sie die hypothetische Situation, in der benutzerdefinierte Modelle für Tabellen und Listen Wrapper über DAO- und/oder EJB-Dienste sind.
Typischerweise sind die Modellobjekte der Swing-Komponente dafür verantwortlich, eine prägnante Schnittstelle bereitzustellen, die Ereignisse, die abgefeuert werden, und zugängliche Eigenschaften für das (konzeptionelle) Datenmodell zur Verwendung durch die zugehörige JComponent definiert. Da das MVC-Muster insgesamt ein lose gekoppeltes Muster für kollaborative Objektbeziehungen ist, stellt das Modell die programmatischen Mittel zum Anhängen von Ereignis-Listenern an das Datenmodellobjekt bereit. Typischerweise sind diese Ereignisse modellzentriert (z. B. ein „Zeile eingefügt“-Ereignis in einem Tabellenmodell) und werden durch die JComponent-Spezialisierung in ein sinnvolles Ereignis für die GUI-Komponente abgebildet.
Zum Beispiel hat das JTable
ein Modell namens TableModel
, das eine Schnittstelle beschreibt, wie eine Tabelle auf Tabellendaten zugreifen würde. Eine Standardimplementierung davon operiert auf einem zweidimensionalen Array.
Die Ansichtskomponente einer Swing JComponent ist das Objekt, das verwendet wird, um die konzeptionelle GUI-Steuerung grafisch darzustellen. Ein Unterscheidungsmerkmal von Swing als GUI-Framework besteht darin, dass es sich auf programmatisch gerenderte GUI-Steuerelemente stützt (im Gegensatz zur Verwendung der nativen GUI-Steuerelemente des Host-Betriebssystems). Vor Java 6 Update 10 war diese Unterscheidung eine Quelle von Komplikationen beim Mischen von AWT-Steuerelementen, die native Steuerelemente verwenden, mit Swing-Steuerelementen in einer GUI (siehe Mischen von AWT- und Swing-Komponenten).
Schließlich bevorzugt Swing in Bezug auf die visuelle Komposition und Verwaltung relative Layouts (die die Positionsbeziehungen zwischen Komponenten angeben) im Gegensatz zu absoluten Layouts (die die genaue Position und Größe von Komponenten angeben). Diese Vorliebe für eine „flüssige“ visuelle Anordnung hat ihren Ursprung in der Applet-Betriebsumgebung, die das Design und die Entwicklung des ursprünglichen Java-GUI-Toolkits einrahmte. (Konzeptionell ist diese Sichtweise der Layout-Verwaltung derjenigen sehr ähnlich, die das Rendering von HTML-Inhalten in Browsern bestimmt, und adressiert dieselbe Reihe von Anliegen, die das erstere motivierten.)
Beziehung zu AWTEdit
Seit frühen Versionen von Java, stellt ein Teil des Abstract Window Toolkit (AWT) plattformunabhängige APIs für Komponenten der Benutzeroberfläche bereit. In AWT wird jede Komponente von einer nativen Peer-Komponente gerendert und gesteuert, die für das zugrunde liegende Windowing-System spezifisch ist.
Im Gegensatz dazu werden Swing-Komponenten oft als leichtgewichtig bezeichnet, da sie keine Zuweisung nativer Ressourcen im Windowing-Toolkit des Betriebssystems erfordern. Die AWT-Komponenten werden als schwergewichtige Komponenten bezeichnet.
Ein Großteil der Swing-API ist im Allgemeinen eher eine ergänzende Erweiterung des AWT als ein direkter Ersatz. Tatsächlich existiert jede Swing-Leichtgewichtsschnittstelle letztendlich innerhalb einer AWT-Schwergewichtskomponente, weil alle Komponenten der obersten Ebene in Swing (JApplet
JDialog
JFrame
und JWindow
) einen AWT-Container der obersten Ebene erweitern. Vor Java 6 Update 10 wurde von der Verwendung von leichtgewichtigen und schwergewichtigen Komponenten innerhalb desselben Fensters aufgrund von Inkompatibilitäten der Z-Reihenfolge generell abgeraten. Spätere Versionen von Java haben diese Probleme jedoch behoben, und sowohl Swing- als auch AWT-Komponenten können nun in einer GUI ohne Z-Reihenfolge-Probleme verwendet werden.
Die Kern-Rendering-Funktionalität, die von Swing verwendet wird, um seine leichtgewichtigen Komponenten zu zeichnen, wird von Java 2D bereitgestellt, einem weiteren Teil der JFC.
Beziehung zu SWTEdit
Das Standard Widget Toolkit (SWT) ist ein konkurrierendes Toolkit, das ursprünglich von IBM entwickelt wurde und nun von der Eclipse-Community gepflegt wird. Die Implementierung von SWT hat mehr Gemeinsamkeiten mit den schwergewichtigen Komponenten von AWT. Dies bietet Vorteile wie eine genauere Übereinstimmung mit dem zugrundeliegenden nativen Windowing-Toolkit, allerdings auf Kosten einer erhöhten Exposition gegenüber der nativen Plattform im Programmiermodell.
Es gab erhebliche Diskussionen und Spekulationen über die Leistung von SWT im Vergleich zu Swing; einige deuteten an, dass SWT’s starke Abhängigkeit von JNI es langsamer machen würde, wenn die GUI-Komponente und Java Daten kommunizieren müssen, aber schneller beim Rendern, wenn das Datenmodell in die GUI geladen wurde, aber dies wurde in keiner Weise bestätigt. Ein ziemlich gründlicher Satz von Benchmarks im Jahr 2005 kam zu dem Schluss, dass weder Swing noch SWT im allgemeinen Fall eindeutig besser abschneiden.