{"id":2306,"date":"2013-09-11T19:05:58","date_gmt":"2013-09-11T17:05:58","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=2306"},"modified":"2013-09-11T19:05:58","modified_gmt":"2013-09-11T17:05:58","slug":"nostalgia-das-javabeans-development-kit-bdk","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2013\/09\/nostalgia-das-javabeans-development-kit-bdk\/","title":{"rendered":"Nostalgia: Das JavaBeans Development Kit (BDK)"},"content":{"rendered":"<p>Das BDK ist (war) eine Testumgebung f\u00fcr anzeigeorientierte Beans und Komponenten ohne visuelle Repr\u00e4sentation wie Datenstrukturen und Container. Es ist nicht mehr im Original, sondern nur noch in der Version unter <a href=\"https:\/\/java.net\/projects\/bean-builder\">https:\/\/java.net\/projects\/bean-builder<\/a> erh\u00e4ltlich.<\/p>\n<p>Die Bean-Box bietet eine Arbeitsfl\u00e4che, auf der die Komponenten platziert und verbunden werden k\u00f6nnen. Wird in der Bean-Box eine Komponente auf dem Bildschirm gesetzt, so liest Java aus der Bean die Informationen (die Properties genannt werden) aus und stellt sie dar. Nun k\u00f6nnen mehrere Beans miteinander verbunden werden, sodass etwa eine Komponente ein Ereignis ausl\u00f6st, auf das die zweite Komponente reagiert. Alle Aktionen k\u00f6nnen direkt ohne eine Zeile Programmcode entworfen werden. Wir entwerfen zun\u00e4chst im Design-Modus die Verbindungen, um sie dann im Laufzeit-Modus zu testen. Damit reiht sich die Bean-Box in die Reihe der grafischen Entwicklungsumgebungen wie etwa IBMs Visual Age ein. Ganz so komfortabel ist die Bean-Box dann aber auch nicht. Sie ist von Sun lediglich zum Testen und Anzeigen von Beans entworfen worden. Dies zeigt sich auch daran, dass beim Verlassen der Umgebung nicht einmal nach dem Speichern gefragt wird.<\/p>\n<h4>Die Bean-Box starten<\/h4>\n<p>In der BDK-Version 1.1 wechseln wir in das bdk\/beanbox\/bin-Verzeichnis und rufen die Skripte run.bat (Windows) oder run.sh (Unix) auf. Dann startet die Umgebung.<\/p>\n<h4>Eine Beispielsitzung im BDK<\/h4>\n<p>Das BDK ist nach dem Start in drei Fenster unterteilt. Dies sind die ToolBox, die Bean-Box und das Eigenschaften-Feld. Das ToolBox-Fenster enth\u00e4lt einige Beispielkomponenten, die wir verwenden k\u00f6nnen. Die Beispiele werden zur Laufzeit aus dem bdk\/jars\/-Verzeichnis genommen. Eigene Komponenten k\u00f6nnen wir als Jar-Dateien einfach dort hineinkopieren. Die eigentliche Bean-Box stellt die Zeichenfl\u00e4che dar. Sie ist der wichtigste Teil des Pakets, weil auf ihr Komponenten platziert und getestet werden k\u00f6nnen. Wir wollen dies anhand der Komponente Molecule zeigen. Wird sie in der ToolBox angeklickt, so verwandelt sich der Cursor in einen Positionszeiger. Klicken wir in der Bean-Box auf eine Stelle, wird ein Molek\u00fcl angezeigt. Es l\u00e4sst sich verschieben und interaktiv in der Gr\u00f6\u00dfe \u00e4ndern. Die Eigenschaften jeder Komponente lassen sich im Property-Sheet \u00e4ndern. Sie bestimmen das Aussehen und das Verhalten. Ist das Molek\u00fcl aktiviert, erscheint im Eigenschaften-Dialog eine Auswahlliste mit einigen Molek\u00fclen. Eine Auswahl wirkt sich direkt in der Anzeige aus.<\/p>\n<p><b>Hinweis:<\/b> Leider k\u00f6nnen selektierte Komponenten nicht mit der Entfernen-Taste von der Oberfl\u00e4che beseitigt werden. Hier ist nur der Gang \u00fcber das Edit-Men\u00fc erfolgversprechend.<\/p>\n<p>Das Zusammenspiel der Komponenten l\u00e4sst sich testen, indem wir den Design-Modus verlassen. Dazu aktivieren wir im Men\u00fcpunkt View den ersten Punkt Disable Design Mode (der sich dann in Enable Design Mode umbenennt). Jetzt kann das Molek\u00fcl mit der Maus verschoben werden.<\/p>\n<h4>Verkn\u00fcpfungen zwischen Komponenten<\/h4>\n<p>Die hervorragendste Eigenschaft der grafischen Programmierung ist das visuelle Setzen von Beziehungen zwischen Komponenten. Dabei werden Ereignisse an Methoden anderer Beans gebunden. Wir wollen das mit der Komponente JellyBean und dem Molek\u00fcl testen. Wenn wir nun mit der Maus auf die JellyBean klicken (also ein Mouse-Event ausl\u00f6sen), dann soll eine bestimmte Methode des Bean-Molek\u00fcls aufgerufen werden, sodass es sich auf dem Bildschirm dreht. Wir verbinden hier also einfach eine Ereignisquelle mit einer Ereignisbehandlung einer anderen Komponente. Die Bedienung der Bean-Box ist dabei so intuitiv, dass sie zum Spielen und Ausprobieren einl\u00e4dt. Wir aktivieren die erste Schaltfl\u00e4che und w\u00e4hlen den Men\u00fcpunkt Edit &gt; Events &gt; mouse &gt; mousePressed.<\/p>\n<p>Jetzt erscheint eine rote Linie, die mit der Maus bewegt wird. Nun klicken wir auf unser Molek\u00fcl. Daraufhin erscheint eine Liste mit Funktionen, die bei der Mausbewegung ausgel\u00f6st werden k\u00f6nnen. Wir entscheiden uns f\u00fcr rotateOnX.<\/p>\n<h4>Beans speichern<\/h4>\n<p>In der Bean-Box l\u00e4sst sich unter dem File-Men\u00fc die Bean in ein Jar-Archiv f\u00fcr ein Applet einwickeln. Der Speicherdialog schl\u00e4gt standardm\u00e4\u00dfig ein Unterverzeichnis der Bean-Box vor. Zus\u00e4tzlich zur serialisierten Klasse befinden sich im Archiv noch die vom BDK erstellten Metainformationen, die Quellcodes zu der Bean in einem Extra-Verzeichnis, eine HTML-Datei sowie eine Readme-Datei mit den Informationen dar\u00fcber, welche Dateien zur Komponente geh\u00f6ren. Die HTML-Datei erh\u00e4lt eine Referenz auf die Klassendatei, sodass ein Applet-Viewer oder ein Browser direkt die Bean darstellen kann. Alte Browser unterst\u00fctzen das Jar-Format im Applet-Tag der HTML-Datei nicht.<\/p>\n<h4>Die kleinste Bohne der Welt<\/h4>\n<p>Wir wollen uns nicht lange mit theoretischem Schnickschnack aufhalten \u2013 daf\u00fcr bleibt noch gen\u00fcgend Zeit. Beginnen wir mit einer Komponente, die wir FirstBean nennen wollen.<\/p>\n<pre>package com.javatutor.insel.bean;\n\nimport java.applet.Applet;\nimport java.awt.*;\n\npublic class FirstBean extends Applet\n{\n @Override\n public void paint( Graphics g )\n {\n  g.drawString( &quot;Hui; so kurz?&quot;, 20, 20 );\n }\n}<\/pre>\n<p>Zweifellos wird die K\u00fcrze dieser L\u00f6sung verwundern. Das kommt daher, dass sich die Beans gut in die vorhandene Technologie einf\u00fcgen und schon viele Komponenten als Beans gebaut sind.<\/p>\n<p>Beginnen wir nun, das schon in der Einf\u00fchrung als einfaches Beispiel f\u00fcr Komponenten identifizierte Applet in unseren Application-Builder einzubauen. Dazu muss die Softwarekomponente in einem speziellen Format vorliegen: in Jar-Dateien.<\/p>\n<h4>Jar-Archive f\u00fcr Komponenten<\/h4>\n<p>Eine Jar-Datei ist ein Archivformat, das Sun zum Verbund von Klassen und Mediendateien einf\u00fchrte. Nach dem Compilieren der Klasse FirstBean wird die Datei mit einem zus\u00e4tzlichen Manifest in eine Jar-Datei gepackt. Damit der Application-Builder erkennen kann, dass es sich dabei um eine Bean handelt, erwartet er eine bestimmte Information in einer Manifest-Datei, die automatisch beim Zusammenpacken erzeugt wird. St\u00fcnden diese Informationen nicht dabei, k\u00f6nnte der Application-Builder die Bean nicht erkennen.<\/p>\n<p>Wir wollen die Jar-Datei mit dem Dienstprogramm <i>jar<\/i> von Hand erzeugen. Zun\u00e4chst legen wir eine Manifest-Datei an, die wir nach der Komponente benennen.<\/p>\n<p><i>FirstBean.mf<\/i><\/p>\n<pre>Manifest-Version: 1.0\nName: FirstBean.class\nJava-Bean: True<\/pre>\n<p><b>Hinweis:<\/b> Vor den Doppelpunkten d\u00fcrfen keine Leerzeichen stehen, sonst erkennt Jar die erste Option nicht und bem\u00e4ngelt den fehlerhaften Header. Leider ist Jar nicht sehr fehlertolerant.<\/p>\n<p>Befinden sich im Jar-Archiv mehrere Klassen, sollten ihre Dateinamen mit Return getrennt sein. Bei Paketnamen ist eine Trennung mit \/ vorgesehen, nicht mit dem Windows-\\.<\/p>\n<p>Im n\u00e4chsten Schritt packen wir mit <i>jar<\/i> die Klassen sowie die Manifest-Datei zu einem Archiv zusammen. Hier m\u00fcssen wir die Optionen cfm nutzen. Merken wir uns die Option im englischen Satz \u00bbCreate a File with a Manifest\u00ab, \u00fcbersetzt \u00bbLege die Datei mit Manifest an\u00ab .<\/p>\n<pre>$ jar cfm FirstBean.jar FirstBean.mf FirstBean.class<\/pre>\n<p>F\u00fcr eine genauere Beschreibung des Dienstprogramms jar sei auf Kapitel in der Insel verwiesen.<\/p>\n<p>Wurde das Jar-Archiv erfolgreich erstellt, muss dem Application-Builder die Bean bekannt gemacht werden. Hier unterscheiden sich die Produkte der einzelnen Hersteller voneinander. Im BDK von Sun m\u00fcssen alle Beans im Unterverzeichnis <i>jars<\/i> liegen, damit sie das BDK automatisch erkennt. Kopieren wir unsere Bean dort hinein. Unter Windows schreiben wir:<\/p>\n<pre>$ copy FirstBean.jar c:\\bdk\\jars<\/pre>\n<p>Wenn wir jetzt die Bean-Box starten, erscheint unsere Komponente mit in der Liste. Im jars-Verzeichnis stehen auch die anderen Beans.<\/p>\n<p><b>Tipp: <\/b>Eine etwas schnellere Vorgehensweise besteht darin, die Jar-Datei nicht in das jars-Verzeichnis, sondern in ein eigenes Verzeichnis zu legen. Das hat den Vorteil, dass die Bean-Box schneller startet, weil sie dann nicht die zus\u00e4tzliche Bean auswerten muss, was immer Zeit kostet. Wenn wir Beans nicht ben\u00f6tigen, k\u00f6nnen wir sie auch verschieben oder l\u00f6schen, was die Ladezeit zus\u00e4tzlich erh\u00f6ht. Damit in diesem Fall das eigene Jar-Archiv eingebunden wird, laden wir es unter dem Men\u00fcpunkt File &gt; Load Jar.<\/p>\n<p>Wenn wir wiederholt Beans in ein Archiv packen und keine integrierte Entwicklungsumgebung diese Arbeit erledigt, kann uns ein kleines Skript helfen. Ein Beispiel f\u00fcr Windows w\u00e4re:<\/p>\n<p><i>a.bat<\/i><\/p>\n<pre>javac zzz.java\njar cfm zzz.jar zzz.mf zzz.class\ncopy zzz.jar c:\\bdk\\jars<\/pre>\n<p>Bean-Eigenschaften anpassen<\/p>\n<p>In einem visuellen Entwicklungswerkzeug lassen sich alle ausgezeichneten Eigenschaften einer Bean anpassen. Dazu bietet die Umgebung oft ein zweigeteiltes Fenster an. Auf der einen Seite befinden sich die Eigenschaften und auf der anderen Seite die Editoren f\u00fcr jede Eigenschaft. Die folgende Abbildung zeigt einige Properties und deren Anzeigen.<\/p>\n<p>Haben wir zum Beispiel als Eigenschaft eine Zeichenkette (wie der angezeigte Text eines Label-Objekts), k\u00f6nnen wir diese einfach in das Feld eintragen. Mit einem eigenen Property-Editor sind wir jedoch nicht auf die einfachen Datentypen beschr\u00e4nkt. Was ist, wenn etwa eine Komponente die Auswahl zwischen DM und Euro anbieten will? Wir k\u00f6nnen dem Benutzer nicht zumuten, dies in Zahlen einzugeben. Auch bei einem Label gibt es zum Beispiel die M\u00f6glichkeit, einen Cursor aus einer Liste auszuw\u00e4hlen.<\/p>\n<p>F\u00fcr ungew\u00f6hnliche Eigenschaften k\u00f6nnen wir einen eigenen Property-Editor definieren. Dazu kann der Editor den Anzeigebereich als Grafikfl\u00e4che beschreiben.<\/p>\n<h4>Customizer<\/h4>\n<p>Reicht auch der Editor nicht aus, zum Beispiel bei einer Farbe, die wir gerne aus einem Farbkreis ausw\u00e4hlen wollen, l\u00e4sst sich zudem ein Customizer definieren, der noch einen Schritt weiter geht, denn f\u00fcr einen Customizer ist ein eigenes Fenster vorgesehen. Er soll mit einer einfachen Benutzerf\u00fchrung den internen Zustand \u00e4ndern. IBM sieht f\u00fcr seine Beans zum Beispiel ein Hilfe-Feld vor. In WebGain wird dieser Customizer durch eine Schaltfl\u00e4che mit drei Punkten angezeigt.<\/p>\n<h4>Property-Editoren<\/h4>\n<p>F\u00fcr jede sichtbare Eigenschaft einer Bean gibt es einen Property-Editor, der den Wert darstellen und ihn bei einer ver\u00e4nderbaren Eigenschaft auch editieren kann. Bekommt die Eigenschaft den Fokus, wird automatisch der passende Editor ausgew\u00e4hlt. F\u00fcr alle primitiven Datentypen gibt es standardm\u00e4\u00dfig Editoren, und zus\u00e4tzlich kommen Auswahlm\u00f6glichkeiten f\u00fcr String, Color und Font hinzu. Ein Editor gilt f\u00fcr jeweils eine Property. Die Editoren werden an einer zentralen Stelle, dem Property-Editor-Manager, registriert und dann beim Fokus ausgew\u00e4hlt und aktiviert. Das ist Aufgabe der Entwicklungsumgebung.<\/p>\n<p>Damit die Einstellm\u00f6glichkeit nicht auf diese einfachen Typen beschr\u00e4nkt bleibt, k\u00f6nnen wir f\u00fcr eine Eigenschaft einen eigenen Property-Editor konstruieren. Der kann eine ganz einfache Textzeile darstellen oder auch eine eindrucksvolle Multimedia-Komponente. Der Editor \u00fcbernimmt die Anzeige und ist gleichzeitig das Modell (also gibt es keine Trennung von Daten und Visualisierung an dieser Stelle). Der Wert ist als Object in unserem Editor gespeichert. Au\u00dferdem muss der Editor die Schnittstelle java.beans.PropertyEditor implementieren oder alternativ die Klasse java.beans.PropertyEditorSupport erweitern, was meist einfacher ist.<\/p>\n<h4>BeanInfo<\/h4>\n<p>Durch Introspection\/Reflection existiert ein leistungsf\u00e4higer Mechanismus, um die Eigenschaften und Ereignisse zur Laufzeit auszulesen. In der Regel nimmt die Entwicklungsumgebung daf\u00fcr Methoden, die sich an die Namenskonvention halten. Es gibt aber noch eine zweite M\u00f6glichkeit, und die l\u00e4sst sich \u00fcber eine Bean-Information-Klasse nutzen. Sie bietet folgende Funktionalit\u00e4t:<\/p>\n<ul>\n<li>explizites Auflisten der freigegebenen Leistungen, die nach au\u00dfen sichtbar sein sollen <\/li>\n<li>Zuordnung eines mit der Bean verwendeten Icons <\/li>\n<li>Anmeldung einer Customizer-Klasse<\/li>\n<\/ul>\n<p>Sind die freigegebenen Leistungen aufgelistet, wird damit eine Untersuchung der Bean-Klassen auf die Namensgebung verhindert. Es gibt daher zur Freigabe der Eigenschaften und Ereignisse spezielle Methoden, die von uns gef\u00fcllt werden, indem wir jede Eigenschaft auflisten. Jede Methode nutzt zur Beschreibung der Leistungen so genannte Deskriptoren. Gibt es keinen Deskriptor, wird die jeweilige Eigenschaft, Methode oder das Ereignis nicht ver\u00f6ffentlicht. Gibt die Anfrage-Methode aus der Bean-Information-Klasse null zur\u00fcck, wird f\u00fcr die jeweilige Eigenschaft\/Event\/Methode Reflection genutzt. Der Java-Code f\u00fcr dieses Doktor-Spielchen liegt in java.beans.Introspection. Ein kleines Beispiel, das alle get-Methoden der Klasse Point ausgibt:<\/p>\n<pre>BeanInfo beanInfo = Introspector.getBeanInfo( Point.class );\nfor ( PropertyDescriptor p : beanInfo.getPropertyDescriptors() )\nSystem.out.println( p.getReadMethod() );<\/pre>\n<p>Die Ausgabe liefert vier Zeilen:<\/p>\n<pre>public final native java.lang.Class java.lang.Object.getClass()\npublic java.awt.Point java.awt.Point.getLocation()\npublic double java.awt.Point.getX()\npublic double java.awt.Point.getY()<\/pre>\n<h4>Beliebte Fehler<\/h4>\n<p>Das Programmieren von Beans ist zwar einfach, doch schleichen sich immer wieder Fehler ein. Dieser Abschnitt soll auflisten, welche Fehler f\u00fcr eine Bean letal sind, sodass sie von einer Umgebung nicht erkannt werden kann.<\/p>\n<ul>\n<li>Die Klasse muss \u00f6ffentlich (public) und darf nicht abstrakt sein. Abstrakte Klassen k\u00f6nnen keine Exemplare bilden, was f\u00fcr eine Bean-Box aber unumg\u00e4nglich ist. <\/li>\n<li>Die Klasse muss vom Klassenlader ohne Folgefehler geladen werden k\u00f6nnen. Der Vorgang wird w\u00e4hrend des Ladens durch Fehler im static-Block oder durch fehlende Klassen m\u00f6glicherweise abgebrochen. <\/li>\n<li>Die Bean muss einen \u00f6ffentlichen Standard-Konstruktor anbieten. <\/li>\n<li>Die Klasse muss Serializable implementieren, muss also serialisierbar sein. Das hat zur Konsequenz, dass alle Attribute, die nicht transient sind, ebenso serialisierbar sein m\u00fcssen. Eine Verletzung dieser Regel liegt beispielsweise vor, wenn eine grafische Komponente eine Referenz auf ein Image-Objekt h\u00e4lt, denn Image-Objekte sind nicht serialisierbar. Wir m\u00fcssen daher entweder ImageIcon nutzen oder eigene Methoden wie writeObject(), readObject() implementieren. Wenn schon eine Oberklasse serialisierbar ist, dann muss unsere Klasse nicht noch einmal Serializable implementieren, weil wir dann selbst automatisch instanceof Serializable durch die Oberklasse sind. Es bietet sich jedoch zum Zweck der Lesbarkeit an, implements Serializable zu schreiben, damit das auf den ersten Blick sichtbar ist.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Das BDK ist (war) eine Testumgebung f\u00fcr anzeigeorientierte Beans und Komponenten ohne visuelle Repr\u00e4sentation wie Datenstrukturen und Container. Es ist nicht mehr im Original, sondern nur noch in der Version unter https:\/\/java.net\/projects\/bean-builder erh\u00e4ltlich. Die Bean-Box bietet eine Arbeitsfl\u00e4che, auf der die Komponenten platziert und verbunden werden k\u00f6nnen. Wird in der Bean-Box eine Komponente auf dem [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-2306","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=2306"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2306\/revisions"}],"predecessor-version":[{"id":2307,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/2306\/revisions\/2307"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=2306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=2306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=2306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}