NetBeans RCP Entwicklerheft - Das
←
→
Transkription von Seiteninhalten
Wenn Ihr Browser die Seite nicht korrekt rendert, bitte, lesen Sie den Inhalt der Seite unten
NetBeans RCP
Das
Entwicklerheft
Jürgen Petri
- Behan
d
- Modula elt NetBeans 6
r
- FormB e Entwicklung
u
- Fenste ilder Matisse
r
- Nodes, verwaltung
DataOb
jects, W
izards ...
O’Reilly
®NetBeans RCP
Das Entwicklerheft
Jürgen Petri
Beijing • Cambridge • Farnham • Köln • Paris • Sebastopol • Taipei • TokyoDie Informationen in diesem Buch wurden mit größter Sorgfalt erarbeitet. Dennoch können Feh- ler nicht vollständig ausgeschlossen werden. Verlag, Autoren und Übersetzer übernehmen keine juristische Verantwortung oder irgendeine Haftung für eventuell verbliebene Fehler und deren Folgen. Alle Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt und sind möglicherweise eingetragene Warenzeichen. Der Verlag richtet sich im Wesentlichen nach den Schreibweisen der Hersteller. Das Werk einschließlich aller seiner Teile ist urheberrechtlich ge- schützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfil- mung sowie Einspeicherung und Verarbeitung in elektronischen Systemen. Kommentare und Fragen können Sie gerne an uns richten: O’Reilly Verlag Balthasarstr. 81 50670 Köln Tel.: 0221/9731600 Fax: 0221/9731608 E-Mail: kommentar@oreilly.de Copyright der deutschen Ausgabe: © 2008 by O’Reilly Verlag GmbH & Co. KG 1. Auflage 2008 Java™ und alle auf Java basierenden Warenzeichen und Logos sind in den USA und in allen an- deren Ländern Warenzeichen oder registrierte Warenzeichen von Sun Microsystems, Inc. O’Reilly Media, Inc. und der O’Reilly Verlag GmbH & Co. KG sind von Sun Microsystems Inc. un- abhängig. »Entwicklerhefte« und »A Developer’s Notebook Series« und darauf basierende Warenzeichen und Logos sind Warenzeichen von O’Reilly Media und dürfen nicht ohne schriftliche Genehmigung verwendet werden. Bibliografische Information Der Deutschen Bibliothek Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar. Lektorat: Christine Haite, Köln Fachgutachter: Markus Jais, München & Jens Boß, Münster Korrektorat: Petra Bromand, Düsseldorf Satz: G&U Technische Dokumentation GmbH, Flensburg; www.gundu.com Umschlaggestaltung: Edie Freedman, Boston & Michael Oreal, Köln Produktion: Karin Driesen, Köln Belichtung, Druck und buchbinderische Verarbeitung: Druckerei Kösel, Krugzell; www.koeselbuch.de ISBN-13 978-3-89721-724-9 Dieses Buch ist auf 100% chlorfrei gebleichtem Papier gedruckt.
Inhalt
Über die Entwicklerhefte . . . . . . . . . . . . . . . . . . . . . . . . VII
Über dieses Buch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XI
Kapitel 1: Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Modulare Entwicklung 1
Eigenschaften eines Moduls 2
Anlage eines Moduls 4
Abhängigkeiten verwalten 7
Versionierung 9
Installation von Modulen 11
Exkurs: Die Beispielapplikation 13
Kapitel 2: Formulare . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Form Builder 19
Anlage eines Formulars 21
Event-Handling 28
Modifikation von generiertem Code 30
Kapitel 3: Die Window System API . . . . . . . . . . . . . . . . . 33
Fenster erzeugen 34
Lebenszyklus verwalten 43
Die Positionierung der Fenster 47
Eigene Docking Modes erzeugen 52
Fenster gruppieren 56
Persistierung des Layouts 58
IIIKapitel 4: Die Lookup API . . . . . . . . . . . . . . . . . . . . . . . 65
Services finden 65
Erweiterungspunkte 69
Lose gekoppelte Kommunikation zwischen Komponenten 73
Dynamisierung und Benachrichtigung 80
ProxyLookups 87
ActionsGlobalContext 89
Kapitel 5: Die Actions API . . . . . . . . . . . . . . . . . . . . . . . 97
Globale Actions 97
Einfügen in Menüs, Toolbars etc. 104
Keybindings 106
Presenter 107
Kapitel 6: Die Nodes API und die Explorer API . . . . . . . . 111
Nodes 112
ExplorerViews 119
Schlüsselbasierte Node-Hierarchien 125
Austauschen von Views 133
Langläufiges Ermitteln von Kindelementen 135
Kontextsensitive Aktionen 140
Nodes dekorieren 153
PropertySheets 159
Inplace-Property-Editoren 163
Kapitel 7: Die File System API . . . . . . . . . . . . . . . . . . . 167
SystemFileSystem 168
Zugriff auf das lokale Dateisystem 168
Zusätzliche Attribute 173
Überwachung 174
Kapitel 8: Die Datasystems API . . . . . . . . . . . . . . . . . . . 175
Unterstützung neuer Dateitypen 175
Zustandsabhängige Fähigkeiten 190
IV InhaltKapitel 9: Die Dialogs API . . . . . . . . . . . . . . . . . . . . . . 199
Benachrichtigungen 199
Standarddialoge 201
Eigene Dialoge 203
Mehrseitige Dialoge 208
Kapitel 10: Einstellungen . . . . . . . . . . . . . . . . . . . . . . . 227
Integration in das Options-Panel 227
Kapitel 11: Hilfe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Eigene HelpSets erzeugen 235
Entfernen der Standardhilfe 244
Kapitel 12: Branding . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Selbständige Applikation 247
Splash-Screen 249
Kapitel 13: Distribution & Updates . . . . . . . . . . . . . . . . 251
Distribution 251
Installer 253
Online-Updates 257
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Inhalt VÜber die Entwicklerhefte
So, Sie haben das Buch also gekauft. Cool. Natürlich fragen Sie sich,
warum die Bücher dieser Reihe solche merkwürdigen Einbände haben,
die eher an ein Notizbuch erinnern. Ist das hier wirklich von O’Reilly? Wo
sind die Tiere? Und ist es denn wirklich nötig, eine weitere Buchreihe
herauszubringen? Könnte dies nicht auch einfach ein »Kochbuch« sein?
Wie wär’s mit einem »Nutshell«-Band oder mit einem »Hacks«-Buch? Auf
diese Fragen gibt es eine kurze Antwort: Ein Entwicklerheft ist nichts
davon – die Idee, die diesen Büchern zugrunde liegt, erschien uns tat-
sächlich so wichtig, dass wir mit einem völlig neuen Look & Feel heraus-
gekommen sind, komplett mit eigenem Umschlag, eigenen Schriften und
sogar mit Randnotizen. Dies alles ist das Ergebnis unserer Bemühungen,
Ihnen ein Buch an die Hand zu geben, das Ihnen bei der praktischen
Arbeit weiterhilft.
Die neunziger Jahre waren dadurch gekennzeichnet, dass alle alles ler-
nen wollten. (Warum auch nicht? Damals hatten wir alle sechsstellige
Gehälter bei Dotcom-Firmen.) Das neue Jahrhundert dagegen ist durch
die Fülle an Informationen geprägt. Niemand hat noch die Zeit (oder das
Geld), 600-seitige Wälzer durchzulesen und dabei 200 Dinge zu lernen,
von denen aber vielleicht nur vier auf die momentane Tätigkeit anwend-
bar sind. Wäre es nicht viel besser, sich neben einen jener Super-Pro-
grammierer zu setzen und ihm über die Schulter zu schauen? Jemanden
zu fragen, der in diesen Dingen zu Hause ist, wie er oder sie diese eine
verzwickte Aufgabe erledigt oder jenes Threading-Problem bei der Arbeit
mit Piped-Streams vermieden hat? Bücher stehen in dem Ruf, dieses spe-
zielle Bedürfnis nicht befriedigen zu können – sie können informieren,
aber die Gedankengänge eines Programmierers werden letztendlich für
etwas gehalten, das man nicht wirklich auf einem Blatt Papier abbilden
kann.
VIIDiese Buchserie behauptet, dass diese Annahme falsch ist – und wir wol-
len das auch beweisen.
Ein Entwicklerheft ist genau das, was der Name sagt: die Bemerkungen
und Notizen, die ein Alpha-Geek im Geiste macht, während er mit einer
neuen Sprache, einer neuen API oder einem neuen Projekt arbeitet.
Dabei handelt es sich vor allem um geradlinigen Programmcode, mit dem
man Probleme lösen kann, befreit von den seitenlangen Kommentaren,
die eher eine Last sind als eine Offenbarung. Entwicklerhefte scheren
sich nicht darum, was raffiniert ist oder was Spaß machen könnte, wenn
Sie gerade etwas freie Zeit haben (wann war das denn das letzte Mal der
Fall?), sondern sie konzentrieren sich auf das, was Sie benötigen, um
etwas einfach »in Gang zu bekommen«. Sie sollten also keine Vorlesung
erwarten, sondern praktische Übungen. Wenn Sie sich für grundlegende
Konzepte, Architekturen und UML-Diagramme interessieren, kann ich
Ihnen unsere Animal-Bücher und Nutshell-Bände wärmstens empfehlen.
Wenn Sie Antworten auf alle Probleme unter der Sonne suchen, sind die
Rezeptsammlungen unserer Kochbücher das Richtige für Sie. Und wenn
Sie auf besonders geheimnisvolle und bisweilen etwas sonderbare
Anwendungsmöglichkeiten der Technologien aus sind, werden Sie sich
für die Hacks-Bücher begeistern. Aber wenn Sie durch und durch Pro-
grammierer sind und einfach nur mit Ihrer Arbeit weiterkommen möch-
ten, dann brauchen Sie ein Entwicklerheft. Die Kaffeeflecken und die
Randnotizen zeigen: Was hier steht, gelangt direkt aus dem Kopf eines
Entwicklers zu Ihnen. Ich hoffe, Sie finden Gefallen daran ... uns hat es
viel Spaß gemacht, daran zu arbeiten.
Entwicklerhefte sind ...
An Beispielen orientierte Leitfäden
Wie Sie im Abschnitt »Aufbau der Entwicklerhefte« sehen, sind die
Entwicklerhefte komplett an Beispielprogrammen orientiert. Fast auf
jeder Seite finden Sie Code-Beispiele, und dies ist Code, der etwas
macht – keine trivialen »Hello World!«-Programme, die nicht mehr
wert sind als das Papier, auf das sie gedruckt sind.
Für Entwickler geschrieben
Haben Sie auch schon Bücher gelesen, die sich an spitzfindige Bosse
zu richten scheinen, die voller Buzzwords sind und eher Marketing-
Materialen gleichen als Programmierbüchern? Solche Bücher ken-
nen wir auch, und diese Reihe bildet die Antithese dazu. Tatsächlich
wird ein gutes Entwicklerheft für jemanden, der nicht programmie-
ren kann, kaum verständlich sein. (Sagen Sie nicht, wir hätten Sie
VIII Über die Entwicklerheftenicht gewarnt!) Aber genau das ist zu erwarten, und für Entwickler ...
könnte es besser nicht sein.
Angenehm durchzuarbeiten
Haben Sie wirklich die Zeit herumzusitzen und etwas zu lesen, das
keinerlei Spaß macht? Wenn ja, dann mögen Sie vermutlich tausend-
seitige Sprachreferenzen – aber wenn es Ihnen so geht wie allen
anderen, dann sind Entwicklerhefte viel passender für Sie. Prakti-
sche Programmierbeispiele, knappe, um die anwendbaren Beispiele
herum zentrierte Dialoge und gelegentlich sogar etwas Humor – dies
sind die Zutaten eines guten Entwicklerhefts.
Es geht ums Tun, nicht darum, über das Tun zu reden
Wenn Sie ein Buch spät in der Nacht lesen möchten, ohne dass ein
Computer in der Nähe steht, sind diese Bücher für Sie vermutlich
nicht besonders hilfreich. Wir wollen, dass Sie programmieren, wäh-
rend Sie mit diesem Buch arbeiten, und dabei tief in den Bytecode
eintauchen. Aus diesem Grund finden Sie in den Entwicklerheften
Code, Code und immer wieder Code. Werfen Sie also Ihren Editor an,
bevor Sie einsteigen.
Entwicklerhefte sind nicht ...
Vorlesungen
Entwicklerhefte werden nicht einfach von irgendjemandem ge-
schrieben – die Autoren müssen wirkliche Programmierer sein, die
vorzugsweise abends zu lange auf bleiben, um noch ein bisschen zu
programmieren. So großartig manche Vollzeit-Autoren, Akademiker
und Theoretiker in ihren Bereichen auch sein mögen, diese Bücher
handeln von der harten Wirklichkeit des Programmierens. Sie sind
voller Anleitungen und nicht voll weiser Sprüche.
Gefüllt mit konzeptionellen Zeichnungen und Klassenhierarchien
Dies ist, wie gesagt, kein Nutshell-Buch. Sie finden hier keinen 100-
seitigen Index, in dem jede Methode aufgeführt ist, und Sie sehen
keine ganzseitigen UML-Diagramme mit Methoden, Vererbungsbäu-
men und Flussdiagrammen. Was Sie Seite für Seite finden, ist Quell-
code. (Erkennen Sie schon das immer wiederkehrende Thema?)
Lang in der Erklärung, schwach in der Anwendbarkeit
Anscheinend müssen viele Programmierbücher heutzutage drei, vier
oder mehr Kapitel haben, bevor man überhaupt auf irgendwelchen
funktionierenden Code stößt. Ich weiß nicht, wer Autoren auf die
Idee gebracht hat, ihre Leser so lange warten zu lassen, aber es ist
Über die Entwicklerhefte IXsicher niemand, der für diese Reihe arbeitet. Wir glauben, dass
etwas falsch läuft, wenn Sie nicht innerhalb von zehn Seiten zum
Programmieren kommen. Darüber hinaus sind diese Bücher randvoll
mit praktischen Anwendungen, die von einem einfachen Beispiel
ausgehen, aber schnell dazu führen, dass Sie eine konkrete Aufgabe
in Ihrem Arbeitsalltag lösen können.
Aufbau der Entwicklerhefte
Die Entwicklerhefte versuchen, Informationen anders zu vermitteln als
die üblichen Bücher. Dementsprechend sind sie auch anders organisiert.
Kapitel gibt es nach wie vor, aber damit hört die Ähnlichkeit eines Notiz-
buchs zu einem traditionellen Buch über Programmierung auch schon auf.
Zunächst werden Sie bemerken, dass sich alle Überschriften eines Kapi-
tels mit einer bestimmten Aufgabe beschäftigen. Beachten Sie, dass wir
das Wort Aufgabe verwenden, nicht etwa Thema. Das ist eine der we-
sentlichen Eigenschaften dieser Bücher: Es geht in erster Linie darum,
etwas zu tun. Jede Überschrift repräsentiert eine Aufgabe. Eine Aufgabe
ist das, wonach es klingt: die zum Erreichen eines bestimmten Ziels nöti-
gen Schritte. Der erste Satz einer Aufgabe lautet typischerweise »Wie ma-
che ich das?”, denn dies ist die zentrale Frage einer Aufgabe. In diesen
Abschnitten wird hemmungslos und bis ins Detail programmiert.
Ein letzter Hinweis: Auf vielen Seiten finden Sie auf den Seitenrand
gekritzelte Notizen. Das ist keine Dekoration: Es handelt sich um kurze
Zusammenfassungen der jeweiligen Abschnitte. Bei den kürzeren und
längeren Code-Abschnitten finden Sie hier außerdem den Namen der
Datei, die gerade modifiziert wird.
Alles in allem, denken Sie immer daran: Diese Bücher sind...
Reine Praxis, kein Vortrag
Brett McLaughlin, Schöpfer dieser Serie
X Über die EntwicklerhefteÜber dieses Buch
Was ist eigentlich NetBeans? Auf den ersten Blick ist NetBeans eine her- Sie können sowohl
vorragende integrierte Entwicklungsumgebung, die als reine Java- die NetBeans
Anwendung auf vielen Plattformen wie Windows, Linux, Solaris und Mac IDE als auch die
OS läuft. Neben der Unterstützung mehrerer Sprachen – derzeit Java, Ruby Plattform der-
und C/C++ – bietet sie über so genannte »Packs« alles, was wir für die zeit in der
Entwicklung von Java ME-, Java SE- und Java EE-Applikationen benö- Version 6 unter
tigen. Ein Vorwort ist sicherlich nicht der passende Ort, um alle Features www.netbeans.org
einer solch umfangreichen IDE aufzuzeigen, aber insbesondere die exzel- herunterladen.
lenten visuellen Editoren für Swing und Web-Anwendungen sowie die
Kollaborationstools und der Profiler sind einen Blick wert.
NetBeans ist aber noch wesentlich mehr. Die NetBeans IDE wurde von
Anfang an vollständig modular entwickelt und ist durch die Fähigkeit,
diese Module dynamisch laden zu können, in ihrem Umfang sehr flexi- Einführende
bel. Im Unterschied zu anderen bedeutenden IDEs basiert sie vollständig Videos finden
auf Java-Standards und verwendet Swing als GUI-System. Das NetBeans- Sie unter
Team hat daher schon sehr früh enorme Anstrengungen unternommen, www.netbeans.tv,
sich selbst ein Framework für die Entwicklung von Swing-basierten eine stets infor-
Applikationen zu schaffen. Dieses Framework berücksichtigt Aspekte wie mative und unter-
die Bereitstellung von Bausteinen für reiche und konsistente Benutzer- haltsame Quelle
oberflächen, Ressourenverwaltung, Konfiguration, kontextsensistive Hilfe für Informatio-
und nicht zuletzt Verteilungs-, Installations- und dynamische Aktualisie- nen zur Platt-
rungsfähigkeiten. Da sehr viele Desktop-Applikationen ähnliche techni- form ist Geert-
sche Anforderungen erfüllen müssen, lag es nahe, den Java-Entwicklern jans Weblog unter
neben dem Tooling auch das Framework zur Verfügung zu stellen – die blogs.sun.com/
NetBeans-Plattform war geboren. geertjan.
XISowohl die Plattform als auch das Tooling sind seit Juni 2000 Open
Source und stehen sowohl unter der CDDL als auch der GPL v2. Elf Jahre
nach dem Beginn der Entwicklung steht NetBeans heute in der Version 6
zur Verfügung. Sun Microsystems ist zwar weiterhin Hauptsponsor des
Projekts, die Bedeutung der Community für die Entwicklung von Net-
Beans wächst jedoch rasant. Mittlerweile sind mehr als 500.000 Mitglie-
der registriert, bringen ihre Erfahrungen ein und verbessern NetBeans
stetig. Immer mehr Partner fördern das Projekt, und die stetig wach-
sende Liste der auf der NetBeans-Plattform basierenden Referenzpro-
jekte belegt die Akzeptanz der Plattform.
Aufbau dieses Buchs
Dieses Buch hat nicht den Anspruch, Ihnen die vollständige Plattform mit
all ihren Aspekten zu zeigen. Vielmehr soll Ihnen möglichst zügig ein pra-
xisbezogener Eindruck der Rich-Client-Entwicklung mit der NetBeans IDE
und der NetBeans-Plattform verschafft werden. Das Ziel ist, Ihnen zu zei-
gen, wie die NetBeans-Plattform Sie bei der Entwicklung hochqualita-
tiver Rich-Client-Applikationen unterstützen kann, was die wesentlichen
Konzepte sind und wo Stolpersteine liegen. Dieses Entwicklerheft soll
kein ausführliches Referenzwerk ersetzen – dafür empfehle ich im Übri-
gen »Rich Client Programming« von Boudreau, Tulach und Wielenga –,
sondern Sie an die Hand nehmen und durch die Entwicklung einer Rich-
Client-Applikation führen. Der zentrale Treiber dieses Buches ist daher
eine Beispielapplikation, die sich vom ersten bis zum letzten Kapitel
durchzieht. Wir werden eine Aufgabenverwaltung implementieren, die
zwar einfach gehalten ist, jedoch die meisten wesentlichen Aspekte der
Rich-Client-Entwicklung berührt. Wir werden dabei so vorgehen, dass
wir jeweils mit dem Wissensstand des aktuellen Kapitels arbeiten und die
Applikation Stück für Stück erweitern und bestehende Teile gegebenen-
falls so umschreiben, dass letztlich eine vollständige Applikation entsteht.
Im Einzelnen werden wir uns die folgenden Themen ansehen:
Module
Module sind die grundlegenden Bausteine unserer Applikationen.
Wir werden uns ansehen, welche Eigenschaften sie haben, wie
Abhängigkeiten zwischen Modulen aufgelöst werden und wie sie
versioniert werden. Zudem beschäftigen wir uns mit ihrem Lebens-
zyklus und unseren Eingriffsmöglichkeiten. Bereits in diesem Kapitel
werden wir unsere Beispielapplikation vorstellen und mit ihrer Ent-
wicklung beginnen.
XIIFormulare
Beinahe jede Desktop-Applikation benötigt eine Vielzahl von Formu-
laren, um Informationen darzustellen und sie zu erfassen. Wir wer-
den uns ansehen, wie Formulare erstellt werden, wie ihr Layout
bestimmt wird und wie wir eine Ereignisbehandlung implementie-
ren können.
Windows API
Die Windows API bietet uns Zugriff auf ein komplexes Fenstersys-
tem. Wir werden uns anschauen, wie Fenster erzeugt werden, wie
ihr Lebenszyklus aussieht und wie wir in diesen eingreifen können.
Zudem werden wir lernen, wie Fenster im Standardlayout positio-
niert werden, wie dieses Layout angepasst werden kann und wie
Gruppen von Fenstern gebildet werden können.
Lookup API
Die Lookup API ist für die Entwicklung von Plattform-Applikationen
von besonders großer Bedeutung. Wir werden uns ansehen, wie mit
Hilfe von Lookups Dienste gefunden werden, eine lose gekoppelte
Kommunikation zwischen Komponenten ermöglicht wird und über
Listener dynamische Lookup-Inhalte realisiert werden. Zudem wer-
den wir lernen, wie ein Lookup als Stellvertreter für einen anderen
dienen kann und warum dies die Grundlage für die globale Kontext-
sensitivität ist.
Actions
Actions sind durch den Benutzer ausführbare Aktionen. Wir werden
uns ansehen, wie globale Actions erzeugt, in Menüs, Toolbars etc.
eingehängt und wie sie an Tastenkombinationen gebunden werden.
Nodes & Explorer API
Diese beiden APIs bieten uns eine ausgeklügelte MVC-Implementie-
rung mit deren Hilfe wir beliebige Fachmodelle mit wenig Aufwand
in wiederverwendbaren Views darstellen können. Wir werden uns
anschauen, wie Nodes zur Präsentation von Modellobjekten verwen-
det und in Explorer Views dargestellt werden. Wir werden dazu
sowohl flache als auch hierarchische Strukturen verwenden und uns
ansehen, mit wie wenig Aufwand die anzeigende View ausge-
tauscht werden kann. Anschließend werden wir uns mit der langläu-
figen Ermittlung von Nodes beschäftigen und sehen, wie die
NetBeans-Plattform kontextsensitive Aktionen unterstützt. Zu guter
XIIILetzt werden wir uns ansehen, wie die Properties der Nodes über
PropertyViews und PropertyEditoren dargestellt und editiert werden
können.
Filesystems API
Die Filesystems API bietet Zugriff auf virtuelle Dateisysteme. Wir wer-
den uns anschauen, wie wir auf das Konfigurations- und das lokale
Dateisystem zugreifen können. Zudem werden wir uns mit frei ver-
gebbaren Attributen der virtuellen Dateien beschäftigen.
Datasystems API
Die Datasystems API ermöglicht uns, auf Dateiinhalte zuzugreifen. Wir
werden uns ansehen, wie wir die Plattform um die Unterstützung
weiterer Dateitypen ergänzen und wie die Fähigkeiten im Umgang
mit den Dateiinhalten abhängig vom Status der Datei geändert wer-
den können.
Dialogs API
Dialoge reichen von einfachen Benachrichtigungen bis zu Wizards.
Wir werden uns daher anschauen, wie wir einfache Benachrich-
tigungen, Standarddialoge, eigene und mehrseitige Dialoge anzeigen
können.
Branding
Branding ermöglicht, die Applikation in ihrem Erscheinungsbild
anzupassen. Wir werden uns exemplarisch ansehen, wie wir den
Splash Screen austauschen können.
Distribution & Updates
Um unsere Software ausliefern zu können, werden wir uns die ver-
schieden Distributionsformen für Plattform-Applikationen ansehen,
einen Exkurs zur Generierung von Installern machen und uns
schließlich der Online-Aktualisierung zuwenden.
Im Buch verwendete
Konventionen
Kursive Schrift
verwenden wir für Datei- und Verzeichnisnamen, URLs und erstmals
eingeführte Begriffe.
Nichtporportionalschrift
wird im Fließtext für Methoden und Schlüsselwörter benutzt, außer-
dem durchgehend für die Quellcodebeispiele.
XIVKAPITÄLCHEN
verwenden wir für GUI-Elemente wie Buttons, Schaltflächen und
Menüelemente.
Das Beispielprojekt
Als Beispielprojekt werden wir eine einfache Aufgabenverwaltung ent-
wickeln. Mit ihr werden Hierarchien von Aufgaben erzeugt, modifiziert,
angezeigt, gefiltert und gelöscht werden können. Wir werden dazu For-
mulare, Wizards und lose gekoppelte Master-Detail-Views erstellen und
die Funktionen über kontextsensitive Aktionen in Menüs, Toolbars und
Kontextmenüs anbieten. Für die Persistierung werden wir die Plattform
um die Unterstützung eines neuen Dateityps erweitern. Zudem werden
wir eine Integration in die Standardkonfiguration und das Hilfesystem
vornehmen, das Branding durchführen und einen Installer zur Distribu-
tion erzeugen. Abgerundet wird die Applikation schließlich über die
Fähigkeit, sich über ein Update-Center zu aktualisieren.
Abbildung 0-1: Beispielapplikation
Der Source-Code der Beispielapplikation ist auf der begleitenden Web-
site www.netbeansrcp.com veröffentlicht. Sie finden dort sowohl den
endgültigen Stand der Applikation als auch die Zwischenstände zum
Ende jeden Kapitels.
XVDanksagungen
An der Entstehung dieses Buches waren viele Personen beteiligt, bei
denen ich mich an dieser Stelle bedanken möchte. Ausdrücklich bedan-
ken möchte ich mich bei Frau Haite vom O’Reilly Verlag für das entgegen-
gebrachte Vertrauen und die tolle Unterstützung in allen Phasen dieses
Projektes. Mein Dank gilt auch Markus Jais, Jens Boß und Geertjan Wie-
lenga für das Review des Buches, die mir mit ihren Ideen und Kritiken
sehr geholfen haben. Vor allem aber bedanke ich mich bei meiner Ver-
lobten Sabine, die in den vergangenen Monaten viel Geduld mit mir hatte
und mir trotz Fernbeziehung erlaubte, einen großen Teil meiner Freizeit
mit dem Schreiben dieses Buches zu verbringen.
XVIKapitel 1 KAPITEL 1
Module
In diesem ersten Kapitel werden wir uns mit Modulen und modularer In diesem Kapitel:
Entwicklung beschäftigen. Wir werden uns anschauen, was Module aus- • Modulare Ent-
machen und wie sie in der NetBeans- Plattform angelegt werden. wicklung
Anschließend werden wir uns mit der Konfiguration von Modulen, insbe- • Eigenschaften
sondere mit der Verwaltung von Abhängigkeiten und Versionierung aus- eines Moduls
einandersetzen. Abschließend werden wir auf den Lebenszyklus von • Anlage eines
Modulen eingehen und sehen, wie wir in diesen programmatisch ein- Moduls
greifen können. • Abhängigkeiten
verwalten
• Versionierung
Modulare Entwicklung • Installation von
Modulen
Mit der stetig wachsenden Komplexität von Software gewinnt die Modula- • Exkurs: Die Bei-
risierung zunehmend an Bedeutung. Immer kürzere Produktzyklen, stetig spielapplikation
wachsender Funktionsumfang und gleichzeitig steigendes Bewusstsein für
Softwarequalität lassen sich mit den herkömmlichen Entwicklungsmetho-
den nicht mehr in Einklang bringen. Gerade der erhöhte Zeitdruck führt
häufig dazu, dass ein an sich klares Design zunächst an wenigen Stellen
aufgeweicht wird und Abhängigkeiten zwischen Komponenten einge-
führt werden, die nie miteinander gekoppelt werden sollten. Mit jeder
Wartungsmaßnahme und jeder Erweiterung kommen immer mehr dieser
kleinen Verstöße hinzu, bis schließlich ein heilloses Chaos herrscht,
Erweiterungen und selbst Bugfixes kaum noch möglich sind und man sich
bei jeder Änderung fragen muss, welche ungewollten Auswirkungen sich
wohl diesmal zeigen werden. Der Testaufwand für eine solche gewach-
sene Applikation steigt ins Unermessliche, bis irgendwann entschieden
wird, dass eine vollständige Neuauflage der Applikation entwickelt wer-
den muss und der Reigen von vorne beginnt.
1Module stellen Eine Lösung dieses Problems liegt in der Einführung von Modulen.
Softwarekompo- Module sind zunächst einmal in sich abgeschlossene Softwarekompo-
nenten mit wohl- nenten, die nach außen über eine wohldefinierte Schnittstelle anzuspre-
definierten chen sind und ihre Implementierung hinter dieser Schnittstelle
Schnittstellen verstecken. In NetBeans wird jedes Modul als selbständiges Projekt abge-
dar und verste- bildet. Jedes grobgranulare Feature einer Applikation wird dabei als
cken ihre Imple- eigenes Modul entworfen, so dass jedes Modul einen überschaubaren
mentierung Umfang hat. Der oben beschriebene Wildwuchs kann innerhalb eines
Moduls im Grunde genommen genauso auftreten wie in herkömmlichen
Applikationen, jedoch sind sämtliche Klassen eines Moduls auf die
Umsetzung eines einzigen Features gerichtet, so dass sie höchstwahr-
scheinlich ohnehin zusammenarbeiten müssen und somit voneinander
abhängig sind. Zudem erleichtert der beschränkte Umfang die Einhal-
tung eines sauberen Entwurfs sehr deutlich.
Das oben beschriebene schleichende Chaos in der gesamten Applikation
kann bei dieser Art der Entwicklung jedoch kaum auftreten, da die Imp-
lementierung des Features lediglich über die öffentliche Schnittstelle
ansprechbar ist. Die Abhängigkeiten im Gesamtsystem sind daher sehr
eingeschränkt und planbar. Eine Abweichung vom Plan und damit der
beschriebene Wildwuchs sind generell nicht möglich.
Neben diesem Vorteil bei der Strukturierung der Applikation hat die
modulare Entwicklung auch ganz handfeste Vorteile für den Endanwen-
der. Da das NetBeans-Module-System dynamisch ist, können Module und
damit Features dynamisch hinzugeladen, entfernt oder ausgetauscht
werden. Damit ist eine weitgehende Anpassbarkeit der Applikation an
den Benutzer sehr leicht umsetzbar, was gerade bei Enterprise-Applika-
tionen, die für eine Vielzahl unterschiedlicher Nutzerprofile eingesetzt
werden, sehr nützlich sein kann.
Schauen wir uns nun aber konkreter an, was Module ausmachen.
Eigenschaften eines Moduls
Ein Modul muss bestimmte Eigenschaften aufweisen, damit sich die
gewünschten Vorteile ergeben können:
Deploymentformat
Sämtliche Ressourcen, die eine Komponente ausmachen, müssen als
eine deploybare Einheit zusammengefasst werden können.
Nahe liegendes Deploymentformat ist im Java-Umfeld sicherlich eine
Jar-Datei. Sie kann beliebig viele Ressourcen bündeln und bietet mit
2 Kapitel 1: Moduleihrem Manifest die Möglichkeit, Meta-Informationen zu speichern.
NetBeans-Module werden daher wie viele andere Komponenten
auch in einer Jar-Datei deployt, die zusätzliche Informationen in
ihrem Manifest aufnimmt.
Eindeutige Bezeichnung
Jede Komponente muss eine eindeutige Identität haben.
NetBeans-Module erweitern das Manifest um den Eintrag OpenIDE-
Module, der den applikationsweit eindeutigen Namen des Moduls
spezifiziert.
Versionierung
Jede Komponente muss darüber hinaus angeben können, in welcher
Version sie vorliegt.
NetBeans-Module unterscheiden hinsichtlich der Versionierung zwi-
schen den Versionen der Spezifikation und der Implementierung.
Die Spezifikationsversion zeigt an, welche Version der öffentlichen
Schnittstelle das Modul realisiert. Sie wird im Manifest-Eintrag Open-
IDE-Module-Specification-Version festgelegt und entspricht dem übli-
chen Dewey-Format. Grundsätzlich wird davon ausgegangen, dass
höhere Versionen abwärtskompatibel sind.
Die Implementierungsversion zeigt an, welchen Implementierungs-
stand das Modul hat. Diese Version dient nicht dem Vergleich der
Kompatibilität des gefundenen mit dem geforderten Modul und kann
daher lediglich auf Übereinstimmung mit einer gewünschten Version
geprüft werden. Sie wird im Manifest-Eintrag OpenIDE-Module-Im-
plementation-Version festgelegt.
Öffentliche Schnittstelle
Jedes Modul definiert eine öffentliche Schnittstelle, über die seine
Funktionalität angesprochen werden kann.
Herkömmliche Verfahren, um auswuchernde Abhängigkeiten inner-
halb einer Software in den Griff zu bekommen, beruhen häufig auf
Konventionen. Typen in bestimmten Paketen dürfen vereinbarungs-
gemäß nur indirekt, z.B. über Fassaden angesprochen werden. Die
wohlgemeinten Konventionen werden aber häufig genug dem Zeit-
druck geopfert.
Komponentensysteme mit eigener Laufzeitumgebung erzwingen in
der Regel die Einhaltung der Regeln. Innerhalb eines Moduls kön-
nen beliebig viele Klassen public sein und von anderen Klassen des
Moduls direkt angesprochen werden. Andere Module können jedoch
nur auf die öffentlichen Klassen zugreifen, die in ausdrücklich als
öffentlich deklarierten Paketen liegen.
Eigenschaften eines Moduls 3NetBeans liefert mit dem Module-System eine solche Laufzeitumge-
bung. Über den Manifest-Eintrag OpenIDE-Module-Public-Packages
werden sämtliche Pakete deklariert, auf die andere Module zugrei-
fen dürfen. Die Laufzeitumgebung verwaltet ein System aus Class-
Loadern, das Klassen eines Moduls lediglich Zugriff auf den eigenen
Modulinhalt sowie die Pakete der öffentlichen Schnittstellen derjeni-
gen Module erlaubt, zu denen das Modul eine Abhängigkeit deklariert.
Deklarierte Abhängigkeiten
Jede Komponente muss zudem deklarieren, welche anderen Kompo-
nenten sie benutzen möchte.
NetBeans sieht hierfür den Manifest-Eintrag OpenIDE-Module-
Dependencies vor. Wie zuvor erläutert, sorgt die Laufzeitumgebung
dafür, dass das Modul lediglich zu den öffentlichen Paketen dieser
Module Zugriff erhält.
Lebenszyklus
Jede Komponente muss über einen definierten Lebenszyklus verfü-
gen, der durch die Laufzeitumgebung sichergestellt ist.
NetBeans Module Runtime sorgt dafür, dass Module geladen und
konfiguriert werden, dass ggf. eigener Initialisierungscode ausge-
führt wird, Module bei Bedarf nachgeladen und entladen werden.
Anlage eines Moduls
Nachdem wir nun viel Theorie gehört haben, wollen wir zwei Module
anlegen und sie so konfigurieren, dass ein Modul auf die öffentliche
Schnittstelle des anderen Moduls zugreifen kann.
Wie mache ich das?
Eine Module Suite Zunächst legen wir ein neues Module-Suite-Projekt an. Die Module Suite
dient als Contai- dient als Container für Module und repräsentiert in der Regel eine Appli-
ner für Module kation. Über sie wird die zu verwendende Plattform konfiguriert und die
und repräsentiert Applikation gebrandet.
eine Applikation. Dazu rufen wir mit FILE À NEW PROJECT den New Project Wizard auf, wäh-
len NETBEANS MODULES À MODULE SUITE und geben den Namen des Projekts
»ModuleExamples« sowie seinen Standort ein (siehe Abbildung 1-1).
Nun können wir dieser Suite ein neues Modul hinzufügen.
4 Kapitel 1: ModuleAbbildung 1-1: Eine neue Module Suite anlegen
Dazu rufen wir das Kontextmenü des Knoten MODULES unserer Module
Suite MODULEEXAMPLES im Project Explorer (oben links) auf und wählen ADD
NEW. Im nun erscheinenden NEW MODULE PROJECT-Wizard geben wir den
Namen des Moduls com.netbeansrcp.helloservice (siehe Abbildung 1-2)
sowie seinen Standort an (siehe Abbildung 1-3). Die Zugehörigkeit zur
richtigen Module Suite wird automatisch erkannt.
Abbildung 1-2: Wir fügen ein neues Modul hinzu ...
Anlage eines Moduls 5Abbildung 1-3: ... und geben seinen Standort an.
Diesem Modul fügen wir nun eine öffentliche Klasse HelloService hinzu,
indem wir das Kontextmenü des Knotens HELLOSERVICE À SOURCE
PACKAGES À COM.NETBEANSRCP.HELLOSERVICE aufrufen, NEW À JAVA CLASS
wählen und den Wizard ausführen.
Der Klasse HelloService fügen Sie bitte die folgende Methode hinzu:
HelloService.java public void hello(String name) {
System.out.println("Hello " + name + "!");
}
Was ist da gerade geschehen?
Die wichtigsten Mit Hilfe des Wizards haben wir nun ein neues Modul angelegt. Das
Konfigurations- Modul beinhaltet mehrere Konfigurationsdateien, von denen die wich-
dateien für Mo- tigsten manifest.mf und layer.xml sind. Beide Dateien sind unter dem
dule sind Knoten HELLOSERVICE À IMPORTANT FILES zu finden. Die layer.xml werden
manifest.mf und wir im Laufe der kommenden Kapitel noch häufiger ansprechen. Ihr
layer.xml. Inhalt soll uns zum jetzigen Zeitpunkt jedoch noch nicht interessieren.
Das Manifest haben wir bereits besprochen, und derzeit enthält es nur
wenige Einträge:
Manifest.mf Manifest-Version: 1.0
OpenIDE-Module: com.netbeansrcp.helloservice
OpenIDE-Module-Layer: com/netbeansrcp/helloservice/layer.xml
OpenIDE-Module-Localizing-Bundle:
com/netbeansrcp/helloservice/Bundle.properties
OpenIDE-Module-Specification-Version: 1.0
6 Kapitel 1: ModuleAbhängigkeiten verwalten
Nun wollen wir den HelloService natürlich auch aus einem anderen
Modul heraus benutzen.
Legen Sie daher bitte auf die gleiche Weise ein zweites Modul namens
HelloClient an, und fügen Sie eine Klasse HelloClient mit folgender
Methode ein:
public static void main(String[] args) { HelloClient.java
new HelloService().hello("NetBeans");
}
Diese neue Klasse lässt sich momentan noch nicht kompilieren, weil Die Plattform
HelloService nicht gefunden werden kann. Auch das Einfügen eines isoliert Module
entsprechenden Import-Statements kann dem nicht abhelfen, da die über eigene Class-
Ursache in der erzwungenen Isolation von Modulen liegt. Bevor eine loader. Abhängig-
Klasse aus dem Modul HelloClient eine Klasse aus dem Modul keiten müssen
HelloService nutzen kann, müssen zwei Voraussetzungen erfüllt sein: deklariert wer-
1. Die Klasse HelloService muss zur öffentlichen Schnittstelle des den, und der
Moduls gehören. Zugriff kann nur
auf die öffentli-
2. Das Modul HelloClient muss seine Abhängigkeit vom HelloService
che Schnittstelle
öffentlich deklarieren.
erfolgen.
Wie mache ich das?
Zunächst müssen wir also den HelloService zur öffentlichen Schnitt- Die öffentliche
stelle des Moduls hinzufügen. Dazu rufen wir das KONTEXTMENÜ DES MODULS Schnittstelle
HELLOSERVICE auf und wählen PROPERTIES. Unter API VERSIONING sehen wir besteht aus Pake-
nun eine Liste der Pakete unseres Moduls und können diejenigen aus- ten. Auf Typen,
wählen, die vollständig zur öffentlichen Schnittstelle gehören sollen die nicht in Pake-
(Abbildung 1-4). In unserem Fall ist das com.netbeansrcp.helloservice. ten der öffent-
Einzelne Typen können nicht veröffentlicht werden. lichen Schnitt-
Nun müssen wir noch die Abhängigkeit des Moduls HelloClient zu stelle liegen, kann
HelloService deklarieren. Dazu rufen wir das KONTEXTMENÜ DES MODULS auch dann nicht
HELLOCLIENT auf und wählen PROPERTIES. Unter LIBRARIES können die Abhän- zugegriffen wer-
gigkeiten zu eigenen und NetBeans-Modulen deklariert werden. Klicken den, wenn sie
Sie bitte auf ADD DEPENDENCY, und beginnen Sie in das fokussierte Textfeld public sind.
den Namen der Klasse zu schreiben, auf die Sie zugreifen möchten. Net-
Beans ermittelt während der Eingabe automatisch die in Frage kommen-
den Module und stellt sie als Liste dar, siehe Abbildung 1-5. Wählen Sie
das Modul HelloService, und bestätigen Sie die Auswahl. Den Properties-
Dialog können wir ebenfalls mit einem Klick auf OK beenden.
Abhängigkeiten verwalten 7Abbildung 1-4: Öffentliche Schnittstelle deklarieren
Abbildung 1-5: Abhängigkeiten deklarieren
Sollten Sie in der Klasse HelloClient noch kein import-Statement für
com.netbeansrcp.helloservice.HelloService stehen haben, so ergän-
zen Sie es bitte. Die Klasse lässt sich nun kompilieren.
8 Kapitel 1: ModuleWas ist da gerade geschehen?
Mit Hilfe von Dialogen haben wir zum einen die öffentliche Schnittstelle
des Moduls HelloService definiert und zum anderen die Abhängigkeit
des Moduls HelloClient hiervon deklariert. Klassen aus dem Modul
HelloClient können nun auf Klassen zugreifen, die zur öffentlichen
Schnittstelle des Moduls HelloService gehören.
Versionierung
Zusätzlich zu der Information, von welchen Modulen ein Modul abhängig Die Versionierung
sein soll, müssen wir noch die Information verwalten, welche Version der von Modulen er-
Module wir überhaupt meinen. NetBeans unterscheidet zwischen Versio- folgt sowohl für
nen der Spezifikation und der Implementierung. die Spezifikation
Die Spezifikationsversion wird in der Dewey-Notation angegeben und als auch die Im-
beinhaltet in der Regel die Hauptversionsnummer, die für wesentliche plementierung.
Erweiterungen erhöht wird, die Nebenversionsnummer, die für Erweite-
rungen erhöht wird, und den Patchlevel, der Bugfixes u. Ä. anzeigt (z.B.
»Mac OS X in der Version 10.4.10«).
Die Implementierungsversion zeigt einen konkreten Entwicklungsstand
an und kann nur auf Übereinstimmung geprüft werden.
Exemplarisch wollen wir für das Modul HelloService die Version 1.2.5
deklarieren.
Wie mache ich das?
Zunächst konfigurieren wir das Modul HelloClient so, dass es Hello- Die Plattform
Server in der Version 1.2.5 benötigt. Dazu rufen wir das Kontextmenü überprüft das
des Moduls HelloClient auf und wählen PROPERTIES. Unter LIBRARIES Vorliegen der
selektieren wir die Abhängigkeit zum HelloService und klicken auf EDIT. benötigten Versio-
Tragen Sie bitte als Spezifikationsversion 2.1.5 ein (Abbildung 1-6), und nen automatisch.
bestätigen Sie die Dialoge.
Wenn Sie nun versuchen, das Projekt zu bauen, bekommen Sie die Mel-
dung, dass der Build gebrochen ist, weil dazu das Modul HelloService in
einer Version größer 2.1.5 vorliegen müsste.
...harness/build.xml:97: Cannot compile against a module:
/Users/jpe/NetBeansProjects/ModuleExamples/build/cluster/modules/
com-netbeansrcp-helloservice.jar because of dependency:
com.netbeansrcp.helloservice > 2.1.5
BUILD FAILED (total time: 1 second)
Versionierung 9Abbildung 1-6: Abhängigkeit zu Spezifikationsversion deklarieren
Um den Build wieder durchzubekommen, deklarieren wir für das Modul
HelloService die Version 2.1.3. Dazu rufen wir das Kontextmenü des
Moduls HelloService auf und wählen PROPERTIES. Unter API VERSIONING
tragen Sie bitte die Spezifikationsversion 2.1.5 ein (siehe Abbildung 1-7).
Abbildung 1-7: Abhängigkeit zu Spezifikationsversion deklarieren
Versuchen Sie nun erneut, das Projekt zu kompilieren. Der Build wird nun
erfolgreich sein, da wir die öffentliche Schnittstelle von HelloService
eingebunden haben.
10 Kapitel 1: ModuleWas ist da gerade geschehen?
Wir haben soeben gesehen, wie über die Properties die Spezifikations-
version eines Moduls gesetzt wird, und gezeigt, dass NetBeans schon
beim Build erzwingt, dass wir stets ein Modul der gewünschten Version
oder neuer vorliegen haben.
Installation von Modulen
Module müssen installiert werden, damit die Laufzeitumgebung ihren
Lebenszyklus steuern kann. Die Installation funktioniert in NetBeans
grundsätzlich deklarativ und wurde bereits durch die Wizards umgesetzt.
Wie greife ich in den Lebenszyklus ein?
Wollen wir in den Lebenszyklus programmatisch eingreifen, können wir Ein ModuleIn-
das über einen speziellen Module-Installer tun. Die Klasse ModuleInstall staller erlaubt uns
definiert Methoden, die die Laufzeitumgebung zu bestimmten Ereignis- den Eingriff in
sen im Leben des Moduls aufruft. Diese Methoden dienen in der Regel den Lebenszyklus
der reinen Information, können aber auch verwandt werden, um z. B. das eines Moduls.
Schließen der Applikation zu verhindern.
validate() kann überschrieben werden, um das Laden des Moduls zu
verhindern. Das ist insbesondere dann sinnvoll, wenn bestimmte Voraus-
setzungen für das korrekte Funktionieren des Moduls wie z.B. das Vor-
handensein einer gültigen Lizenz nicht gegeben sind.
restored() kann überschrieben werden, um Initialisierungen des
Moduls vorzunehmen. Zugunsten der Performance sollten Sie jedoch
überlegen, ob die Initialisierung nicht erst bei Bedarf, also lazy, ausge-
führt werden sollte.
closing() kann überschrieben werden, um das Schließen der Applika-
tion durch die Rückgabe von false zu verhindern.
close() informiert über das bevorstehende Schließen der Applikation.
Um einen eigenen Module-Installer zu erzeugen, rufen wir das Kontext-
menü des Moduls HelloService auf, wählen NEW À OTHER À MODULE
INSTALLER, bestätigen die vorgegebenen Werte und beenden den Dialog
(siehe Abbildungen 1-8 und 1-9).
Bitte überschreiben Sie restored() wie folgt:
@Override Installer.java
public void restored() {
System.out.println("HelloService() restored.");
}
Installation von Modulen 11Sie können auch lesen