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 • Tokyo
Die 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 III
Kapitel 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 Inhalt
Kapitel 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. VII
Diese 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 Entwicklerhefte
nicht 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 IX
sicher 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. XI
Sowohl 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. XII
Formulare 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 XIII
Letzt 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. XIV
KAPITÄ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. XV
Danksagungen 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. XVI
Kapitel 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. 1
Module 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: Module
ihrem 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 3
NetBeans 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: Module
Abbildung 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 5
Abbildung 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: Module
Abhä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 7
Abbildung 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: Module
Was 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 9
Abbildung 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: Module
Was 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 11
Sie können auch lesen