H8 Knoppen en tekstvakken

Leerdoelen

Na het bestuderen van dit hoofdstuk wordt van je verwacht dat je:

  • Een knop, teksvak en label aan je Applet kunt toevoegen
  • weet hoe je event-handling aan knoppen en tekstvakken kunt toevoegen middels een inwendige klasse
  • weet hoe je een lege string gebruikt
  • Hoe je getallen in string vorm kunt converteren naar echte getallen

Praktijk

Een knop zichtbaar maken

Eerst de code:

//Voorbeeld 8.1

import java.awt.*;
import java.applet.*;


public class Knop extends Applet {
    Button knop;						
	
    public void init() {
        knop = new Button();
        knop.setLabel( "Klik op mij" );
        add(knop);
    }

    public void paint(Graphics g) {
        g.drawString("Doet deze knop wel iets?", 50, 60 );
    }
}

Een knop zichtbaar maken gaat in vier stappen:

De tweede en derde stap kun je ook in één keer afhandelen. De klasse Button heeft namelijk twee "constructors", één zonder argumenten en één met (String label) als argument.

knop = new Button( "Klik op mij" );

Als je dit programma uitvoert en je klikt op de knop, dan zie je de knop zelf op het scherm wel reageren (Dat handelt je besturingssysteem voor je af), maar verder gebeurt er niets. Dat komt omdat er nog geen methode met de knop is verbonden.

Event-handling

//Voorbeeld 8.2

import java.awt.*;
import java.applet.*;
import java.awt.event.*;


public class Knop extends Applet {
    Button knop;
    String schermtekst;
	
    public void init() {
        schermtekst = "Doet deze knop wel iets?"
        knop = new Button("Klik op mij");
        KnopListener kl = new KnopListener();
        knop.addActionListener( kl );
        add(knop);
    }

    public void paint(Graphics g) {
        g.drawString(schermtekst, 50, 60 );
    }
	
    class KnopListener implements ActionListener {
        public void actionPerformed( ActionEvent e ) {
            schermtekst = "Ja, deze knop doet wel iets";
        }
    }
}

Ook nu zijn er vier stappen nodig om de event-handler te activeren:

Als we de applet gaan uitvoeren, wordt de knop getoond en eronder de tekst "Doet deze knop wel iets?". Verder gebeurt er niets. Als je op de knop klikt, dan gebeurt er ook niets! Als je het scherm iets vergroot, dan wordt de tekst ineens wel gewijzigd. Dit komt omdat de string schermtekst in het geheugen netjes is aangepast, maar het venster is niet ververst en dus blijft de oude tekst staan totdat het scherm wordt ververst. We moeten er dus voor zorgen dat het venster ververst wordt. Dat doen we met de opdracht repaint().

De inwendige klasse KnopListener komt er dan zo uit te zien:

class KnopListener implements ActionListener {

    public void actionPerformed( ActionEvent e ) {
        schermtekst = "Ja, deze knop doet wel iets";
        repaint();
    }
}

We wijzigen eerst de inhoud van de string en geven daana opdracht het scherm te verversen. De methode paint() wordt door een aanroep naar repaint() opnieuw uitgevoerd.

Een tekstvak

Een tekstvak maken gaat op dezelfde manier als het maken van een knop.

//Voorbeeld 8.3

import java.awt.*;
import java.applet.*;

public class Tekstvak extends Applet {
    TextField tekstvak;				
	
	
    public void init() {
        tekstvak = new TextField("Klik op mij", 20);
        add(tekstvak);
    }

    public void paint(Graphics g) {
        g.drawString("Type iets in het tekstvakje", 50, 60 );
    }
}

Er zijn drie stappen nodig om een tekstvak op het scherm zichtbaar te maken:

Allereerst weer de declaratie:

TextField tekstvak;

Dan het reserveren van het geheugen:

tekstvak = new TextField("Klik op mij", 20);

De tekst "Klik op mij" komt in het tekstvak te staan. Er kunnen ongeveer 20 tekens in het tekstvak staan. Dat is nooit helemaal zeker als het gaat om proportionele letters.
Dan moet het tekstvak aan de applet worden toegevoegd:

add(tekstvak);

Een label

Het zou mooier als de tekst "Type iets in het tekstvakje" niet ergens onder maar voor het tekstvak komt te staan. Dat wordt opgelost met een zogenaamd label. Dit is een tekstvak waarin niets ingetikt kan worden, maar waar het programma wel tekst in kan zetten. Hieronder zie je het gebruik van het label aan de hand van het vorige voorbeeld.

//Voorbeeld 8.4

import java.awt.*;
import java.applet.*;

public class Tekstvak extends Applet {
    TextField tekstvak;
    Label label;				
	
	
    public void init() {
        tekstvak = new TextField("Klik op mij", 20);
        label = new Label("Type iets in het  tekstvakje");
        add(label);
        add(tekstvak);
    }

    public void paint(Graphics g) {}
	
}

In drie stappen is het label gerealiseerd:

Als de applet wordt uitgevoerd kun je in het tekstvak iets intikken. Wat je intikt, verschijnt in het tekstvak. Omdat alleen standaardhandelingen voor het tekstvak nodig zijn, namelijk de ingetikte tekst tonen, hoeft voor een tekstvak geen event-handling plaats te vinden. Windows handelt dit intern af. Wel kan de gebruiker op de enter-toets drukken en op die manier een gebeurtenis veroorzaken die wel afgehandeld moet worden.

