Artikel

 
November 2009 | Artikel

Metawidget: King of the Hill Fortsetzung, Teil 3

Teil 1   Teil 2   Teil 3   Teil 4   

Naked Objects kann sowohl als Rich Client, dem so genannten Drag and Drop Client, als auch als Webapplikation betrieben werden, wobei in beiden Fällen das komplette User Interface zur Laufzeit generiert wird. Der Entwickler kann dabei auf das User Interface nur über die vom Framework bereitgestellten Möglichkeiten Einfluss nehmen. Gerade beim Rich Client ist dies äußerst problematisch, da sich die Oberfläche nicht an bestehende UI-Standards hält und dadurch die Applikation einige Einarbeitung benötigt. Gerade dieser Aspekt kann daher zu einem Ausschlusskriterium für Naked Objects werden, vor allem wenn die Applikation nicht für Power User vorgesehen ist. Einen tabellarischen Vergleich mit einigen anderen UI-Technologien bietet der FAQ-Bereich auf der Metawidget-Website.

Let's go, Metawidget!

Nachdem wir jetzt einige alternative Technologien kennengelernt haben, wollen wir uns endlich in die Materie hineinstürzen und uns ansehen, wie die Formularerstellung mit Metawidget funktioniert. Sehen wir uns zuerst die Domänenklasse von Listing 2 an. Was dem aufmerksamen Leser dieses Artikels natürlich gleich auffällt, ist die Ähnlichkeit zu Naked Objects. Genau wie dieses verwendet Metawidget Annotationen, um die Domänenklassen mit Informationen anzureichern, die für das User Interface benötigt werden. Analog zu @MemberOrder gibt es daher die @UiComesAfter, die angibt, an welcher Stelle im Formular das Eingabefeld angezeigt werden kann. Der Unterschied ist jedoch, dass bei @UiComesAfter eine relative Positionierung stattfindet, da der Name des vorhergehenden Properties angegeben wird. Dadurch erspart man sich, sämtliche Annotationen nochmals zu korrigieren, wenn man nachträglich weiter vorne im Formular ein Eingabefeld positionieren will. @UiLabel ist wiederum analog zu @Named, wobei Metawidget auch die Internationalisierung über Ressourcendateien erlaubt. Der erste bedeutende Unterschied sind Annotationen wie @NotEmpty, @Pattern oder @Length, die zwar die gleiche Semantik wie ihre Pendants in Naked Objects haben, allerdings nicht wie bei Naked Objects von Metawidget zur Verfügung gestellt werden. Stattdessen wurden in diesem Beispiel die Annotationen von Hibernate Validator verwendet, wobei Metawidget nicht darauf festgelegt ist. Tabelle 2 listet die wichtigsten Annotationen von Metawidget auf.

Tabelle 2: Metawidget-Annotationen
Annotation Beschreibung
UiComesAfter Bestimmt die Reihenfolge, in der die Eingabefelder angezeigt werden
UiLarge Vergrößert das Eingabefeld für längere Texte
UiHidden Zeigt das Eingabefeld nicht an
UiReadOnly Markiert das Eingabefeld als schreibgeschützt
UiMasked Maskiert die Eingabefelder für die Eingabe von Passwörtern
UiLookup Gibt die Eingabewerte in einer Combo-Box zur Auswahl vor
UiDontExpand Komplexe Typen werden nicht als Subformular angezeigt
UiSection Beginnt eine neue Sektion im Formular und setzt dessen Titel
 
 

Nicht jeder Entwickler ist darüber glücklich, dass immer mehr Annotationen eingesetzt werden. Nachdem die Verwendung von Annotationen immer mehr zunimmt, wird hierfür teilweise schon der Begriff "Annotationshölle" verwendet. Daher bietet Metawidget als Alternative auch die gute, alte Konfiguration per XML-Dateien an. Listing 3 zeigt dieselbe Domänenklasse wie Listing 2, diesmal jedoch in XML definiert. Der Vorteil: Die Reihenfolge der Eingabefelder wird durch die Reihenfolge in der XML-Datei bereits festgelegt.

  1. package de.javamagazin.mwd;
  2. import java.util.*;
  3. import org.hibernate.validator.*;
  4. import org.metawidget.inspector.annotation.*;
  5. public class Project
  6. {
  7. private String name = null;
  8. private String codeName = null;
  9. private String description = null;
  10. @UiLabel("Projektname")
  11. @NotEmpty(message="Der Projektname muss angegeben werden")
  12. @Pattern(regex="[A-Za-z]\\w+",message="Der Projektname muss mit einem Buchstaben beginnen")
  13. public String getName() {
  14. return name;
  15. }
  16. @UiComesAfter("codename")
  17. @UiLabel("Beschreibung")
  18. @UiLarge
  19. public String getDescription() {
  20. return this.description;
  21. }
  22. @UiComesAfter("name")
  23. @UiLabel("Codename")
  24. @Length(max=10,message="Der Codename darf maximal 10 Zeichen lang sein")
  25. public String getCodeName() {
  26. return codeName;
  27. }
  28. // Setter-Methoden
  29. }
  1. <?xml version="1.0"?>
  2. <inspection-result xmlns="http://metawidget.org/inspection-result"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://metawidget.org/inspection-result
  5. http://metawidget.org/inspection-result-1.0.xsd ">
  6. <entity type="de.javamagazin.mwd.Project">
  7. <property name="name" />
  8. <property name="codeName" />
  9. <property name="description" large="true"/>
  10. </entity>
  11. </inspection-result>

