JSR-296 Swing Application Framework

Afgelopen zomer werd een nieuwe Java Specification Request (JSR) gedefinieerd om een simpel framework voor Swing applicaties te maken. Ondanks dat de Java Swing API al een tijd bestaat, heeft Java nog niet de desktop veroverd zoals dat wel met J2EE bij enterprise applicaties is gebeurd. De Swing API is simpelweg te complex en omvangrijk om er gemakkelijk mee uit de voeten te kunnen. Door deze omvang en complexiteit is het eenvoudig om het verkeerd te doen, en erg moeilijk om een goede implementatie voor een grafische interface te bouwen. Deze JSR is bedoeld om dat probleem op te lossen.

In dit artikel komen een aantal nadelen van de Swing API aan bod welke er naar mijn mening de oorzaak van zijn dat Java van de desktop is weg gehouden. Daarnaast doe ik enkele suggesties die met het Java Desktop initiatief en in het bijzonder de JSR-296 gevolgd zouden kunnen worden.

(An english version of this article can be found here.)

Design patterns
De Swing API biedt een toonbeeld van het gebruik van design patterns. Maar dat is toch juist een goede zaak, zou je op het eerste gezicht zeggen? Ja, en nee. Design patterns zijn nuttig als ze de structuur van de API blootleggen en verhelderen. Maar het kan een slechte zaak worden als de patterns je overweldigen en als gevolg daarvan de structuur juist verbergen. Het is de boom versus het bos.

En laten we er niet om heen draaien, de gemiddelde Java programmeur is helemaal niet zo thuis in het herkennen en toepassen van concepten als object georiënteerd programmeren en design patterns. Hoezeer hardcore Java ontwikkelaars het ook zouden wensen, er is gewoon te veel Java code die het tegendeel bewijst. Met dit gegeven zijn principes als ‘Minder is Meer’ en ‘Keep it Simple, Stupid‘ (KISS) veel waardevoller.

Bijvoorbeeld. Er zou voor gekozen kunnen worden om het hele concept van ‘listeners‘ voor het implementeren van event afhandeling te laten vervallen. In plaats van een listener welke een view aan een model bindt, kun je ook een setter op het model maken en de relatie verder automatisch (laten) afhandelen.

Flexibiliteit
De Swing API is erg flexibel en open voor custom aanpassingen. Dat is prima wanneer je totale vrijheid nodig hebt om gegevens op jouw eigen en unieke manier te laten zien. Maar het is echt niet nodig als je een standaard, recht-door-zee implementatie maakt. Je zou je veel liever op de echt belangrijke dingen willen richten, zaken zoals gegevensinvoer, het ophalen en verwerken van deze gegevens en de navigatie structuur van het programma.

Met deze randvoorwaarde in gedachte is ‘Conventie over Configuratie’ een veel beter principe. Dit betekent dat de programmeur alleen configuratie dient te gebruiken voor de niet-conventionele dingen. Met andere woorden, de flexibiliteit van de API is er als je het nodig hebt, maar het is op een handige manier verborgen als het je niets uitmaakt en je gewoon snel iets wilt maken.

Componenten met een laag abstractie niveau
De traditionele kern van Swing, de Swing GUI componenten, bestaat uit de grafische bouwblokken waarmee een GUI gemaakt kan worden. Knoppen, menu balken, pull-down menu’s, tabellen en split panes om er maar een paar te noemen. Helaas zijn deze bouwblokken vaak van een te laag abstractie niveau om snel GUI ontwikkeling te ondersteunen. Er is gewoon weg te veel standaard template code nodig om zelfs het simpelste GUI component te kunnen gebruiken. Je moet rekening houden met de layout, je moet de model, view en controller definiëren en event listeners leveren. Nogmaals, dit leidt gewoon te veel af van het echte doel dat moet worden bereikt.

Multi-threading
Dé valkuil voor elk Swing project is het blokkeren van de Event Dispatching Thread (EDT) door events die eigenlijk achtergrond processen zijn. Voorbeelden hiervan zijn het ophalen of manipuleren van data. Het gevolg hiervan is het vaak voorkomende “bevriezen” van de GUI. Uiteraard is een niet reagerende GUI een slechte zaak welke leidt tot een lager gebruiksgemak. Ondanks dat het probleem gemakkelijk kan worden vermeden, bewijst dit dat het met de Swing GUI te eenvoudig is om het fout te doen, en dat het moeilijk is om het goed te doen.

