6. Reageren op een knop

Als onze applet eenmaal gestart was, konden we daar tot nu toe weinig invloed meer op uitoefenen. Daar gaan we nu verandering in aanbrengen met de klasse Button. Zo'n knop wordt normaliter gedeclareerd in het bovenste deel van de applet (het declaratiegedeelte). Een variabele die in dit deel is gedeclareerd is in het hele programma bekend. Declaraties van knoppen zien er bijvoorbeeld zo uit:

Button knop;
Button knopje;
Button button;

De laatste declaratie lijkt wat vreemd, maar is toch correct, want Java maakt onderscheid tussen hoofd- en kleine letters . De knop moet echter nog wel geïnitialiseerd worden. Dat gebeurt in de methode init() met:

knop = new Button ("hier klikken");
knopje = new Button ("klik");
button = new Button ("click here");

Je kunt de initialisatie en de declaratie ook combineren, bijvoorbeeld zo:

Button knop = new Button ("hier klikken");
Button knopje = new Button ("klik");
Button button = new Button ("click here");

Tenslotte moeten we de knop nog toevoegen aan de applet. Dat gebeurt met het statement add, dat normaliter thuishoort in de methode init, als volgt:

add (knop);
add (knopje);
add (button);

We kunnen op dit moment al een applet met een knop maken:

// Een knop die helemaal niets doet
import java.applet.*;
import java.awt.*;
public class LozeKnop extends Applet {
Button knop = new Button ("klik");
   public void init () {
      add(knop);
   }
}

De knop reageert als we erop klikken, maar verder doet deze applet natuurlijk helemaal niets. Willen we controleren of er op een knop geklikt is, dan kan dat bijvoorbeeld in de methode action.

Zoals paint standaard een object van de klasse Graphics meekrijgt, zo krijgt action standaard twee objecten mee, de eerste van de klasse Event en de tweede van de klasse Object. De eerste regel (kopregel) van de methode action ziet er als volgt uit:

public boolean action (Event e, Object o) {

Deze methode is van het type boolean. Dat betekent dat hij de waarde true of false moet afgeven, bijvoorbeeld zo:

return true;

Gewoonlijk geeft de methode action de waarde true af als er op de knop geklikt is, en anders false. Bekijk eens goed hoe de volgende applet in elkaar zit:

// Een knop die de achtergrond
// van het venster verandert als
// er op de knop geklikt wordt.
import java.applet.*;
import java.awt.*;
public class WisselKleur extends Applet {

Button knop = new Button ("klik");
boolean licht = true;

public void init () {
   add (knop);
}

public void paint (Graphics g) {
   if (licht)
      setBackground (Color.lightGray);
   else
      setBackground (Color.darkGray);
}

public boolean action (Event e, Object o) {
   if (e.target == knop) {
      licht = !licht;
      repaint();
      return true;
   }
return false;
}

}

De variabele licht wordt 'globaal' (oftewel in het declaratiedeel) gedeclareerd met:

   boolean licht = true;

In de methode action wordt gecontroleerd of er op de knop is geklikt met:

    if (e.target == knop) {

Als er wordt geklikt, moet er een aantal statements worden uitgevoerd. Om te zorgen dat na het klikken al deze statements worden uitgevoerd, worden ze met accolades tot een blok gemaakt.

De waarde van licht wordt na elke klik omgekeerd met:

    licht = !licht;

Dezelfde soort expressie kwamen we ook al tegen bij de schietschijf in hoofdstuk 4. Het betekent dat de waarde van licht wordt omgekeerd.

Het opnieuw tekenen van het scherm gebeurt door de aanroep repaint(). Hierdoor wordt feitelijk de methode paint() (opnieuw) aangeroepen.

   

Een 'pulserende' cirkel

Laten we eens proberen een programma te maken dat reageert op het klikken op een knop. We kunnen een cirkel tekenen die een stukje groter (en weer kleiner) wordt bij elke klik op de knop.

// Pulserende cirkel als demonstratie
// van de methode action en een knop.
import java.applet.*;
import java.awt.*;
public class PulserendeCirkel extends Applet {

Button knop = new Button ("hier klikken");
int toename = 10, diameter = 5, maxGrootte;

public void init() {
   add (knop);
   setBackground (Color.yellow);
}

public void paint (Graphics g) {
   Dimension d = getSize();
   int hoogte = d.height, breedte =     d.width;
   if (breedte < hoogte)
      maxGrootte = breedte;
   else
      maxGrootte = hoogte;
   g.setColor (Color.red);
   int x = (breedte - diameter) / 2;
   int y = (hoogte - diameter) / 2;
   g.fillOval (x, y, diameter, diameter);
}

public boolean action (Event e, Object o) {
   if (e.target==knop) {
      diameter = diameter + toename;
      if (diameter<10 || diameter>=maxGrootte)
         toename = -toename;
      repaint();
      return true;
   }
   return false;
}

}

We bepalen welke afmeting de grootste is met behulp van deze regels:

Dimension d = getSize();
int hoogte = d.height, breedte = d.width;
if (breedte < hoogte)
   maxGrootte = breedte;
else
   maxGrootte = hoogte;

Als je het programma laat uitvoeren, zie je dat de cirkel beurtelings groter en kleiner wordt. De wisseling tussen toename en afname wordt verzorgd door de regels:

if (diameter<10 || diameter>=maxGrootte)
toename = -toename;

De operator || wordt uitgesproken als or en betekent hier dat de waarde van toename wordt omgekeerd als de diameter kleiner is dan 10 of als de diameter groter is dan maxGrootte.

   

Over = en ==

Ten slotte nog even iets over de tekens = en ==, die we al enige malen gezien hebben. Eerst het teken =

       a = 7;

Deze expressie betekent: a wordt 7, oftewel: a krijgt de waarde 7.

De operator == wordt gebruikt in vergelijkingen (bijvoorbeeld bij if of while) en betekent dat de twee variabelen aan beide kanten van == dezelde waarde hebben, bijvoorbeeld zo:

if (a==b) . . .
while (x==y) . . .

   

Opdracht 6.1

Schrijf een applet die in het midden van het venster de volgende tekst laat verschijnen:

        Er is 0 maal op de knop geklikt.

Na klikken verandert deze tekst in:

        Er is 1 maal op de knop geklikt.

Uiteraard wordt dit aantal na elke klik 1 groter.

Opdracht 6.2

Schrijf een applet waarin links in het venster een stip staat die bij elke klik op de knop eindje verder 'wandelt', eerst naar rechts, dan weer terug, enz.

   

(c) 2003-2008, Thomas J.H.Luif