Tekenen en vullen met de Java AWT

 
In de kursus Objectgeoriënteerd programmeren met Java leren we onder andere dat een getekende rechthoek of ellips zowel in de breedte als in de hoogte 1 pixel groter wordt dan je op grond van de parameters zou vermoeden. Dit in verband met de manier waarop Java het abstrakte koördinatenstelsel vertaalt naar schermpixels (zie boek 1, bladzijde 217). Wat we hier leren is in overeenstemming met de API Reference.

Volgens diezelfde API Reference worden gevulde figuren anders getekend: deze blijven wél netjes binnen de door ons opgegeven perken. Het kursusboek waarschuwt dat dit niet klopt: bij gevulde figuren zou eerst de omtrek worden getekend zoals boven omschreven, en zou deze vervolgens worden opgevuld. Resultaat: ook hier moeten we hoogte en breedte één pixel te klein opgeven om de gewenste afmeting te verkrijgen (blz. 218).

Mijn eigen ervaring is echter dat de fill-methoden wel degelijk werken zoals beloofd door de API Reference. Ik gebruik de Java VM + AWT zoals die op de CD-ROM bij de kursus is geleverd. Hebben de schrijvers van de kursus misschien een andere versie gebruikt? De (belabberde) wijze waarop gevulde ellipsen worden getekend doet namelijk wel vermoeden dat ze vroeger zowel naar rechts als naar beneden één pixelrijtje meer gebruikten. Gevulde ellipsen hebben in Java, althans bij mij thuis, geen enkele symmetrie, en dat terwijl ze twee onderling loodrechte spiegellijnen horen te hebben, waarvan het snijpunt een tweetallige as is.

Probeer de bijgaande applet eens uit en let goed op de rechter- en onderkanten van de getekende en gevulde ellipsen. De niet-gevulde zijn bij mij symmetrisch, de gevulde niet. Bovendien zijn ze één pixel smaller en één pixel lager, net als gevulde rechthoeken trouwens. Dat is debiel, maar wel in overeenstemming met de API Reference. Het zijn alleen geen ellipsen meer - en daardoor is het geheel toch weer níet in overeenstemming met de API Reference; die belooft namelijk een ellips.

Het heeft er alle schijn van dat de vulmethode ooit symmetrische ellipsen tekende, die dan echter naar rechts en naar beneden één pixelrijtje meer gebruikten dan gespecificeerd. Kennelijk is men hierop gewezen, maar inplaats van de methode opnieuw - en nu goed - te implementeren, zal men gedacht hebben: komaan, we snijden gewoon het meest rechtse en het onderste reepje van de figuur af, en dan heeft-ie weer precies de opgegeven maten. Bij een rechthoek werkt dat; je houdt dan weer een zuivere rechthoek over. Maar doe je zoiets met een ellips, dan raakt die lelijk verminkt.

Omdat het leuke van applets is, dat ze weliswaar "op" een webpagina staan, maar op de computer van de gebruiker worden uitgevoerd - met gebruikmaking van de AWT-implementatie op de machine van de gebruiker - is het natuurlijk heel goed mogelijk dat deze applet bij een ander wel prachtige symmetrische ellipsen tekent, al dan niet met een rijtje pixels teveel. Probeer eens een stel kombinaties uit: (0,0), (0,1), (1,10), (0,10), (2,2), (15,2), (3,3), (63,63), (63,64), (64,64), enz... en let goed op vorm- en grootteverschillen tussen de getekende en de gevulde figuren. Gebeurt bij jullie hetzelfde als bij mij, of niet? Reageer liefst in de nieuwsgroep studie.alg.cursus.t42211; ik ben vooral benieuwd hoe het mensen vergaat die vanaf andere platforms werken. Zelf kan ik alvast melden dat voor Netscape onder Linux met XFree86 hetzelfde geldt als onder Windows98, hoewel de tekenroutines toch duidelijk verschillen (te zien aan uitstekende pixeltjes e.d.; het is werkelijk treurig hoe slecht Java blijkbaar gestandaardiseerd is).

De JAR waarin deze ik deze applet heb verpakt, bevat ook de Java-bronkode van de gebruikte klassen, maar je kunt die ook los in de browser bekijken (klikken op een van onderstaande links opent een nieuw venster):

De aanleiding voor het maken van deze pagina was trouwens de stoplichtapplet in het tentamen van 26 augustus 1999. Maar daarover meer in de nieuwsgroep.

Paul Vinkenoog
<paul op vinkenoog punt nl> (vervang "op" door @, enz., en plak aaneen)