Voorkomen dat dit probleem optreedt is een betere oplossing. Verberg dus de threading problemen door een of ander Task object aan te bieden welke processen in zijn eigen thread op de achtergrond kan draaien.

Begrijp me echter niet verkeerd. De Java Swing API is een prachtig framework dat je in staat stelt de meest indrukwekkende GUI’s te maken. Het is alleen dat Swing compleet het doel voorbij schiet wanneer je het toepast op de alledaagse applicaties welke we als gewone Java ontwikkelaar moeten realiseren.

Wat naar mijn bescheiden mening nodig is, is een extra abstractie laag, bovenop de bestaande Java Swing API, welke alle omslachtigheid en complexiteit verbergt. Deze laag biedt eenvoudige oplossingen voor veel voorkomende eisen die gesteld worden aan hedendaagse GUI applicaties. Deze eisen zijn onder andere:

  • componenten van hoog abstractie niveau,
  • ondersteuning voor de applicatie levensloop (installatie, update, activering, configuratie, opstarten, applicatie status, afsluiten, enz.),
  • data binding en validatie,
  • event afhandeling,
  • achtergrond processen.

Elk van deze eisen is een onderwerp op zich. Om deze hier allemaal tot in detail te bespreken past niet binnen het doel van dit artikel. Ik stip daarom slechts kort enkele punten aan.

Componenten van hoog abstractie niveau
De extra abstractie laag moet bestaan uit elementaire componenten van hoog abstractie niveau die nodig zijn voor het creëren van een GUI applicatie. Op het hoogste niveau heb je een Applicatie; de entiteit die de totale applicatie representeert. Het omvat de basis concepten die in elke applicatie te vinden zijn. Het bevat daarnaast alle elementen die je verwacht in een GUI applicatie: een titel balk, een menu balk, een document view, een status balk en dat soort zaken.

Het zou gemakkelijk configureerbaar moeten zijn om tegemoet te komen aan veel voorkomende eisen. Bijvoorbeeld, door het aanpassen van slechts een enkel configuratie veld zou een applicatie eenvoudig moeten veranderen van een single-document naar een multi-document desktop concept. Gewoon out-of-the-box, geen programmeren noodzakelijk. Dit geldt ook voor gebruikelijke layout strategieën (denk aan master-detail view, etc.).

Ondersteuning voor de applicatie levensloop
Het Applicatie component zou tevens het gedrag moeten leveren om de applicatie levensloop te ondersteunen. Denk hierbij bijvoorbeeld aan het opstarten en afsluiten. Andere levensloop events om in ogenschouw te nemen zijn product activering, installatie en/of product updates en configuratie. Het behouden van de applicatie status (bijvoorbeeld, het vasthouden van de grootte en positie van het applicatievenster na het afsluiten) is een andere eigenschap die hieronder kan vallen.

Data binding en validatie
De bedoeling van iedere GUI is om business data te tonen en, meestal ook, om een gebruiker toe te staan deze data te wijzigen. Dit vereist een data binding en validatie oplossing. Deze oplossing zou weinig impact mogen hebben op de data objecten zelf, aangezien deze (domein) objecten vaak al bestaan en waarschijnlijk niet onder de controle van de GUI ontwerper vallen. Een aanpak gebaseerd op POJO’s en de getter/setter conventies zoals gedefinieerd in de Java Bean specificaties is in dit geval een natuurlijke keuze.

Alle concepten die ik hierboven behandeld heb zijn eigenlijk niet nieuw. Er zijn een aantal bestaande oplossingen/frameworks vandaag beschikbaar (Swing GUI Components, Event Handling, Pluggable Look-and-Feel (PLAF), Internationalization (I8N), Accessibility, Java Beans, Java 2D, etc.) om de doelen te realiseren die beschreven zijn in dit artikel. Daarom zou naar mijn bescheiden mening de algemene nadruk van JSR-296 moeten liggen bij hergebruik en vereenvoudiging van bestaande oplossingen.

Keesjan van Bunningen
Senior Java Developer
Finalist IT Group

Links:
JSR-296: Swing Application Framework
http://jcp.org/en/jsr/detail?id=296

Java SE Desktop
http://java.sun.com/javase/technologies/desktop/


Reageer

RSS feed for comments on this post · TrackBack URI