// Voorbeeld 8.5
import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Tekstvak extends Applet {
    TextField tekstvak;
    Label label;				
    String s;
	
    public void init() {
        tekstvak = new TextField("Klik op mij", 20);
        label = new Label("Type iets in het tekstvak " + 
            "en druk op enter");
        tekstvak.addActionListener( new TekstvakListener() );
        add(label);
        add(tekstvak);
        s = "";
    }

    public void paint(Graphics g) {
        g.drawString(s, 50, 60 );
    }
	
    class TekstvakListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            s = tekstvak.getText();
            repaint();
        }
    }
}

Ook hier wordt net zoals bij de knoppen eerst de listener aan het tekstvak gekoppeld:
tekstvak.addActionListener( new TekstvakListener() );
en wordt in de methode actionPerformed van de klasse TekstvakListener de gebeurtenis afgehandeld.
Met de regel s = tekstvak.getText(); wordt de tekst in het tekstvak in de string s gezet. Deze string wordt in het venster van de applet op het scherm gezet.

Een knop en een tekstvak

//Voorbeeld 8.6

import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Tekstknop extends Applet {
    TextField tekstvak;				
    Button knop;
	
    public void init() {
        tekstvak = new TextField("", 30);
        knop = new Button("Ok");
        knop.addActionListener( new KnopListener() );
        add(tekstvak);
        add(knop);
    }

    public void paint(Graphics g) {
        g.drawString("Type een hele lange tekst " +
           "in het tekstvakje " +
           "en klik op Ok", 50, 60 );
    }
	
    class KnopListener implements ActionListener	{
        public void actionPerformed( ActionEvent e ) {
            tekstvak.setText("Jammer, " +
                "maar nu staat er iets anders");
            repaint();
        }
    }
}

In feite is in deze code slechts één nieuw element aangebracht:
tekstvak.setText("Jammer, maar nu staat er iets anders");

Als een gebruiker op de knop Ok klikt wordt zijn tekst vervangen door de hierboven gegeven tekst. SetText is een methode van het object tekstvak.
De "" in de regel tekstvak = new TextField("", 30); is een lege string. Met een lege string kun je het tekstveld leeg laten of leeg maken als er iets in staat.

De volgende regel lijkt nieuw maar is het niet:

knop.addActionListener( new KnopListener() );

Deze regel is een samenvoeging van de twee volgende regels uit voorbeeld 8.2:

KnopListener kl = new KnopListener();
knop.addActionListener(kl);

Er zijn nu twee elementen aan de applet toegevoegd:
add(tekstvak);
add(knop);
De volgorde van deze regels bepalen de volgorde op het scherm: we zien eerst het tekstvak en daarna de knop rechts ervan. Als deze regels in omgekeerde volgorde zouden staan, dan zou de knop links van het tekstvak staan.

Tekstvakken en getallen

Als een getal uit een tekstvak opgehaald wordt, dan is dat altijd in de vorm van een string. Er is een extra stap nodig om die string tot int of een double te converteren.

//Voorbeeld 8.7

import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class Tekstvak extends Applet {
    TextField tekstvak;
    Label label;				
    double getal;
	
    public void init() {
        tekstvak = new TextField("", 20);
        label = new Label("Type een getal";
        tekstvak.addActionListener( new TekstvakListener() );
        add(label);
        add(tekstvak);
    }

    public void paint(Graphics g) {
        g.drawString("Het getal is " + getal, 50, 60 );
    }
	
    class TekstvakListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            String s = tekstvak.getText();
            getal = Double.parseDouble( s );
            //Je kan deze regels ook samenvoegen
            //getal = Double.parseDouble(tekstvak.getText());
            repaint();
        }
    }
}

De extra stap staat in de methode actionPerformed() en is de regel:
getal = Double.parseDouble( s );
De string s is in de vorige regel opgehaald uit het tekstvak en wordt in deze regel door de methode Double.parseDouble( ) omgezet in een double en die waarde wordt in de variabele getal gezet. Voor een integer luidt deze regel:
getal = Integer.parseInt( s );

Vragen

  1. Wat is event-handling?
  2. Wat is een gebruikersinterface?
  3. Waarom moet er voor een knop wel en voor een tekst geen event-handling geprogrammeerd worden?
  4. Wat is een lege string?
  5. Wat is het verschil tussen een tekstvak en een label?
  6. Waarom moeten getallen uit een tekstvak altijd geconverteerd worden naar een double of een int?

Opdracht 8.1

Maak een applet in Java, waarin een tekstvak met een label en twee knoppen voorkomen. De eerste knop is de ok-knop die ervoor zorgt dat wat de gebruiker in het tekstvak heeft ingetikt in het venster van de applet zichtbaar wordt. De tweede knop is de reset-knop die het tekstvak leeg maakt als de gebruiker erop klikt.

Opdracht 8.2

Op de open avonden van school wordt bijgehouden hoeveel mannen en vrouwen en hoeveel potentiële vrouwelijke en mannelijke leerlingen de school op zo'n avond bezoeken. Schrijf een applet waarin alleen op één van de vier knoppen geklikt hoeft te worden en de vier aantallen en het totaal wordt in het venster van de applet worden bijgehouden.

Opdracht 8.3

Maak een applet waarin een tekstvak met label en een knop Ok staan. In het tekstvak moet een bedrag worden ingevuld en zodra de gebruiker op Ok klikt of op de enter-toets drukt moet de prijs inclusief BTW (= 21%) in het venster geplaatst worden.

Praktijkopdracht

Maak een rekenmachine in een applet. De rekenmachine bestaat uit twee tekstvakken en vier knoppen. De gebruiker tikt in het eerste tekstvak een getal in en in het tweede en klikt vervolgens op één van de knoppen om de berekening te laten uitvoeren. De uitkomst wordt in het eerste tekstvak getoond en het tweede tekstvak wordt leeggemaakt.

Uitbreiding staafdiagram

Voeg labels, invoervelden en een knop toe zodat de gebruiker de waardes van het staafdiagram kan veranderen