7. De klasse TextField

Het is vaak nuttig om in computerprogramma's gegevens in te voeren. In Java kan dat bijvoorbeeld via een tekstvak. Dat is een object van de klasse TextField, dat we kunnen creëren met declaraties als:

TextField vak;
TextField tekstVak;

Tekstvakken moeten worden geïnitialiseerd in de methode init(), bijvoorbeeld zo:

vak = new TextField ("hier intikken");
tekstVak = new TextField (20);

In het eerste geval wordt de tekst hier intikken in het vak geplaatst. In de tweede regel wordt een vak gecreëerd dat breed genoeg is voor (gemiddeld) twintig tekens. Net als knoppen, moeten ook tekstvakken in init() worden toegevoegd aan de applet met:

add (tekstVak);
add (vak);

Zo'n tekstvak zou vrij nutteloos zijn als je geen toegang had tot de ingetikte tekst. Wil je tekst die in een tekstvak staat naar een string kopiƫren, dan kun je gebruik maken van de methode getText() die behoort tot de klasse TextField:

String tekst = vak.getText();
String regel = tekstVak.getText();

Wil je in een tekstvak een nieuwe tekst (of geen tekst) plaatsen, dan kan dat zo:

vak.setText ("Gegevens ingevoerd";
naamVak.setText ("");

In het laatste geval wordt eventuele tekst uit het naamvak verwijderd door er een lege string in te plaatsen.

Stel dat we een applet willen maken waarin getoond wordt uit hoeveel tekens een ingevoerde tekst bestaat. Om het aantal tekens in een string te bepalen heeft de klasse String de methode length(), die als volgt te gebruiken is:

String s = "Be happy";
int lengte = s.length();

In de tekst "Be happy" zitten weliswaar zeven letters, maar lengte bevat na afloop de waarde 8. Een spaties is namelijk ook een teken en telt dus ook mee. Als je dat snel zou willen controleren, kun je de volgende regel in je programma opnemen:

System.out.println (lengte);

Hierdoor wordt de waarde van de variabele lengte afgebeeld, maar niet in het appletvenster. De tekst verschijnt op het tekstscherm (het DOS-scherm). Als je fouten in je programma wil opsporen, kun je vaak met System.out.println( ) de waarde laten zien van variabelen die je niet helemaal vertrouwt.

Ten slotte de hele applet:

// Een applet die het aantal ingevoerde tekens toont
import java.applet.*;
import java.awt.*;
public class StringLengte extends Applet {

String s = "Tik een zin in ..";
TextField vak = new TextField (25);
Button knop = new Button ("klik");
public void init () {
   add (vak);
   add (knop);
}
public void paint (Graphics g) {
   g.drawString (s, 30, 130);

public boolean action (Event e, Object o) {

if (e.target == knop) {
   String temp = vak.getText();
   int aantal = temp.length();
   s = "De tekst bevat "+aantal+"tekens.";
   repaint();
   return true;
}
return false;

}

}

       

Verschillende typen van getallen

Tot dusver zijn we maar één soort getallen tegengekomen, namelijk het type int, dat we gebruiken voor hele getallen. Zouden we proberen een gebroken getal toe te wijzen aan een int-variabele, dan levert dit een foutmelding op en zal de applet niet te compileren zijn.

       int getal = 0.75; //

Dit is dus fout!!!

Om gebroken getallen op te slaan hebben we typen als double. Dus het volgende statement is wel correct:

       double getal = 0.75;

Bij het compileren houdt Java zoveel mogelijk bij of we geen getallen van het type double in een int proberen op te slaan. De volgende twee regels worden door de Java-compiler dan ook niet geaccepteerd.

       double getal = 9;
       int i = getal;

Hier lijkt niets aan de hand. Immers 9 is een heel getal, dus waarom zou dit niet in int i passen?

Maar het maakt niet uit dat dit hier toevallig wel lukt. Een double kan nu eenmaal meer informatie bevatten dan een int. Java staat dan ook ook niet toe dat we een 'groter' type opslaan in een 'kleiner'. Immers als we blindelings een grote emmer leeggieten in een kleine, kan het ook fout lopen!

'CAST'

Een enkel keer is het wel eens nodig om het hele getal-deel van een double in een variabele van het type int op te slaan. Dan kunnen we doen met een zogenaamde cast, namelijk zo:

       double getal = 9;
       int i = (int)getal;

Voor iets minder nauwkeurige gebroken getallen hebben we ook het type float. Daar dit echter wat beperkingen heeft, kun je het beter niet al te vaak gebruiken.

Verder is het nuttig te wijzen op het bestaan van het type long. Dit kan enorm grote getallen aan (van -9223372036854775808 t/m 9223372036854775807), terwijl de int niet verder gaat dan -2147483648 t/m 2147483647.
Maar eerlijk gezegd, heb ik in 25 jaar programmeren nog nooit het type long voor een praktische toepassing nodig gehad.

   

Tekens in een string

Een string bestaat uit tekens. Je kunt een teken in een variabele opslaan van het type char. De inhoud van een char geven we aan met enkele aanhalingstekens, dus bijvoorbeeld zo:

char teken = '#';
char letter = 'A' ;
char russisch = 'Я';

Je ziet dat het type char ook tekens uit andere alfabetten dan het Romeinse kan bevatten. Dat komt omdat het type char in Java werkt met Unicode. In Unicode bestaat elk teken uit 2 bytes, dit in tegenstelling tot ASCII, een systeem waarbij elk teken niet groter is dan 1 byte (eigenlijk maar 7 bits).

Soms wil je wel eens een afzonderlijk teken uit een string bewerken. Dat kan met de methode charAt(). Deze methode (uit de klasse String) geeft ons het zoveelste teken van een string. Let er wel op dat je in Java begint te tellen bij nul. Wil je dus weten wat het eerste teken is, dan kan dat bijvoorbeeld zo:

String programmeerTaal = "Java";
char teken = programmeerTaal.charAt(0);

Hierna bevat teken de letter J.

   

De for-lus

Willen we een deel van een Java-programma een bepaald aantal malen laten herhalen, dan kan dat goed met een zogenaamde "for-lus". Deze bestaat uit het woord for, gevolgd door (tussen haakjes) drie "velden", die gescheiden worden door puntkomma's. De velden zijn:

1. beginwaarde (en soms ook declaratie) van de controle-variabele
2. conditie waaronder de lus voortgezet mag worden
3. met welke waarde neemt de controle-variabele toe of af?

Willen we bijvoorbeeld de getallen 0 tot en met 8 onder elkaar laten zien op het tekstscherm, dan kan dat zo:

for (int i=0; i<9; i++)
   System.out.println (i);

Let op dat we de tweede regel laten inspringen omdat die afhankelijk is van de eerste.

Willen we alleen de even getallen van 2 tot en met 10 laten zien, dan kan dat bijvoorbeeld zo:

for (int i=2; i<11; i+=2)
   System.out.println (i);

De for-lus maakt het mogelijk om teken voor teken een string te bewerken. Zo zouden we bijvoorbeeld uit een tekst de spaties kunnen verwijderen op de volgende manier:

String tekst = "de koe loopt in de wei.", s = "";
for (int i=0; i<tekst.length(); i++) {
   char k = tekst.charAt(i);
   if (k != ' ') // Alleen als k geen spatie is,
      s += k;    // plak teken dan achter s.
}

Hierna bevat de string s de tekst dekoelooptindewei. (dus zonder spaties).

We kunnen een applet maken die een tekst in hoofdletters omzet. Hierbij maken we gebruik van het feit dat de unicodes van de hoofdletters 32 punten lager liggen dan de kleine letters. Zo is de unicode van 'A' gelijk aan 65, terwijl de letter 'a' unicode 97 heeft.

// Tekst wordt omgezet in hoofdletters.
import java.applet.*;
import java.awt.*;
public class Hoofdletters extends Applet  {

TextField vak = new TextField (25);
Button knop = new Button ("klik");
String s = "Tik een woord in en klik ..";
public void init () {
   add (vak);
   add (knop);
}
public void paint (Graphics g) {
   g.drawString (s, 20, 120);
}
public boolean action (Event e, Object o) {

if (e.target == knop) {
   String tekst = vak.getText();
   s = "In hoofdletters: ";
   for (int i=0; i<tekst.length(); i++) {
      char k = tekst.charAt(i);
      if (k>='a' && k<='z')
         k = (char)(k-32);
      s += k;
   }
   repaint();
   return true;
}
return false;

}

}

Je ziet dat de omzetting feitelijk gebeurt met:

k = (char)(k-32);

De uitdrukking (char) noemen we een cast. Met zo'n cast (ook wel typecast genoemd) kunnen we het ene type omzetten in het andere. Zo kunnen we de getalscode van de letter 'A' laten zien met:

System.out.println ((int)'A');

We gebruiken een cast (int) om 'A' te laten zien als getal. Zoals we eerder zagen, is een cast nodig in Java als er informatie verloren dreigt te gaan, zoals in de volgende regels:

double a = 10, b = 5;
int c = a / b;

Deze regels geven een foutmelding. Weliswaar is 10/5 gelijk aan 2, maar een deling tussen twee variabelen van het type double kan een gebroken getal opleveren. Daarbij zou dan het breukdeel verloren gaan. We moeten de compiler duidelijk maken dat dit geen vergissing is met:

int c = (int)(a/b);

   

INTEGERDELING:

Deze cast is niet nodig als a en b allebei van het type int zijn. Java geeft bij deling van twee variabelen van het type int namelijk altijd een heel getal als uitkomst, zoals bij de volgende deling:

int a = 5, b = 2;
double c = a / b;

Je zou misschien de waarde 2.5 verwachten. Maar de berekende waarde van c blijkt 2 te zijn, Deling tussen twee int-variabelen wordt door Java berekend met als uitkomst een heel getal. Eventuele breukdelen worden niet berekend.

Willen we een gebroken getal als uikomst, dan moeten we aan Java duidelijk maken dat een van de twee betrokken getallen als gebroken getal moet worden beschouwd. Dat kan op een aantal manieren, bijvoorbeeld zo:

int a = 5;
double b = 2;
double c = a / b;

Of zo:

int a = 5, b = 2;
double c = (double)a / b;

Niet correct is de volgende manier:

int a = 5, b = 2;
double c = (double)(a / b);

Wat we daar namelijk doen, is eerst a / b laten uitrekenen. Als integer-deling levert dat 2 op. Dat we die uitkomst daarna naar double casten, heeft natuurlijk geen invloed meer op de waarde.

   

Standaardmethode voor omzetting naar hoofdletters

Ten slotte moet nog even vermeld worden dat de klasse String de standaardmethode toUpperCase() heeft om een string in hoofdletters om te zetten, namelijk zo:

String groteLetters = kleineLetters.toUpperCase();

Opdracht 7.1

Schrijf een applet waarin met een for-lus de getallen van 1 tot en met 10 onder elkaar in het appletvenster worden getoond.

Opdracht 7.2

Schrijf een applet waarin met een for-lus de getallen van 1 tot en met 80 in een nette tabel worden getoond.

Opdracht 7.3

Schrijf een applet waarin een postcode kan worden ingevoerd van 4 cijfers en twee letters (zonder spaties). De applet deelt hierna mee of de postcode correct is of niet.

Opdracht 7.4

Schrijf een applet waarin een zin kan worden ingevoerd, waarna deze als volgt wordt omgezet: elke r verandert in l en elke R in een L.

   

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