Teil 1   Teil 2   Teil 3   Teil 4   

Anzeige

Kommentare

Gravatar RPR 25.11.2009
um 20:24 Uhr
Für einfache Prototypen ist so was ja ganz nett; aber:1. Für ausgefeilte Endkunden-GUIs die komplexe Business-Logik darstellen sollen ist so was nicht geeignet.2. Schon die GUI des einfachen Beispiels sieht - pardon - besch... aus; die Labels gehören z.B. rechtsbündig.3. Der Code des Beispiels wäre mit Swing allein auch nicht länger gewesen; höchstens die Validierung (die auch nur in einfachsten Fällen so geht - wie siehs z.B. mit dynamischen Lookups aus?) bringt ein paar Zeilen Code; verstopft aber die Übersichtlichkeit; pro Property 10 Annotations? Nein danke.4. Durch die ganzen Interzeptoren XML-Einlesearbeit etc. wird das Programm sicher nicht schneller (starten).Woher kommen wohl seit 10 Jahren die "Gerüchte" dass Java-GUIs hässlich und langsam sind? Nicht zuletzt von solchen "Vereinfachungen".Nein Leute lasst euch sagen: Wenn ein Programm erfolgreich werden soll dann braucht es eine ausgefeilte Benutzerführung dass die Leute sagen: Geil das macht das genau so wie ich mir das vorstelle. Ansonsten werden die Benutzer das Programm von Anfang an hassen. Ergo: Für die nächste Franken-GUI durchaus eine Überlegung wert ;-) #zitieren
Gravatar RPR 25.11.2009
um 20:26 Uhr
Jetzt geht der vermaledeite Zeilenumbruch hier schon wieder nicht welche Stümper programmieren das hier eigentlich? #zitieren
Gravatar Wolfgang Gruber 26.11.2009
um 15:37 Uhr
ad 1. nein, dazu ist es auch gar nicht gedacht. Es soll die Entwicklung von Standard-Formularen vereinfachen, die meist einen großen Teil von Applikationen einnehmen. Komplexe GUIs erfordern natürlich weiterhin "Handarbeit".
ad 2. Stimmt, es ist aber nur ein kurzes Beispiel. Auf http://metawidget.sourceforge.net/screenshots.html gibt es einige schönere GUIs.
ad 3. Bei kurzen Beispielen machen sich die Einsparungen an Source Code natürlich nicht bemerkbar. Zum Vergleich: Wenn man den Code für ein einfaches JDBC-Select-Statement mit dem Code vergleicht, den JPA für die gleiche Funktionalität benötigt, dann schneidet JPA auch nicht gerade gut ab. Es geht aber auch darum repetativen Code zu eliminieren, so dass man sich als Entwickler mehr auf den Kern konzentrieren kann. Im Fall von Metawidget eben die Anordnung der Widgets, sowie deren Aussehen. Ob man alle Metadaten als Annotationen direkt in der Entität angibt oder in XML-Dateien auslagert (wie das auch von Metawidget angeboten wird), bleibt jedem Entwickler selbst überlassen. Momentan ist es eben einfach der Trend alles in Annotationen zu packen. Ob das der ideale Weg ist, ist natürlich eine andere Frage :-)
ad 4. das Problem ist, dass solche Gerüchte einmal aufkommen und dann nicht mehr hinterfragt werden. Inzwischen sind 10 Jahre vergangen, in denen sich sowohl Java, als auch die darunterliegende Hardware weiterentwickelt haben. Ansonsten kommen langsame Java-GUIs sehr oft von suboptimaler Programmierung, z.B. dass zu viel Arbeit im Event Dispatch Thread erfolgt, die GUI dadurch "einfriert" und nicht mehr auf den Benutzer reagiert.
Metawidget bildet einen Wrapper um vorhandene Technologien und ist mit knapp 300 KB nicht besonders groß. Von daher ist die Performance-Einbuße beim Start zwar sicherlich vorhanden, aber nicht wesentlich (die Initialisierung von z.B. JPA nimmt da sicherlich mehr Zeit in Anspruch).
Wie im Artikel beschrieben, handelt es sich nicht um eine All-inclusive-Lösung, sondern einfach um ein Tool, dass die Arbeit mit Formularen erleichtern soll.
#zitieren
Gravatar Jan Lessner 26.11.2009
um 22:48 Uhr
Ich kann nur bestätigen, dass solche Ansätze funktionieren. Wie ich seinerzeit in dem zitierten Artikel über Naked Objects geschrieben hatte, ließt an dem Framework nicht das Konzept sondern nur die konkrete Umsetzung zu wünschen übrig. Inzwischen haben wir bei arvato services ein eigenes Framework nach Naked-Objects-Pattern entwickelt, das tadellos im produktiven Einsatz funktoniert, enorm Zeit spart und trotzdem flexibel und offen ist, so dass selbst die kritischen Entwickler das Ding richtig "cool" finden. Entscheidender Trick dabei: die zur Laufzeit erzeugten Maskenlayouts (basierend auf JGoodies FormLayout) werden - sofern man es nicht explizit unterdrückt - in Dateien abgelegt und lassen sich anschließend mit einem sehr komfortablen GUI-Designtool nachbearbeiten. Dadurch sind auch hohe Ansprüche an die äußerliche Gestaltung erfüllbar und es können eine ganze Reihe von Annotatinen im Sourcecode vermieden werden, die reine Oberflächenthemen betreffen, z.B. Default-Buttons, Tab-Reihenfolge, Ausblenden von Feldern usw. Bei nachträglichen Ergänzungen der Domänenklassen werden Felder für neue Attribute in die bestehenden Layouts vom Framework zur Laufzeit hinein gemerged.
Mit dieser Technik erschlagen wir 80% aller GUIs. Wichtig ist natürlich die Offenheit der Umgebung für die restlichen 20%, wo tiefe Eingriffe notwendig sind. Mit ein bisschen Kenne lässt sich auf Basis der vielen verfügbaren Toolkits in der Java-Welt ein sehr schlankes Naked-Objects-Framework bauen. Wir setzen z.B. auf AjaxSwing, um unsere generisch erzeugten Swing-Oberflächen ins Web zu kriegen.
#zitieren
Gravatar RPR 28.11.2009
um 12:09 Uhr
Hallo Jan,
nun gut, wenn man die GUIs nachbearbeiten kann, ohne den Bezug zum Original zu verlieren (was ein wirklich beeindruckendes Feature ist - die meisten UML-Tools können das nicht mal) und nachträglch reinmergen kann und das gut funktioniert, ist es sicher ne Möglichkeit, sich hier Zeit zu sparen und konsistent zu bleiben. Das Ding ist nicht zufälligerweise open source oder kann man mal wo testen?

Ein Schmunzeln entlockte mir der Satz "Mit dieser Technik erschlagen wir 80% aller GUIs" - so wie viele Java-GUIs aussehen, muss man wirklich von "Erschlagen" sprechen ;-)
#zitieren
Gravatar Jan Lessner 30.11.2009
um 11:40 Uhr
Das stimmt schon - viele GUIs werden von Entwicklern gestaltet, und die haben in der Regel nicht Gestaltung studiert, und das sieht man dann auch ;-)
Ich find's aber OK, das Hauptaugenmerk auf die wirklich wichtigen Dinge zu lenken und an "Nebenkriegsschauplätzen" nicht von vornherein Aufwand für Usability zu spendieren. insbesondere ist es gut, wenn sich da im Nachgang ohne Codeänderung einiges drehen lässt, und das ist genau unsere Intention gewesen. Wir setzen übrigens als GUI-Designtool den JFormDesigner ein, der so komfortabel ist (und insbesondere losgelöst von einer fetten IDE), dass die Fachbereiche es sich nach einer Weile auch selber zutrauen, die Controls an die richtigen Stellen zu schubsen.

Das Toolkit ist leider noch nicht Open Source obwohl es das werden soll. Ich muss unseren Abteilungsleiter noch ein bisschen bearbeiten - das ist mir mit einem anderen Framework in der Vergangenheit auch schon gelungen, deswegen sollte das diesmal auch klappen ;-)
Im Moment schleifen wir noch ein paar Ecken rund. Wenn es Dich sehr interessiert, kann ich checken, ob Du's gegen ein NDA mal haben kannst.
#zitieren

Anzeige

zurück zum Seitenanfang