Informaticasite van het Sondervick College te Veldhoven                 © L.J.M van Haperen (bron : R.J. van der Beek)
 

Hoofdstuk 18 Java

18.3 Knoppen precies plaatsen, een figuur toevoegen, foutmeldingen voorkomen

  18.3.1. Labels, knoppen en tekstvensters plaatsen

We gaan hier hetzelfde programma maken als waarmee we zijn begonnen in de cursus Pascal en Visual Basic: we zorgen er voor dat er in het begin het volgende op het scherm staat :



Je moet in de eerste twee tekstvakken getallen in kunnen vullen, en als je dan op het de knop met Bereken klikt dan moet de som, het verschil, het product en het quotient van die twee getallen in de vier tekstvakken er onder komen.

We gaan nu geen layout-manager gebruiken, maar we gaan de labels, knoppen en tekstvensters direct op de juiste plaats zetten.

We beginnen met het label waarop Getal 1 staat. Dat programmeren we op de volgende manier :

lblGetal1 = new Label("Getal 1",Label.CENTER);
lblGetal1.setBounds(20,20,100,20);
lblGetal1.setFont(new Font("TimesRoman",Font.PLAIN,18));
lblGetal1.setForeground(new Color(255,255,255));
lblGetal1.setBackground(new Color(255,0,0));
this.add(lblGetal1);


De opdrachten begrijp je waarschijnlijk voor een groot gedeelte zo wel. Toch even een verduidelijking.
  • lblGetal1 = new Label("Getal 1",Label.CENTER); heeft tot gevolg dat het label wordt gedeclareerd, en direct wordt het (in het geheugen) gemaakt. En wel zo dat het opschrift Getal 1 wordt, en die tekst wordt gecentreerd.
  • lblGetal1.setBounds(20,20,100,20); zorgt er voor dat de linker bovenhoek van het label 20 van de linker kantlijn en 20 van de bovenkant komt. Verder is de breedte van het label 100 pixels en de hoogt 20.
  • Met lblGetal1.setFont(new Font("TimesRoman",Font.PLAIN,18)); bepaal je het lettertype van het opschrift. Verder kun je aangeven of het normaal (=Font.PLAIN), vet (=Font.BOLD), cursief (=Font.ITALIC) of vet en cursief (=Font.BOLD+Font.ITALIC) moet worden afgedrukt, en wat de puntgrootte van de letters is.
  • De opdracht lblGetal1.setForeground(new Color(255,255,255)); heeft tot gevolg dat de kleur van de letters wit wordt, want de RGB-waarden van wit zijn 255, 255 en 255. De opdracht lblGetal1.setBackground(new Color(255,0,0)); heeft tot gevolg dat de achtergrondkleur van het label rood wit wordt, want de RGB-waarden van rood zijn 255, 0 en 0.
  • De opdracht this. add(lblGetal1); tenslotte heeft tot gevolg dat het label echt op het applet geplaatst wordt. Het woordje this mag je hier ook weglaten.
Hiermee is het eerste label klaar. Nu kun je de volgende labels op dezelfde manier maken. Ook de button met het opschrift Bereken maak je op dezelfde manier.
En tenslotte moeten er nog 6 testvensters gemaakt worden. Dat gaat ook op vrijwel dezelfde manier. Maar bij de laatste vier tekstvakken is nog een methode gebruikt, die niet bij de vorigen voorkomt. Bijvoorbeeld txtSom.setEnabled(false); heeft tot gevolg dat de cursor niet in het tekstvak met de naam txtSom geplaatst kan worden, daar kun je dus niet zelf iets in typen als het applet loopt.
Een soortgelijke opdracht is: txtSom.setsetEditable(false); Als je die opdracht gebruikt in plaats van de vorige dat kan de cursor wel in het tekstvak geplaatst worden, maar de tekst kan niet veranderd worden.

  18.3.2. De event-handler

We moeten er nog voor zorgen dat, als er op de knop met Bereken wordt geklikt, de uitkomsten in de laatste vier tekstvakken verschijnen. Daarvoor moeten we vier dingen doen hebben we in H18.2 gezien.
  1. aan het begin een extra package importeren, namelijk: import java.awt.event.*;
  2. in de kopregel implements ActionListener toevoegen.
    De kop wordt dus:
    public class Oefening4 extends Applet implements ActionListener
  3. de interface koppelen aan de Bereken-knop in de methode init:
    btnBereken.addActionListener(this);
  4. De volgende methode toevoegen: public void actionPerformed (ActionEvent e)
    if (e.getSource() == btnBereken)
            {
                    Hier komen de programmaregels die we hier onder bespreken
            }
Welke programmaregels moeten er in bovenstaande methode komen, met andere woorden: wat moet er gebeuren ?

Het eerste getal is ingetypt in de textbox met de naam txtGetal1.
De inhoud daarvan kun je krijgen met txtGetal1.getText().
Denk er om dat Java hoofdlettergevoelig is. Dus als je gettext in plaats van getText typt dan krijg je een foutmelding!

De inhoud van een textbox is net zo als in Visual Basic altijd een string.
Die string moet je eerst declareren, en als je die string s1 noemt dan gaat dat zo: String s1;

Deze opdracht hoeft niet beslist vlak onder de kop te staan. Het mag best tussen de andere code in staan, als het maar gebeurt voordat de string s1 gebruikt wordt.

En dan kun je er voor zorgen dat de inhoud van de eerste textbox in s1 wordt bewaard, de opdracht daarvoor is:
s1=txtGetal1.getText();

Die twee regels kunnen ook tot één regel gecombineerd worden, dan krijg je het volgende:
String s1=txtGetal1.getText();

Nu moet die string in een getal worden omgezet, en dat getal moet worden bewaard bijvoorbeeld in g1. Dan moet je dus eerst een integer declareren, de opdracht daarvoor is: int g1;

en dan moet er voor worden gezorgd dat in g1 de waarde van de string s1 wordt vastgelegd. De opdracht daarvoor is:
g1=Integer.parseInt(s1);
Een methode hoort altijd bij een klasse, en de methode parseInt hoort bij de klasse Integer en die naam moet er dus beslist voor staan!

Je mag die twee regels ook weer tot één regel combineren, dan krijg je het volgende: int g1=Integer.parseInt(s1);

Het kan nog korter. De string s1 hoeft eigenlijk niet bewaard te worden, als het getal g1 maar bekend is.
Daarom kan het ook zo in één opdracht: int g1=Integer.parseInt(txtGetal1.getText());

Als je het getal, dat in de tweede tekstbox is ingetypt, in de variabele g2 wilt zetten, dan wordt de opdracht daarvoor natuurlijk:
int g2=Integer.parseInt(tGetal2.getText());

Nu moeten die twee getallen worden opgeteld, en als dat nieuwe getal wilt bewaren in s dan moet je die declareren met de opdracht int s; en de optelling gebeurt met de opdracht s=g1+g2;
Je kunt die twee regels weer tot één regel combineren: int s=g1+g2;

Nu moet dat getal in de textbox txtSom verschijnen. Dan moet er eerst een string van gemaakt worden, want in een textbox kan alleen een string geplaatst worden.
Declareren en toekennen nu direkt maar in één opdracht: String som=String.valueOf(s));
en dan die string in de textbox plaatsen met de opdracht: txtSom.setText(som);
De laatste twee opdrachten kunnen weer tot één gecombineerd worden m.b.v. de opdracht:
txtSom.setText(String.valueOf(s));

Vervolgens krijg je opdracht om het verschil in de textbox txtVerschil te zetten.
Dat kan net zo als met de som. Op zijn kortst doe je het zo: txtVerschil.setText(String.valueOf(g1-g2));

Dan de opdracht voor het product: txtProduct.setText(String.valueOf(g1*g2));

Als je de opdracht voor de deling op de volgende manier geeft: txtQuotient.setText(String.valueOf(g1/g2)); dan gaan er een aantal dingen verkeerd.

Als er in Java een berekening wordt gemaakt met twee integers dan neemt Java aan dat het resultaat ook weer een integer moet zijn, het wordt dan altijd afgerond op een geheel getal.
Een kommagetal is van het type double.
Maar zelfs als je de opdracht op de volgende manier geeft:
double q = g1 / g2;
dan wordt de uitkomst afgerond op een geheel getal, omdat g1 en g2 beide gehele getallen zijn.
Als je de opdracht op de volgende manier geeft gaat het goed:
double q = (double) g1 / g2;
dan wordt de uitkomst als kommagetal berekend.

De laatste opdracht geeft nog een probleem, want als g2 gelijk aan 0 is, dan zul je een foutmelding krijgen, omdat delen door 0 niet mag en kan.

Alleen als g2 ongelijk aan 0 is mag er gedeeld worden. Daarom moet de laatste opdracht als volgt worden veranderd:
if (g2!=0) {q = (double)g1/g2;};
en daarna komt de volgende opdracht:
if (g2!=0) {txtQuotient.setText(String.valueOf(q));}
else
{txtQuotient.setText(" ");};


Je kunt het ook zo doen:
if (g2==0 ) {txtQuotient.setText(" ");}
else
{txtQuotient.setText(String.valueOf(q));};


Dat heeft tot gevolg dat als g2 gelijk is aan 0 er geen foutmelding komt, maar dat er in het zesde tekstveld niets verschijnt.
( g2!=0 betekent: g2 ongelijk aan 0 )
De totale methode wordt dan als volgt:

public void actionPerformed(ActionEvent e)  
   { 
      if (e.getSource() == btnBereken)
      {
          int g1=Integer.parseInt(txtGetal1.getText());
          int g2=Integer.parseInt(txtGetal2.getText());
          txtSom.setText(String.valueOf(g1+g2));
          txtVerschil.setText(String.valueOf(g1-g2));
          txtProduct.setText(String.valueOf(g1*g2));
          double q=0;
          if (g2!=0)  {q=(double)g1/g2;};
          if (g2==0)   
             {txtQuotient.setText(" ");}
          else
             { txtQuotient.setText(String.valueOf(q));};
      } 

Als het plaatje niet getoond hoeft te worden, en er eventueel een foutmelding mag verschijnen, dan ziet de volledige code er als volgt uit:

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

public class Oefening4 extends Applet implements ActionListener 
{ 
   Label lblGetal1;
   Label lblGetal2;
   Label lblSom;
   Label lblVerschil;
   Label lblProduct;
   Label lblQuotient;
   Button btnBereken;
   TextField txtGetal1;
   TextField txtGetal2;
   TextField txtSom;
   TextField txtVerschil;
   TextField txtProduct;
   TextField txtQuotient;
   
   public void init()
   {
      setLayout(null);
      setSize(250,250);
      lblGetal1 = new Label("Getal 1",Label.CENTER);
      lblGetal1.setBounds(20,20,100,20);
      lblGetal1.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblGetal1.setForeground(new Color(255,255,255));
      lblGetal1.setBackground(new Color(255,0,0));
      add(lblGetal1);
      lblGetal2 = new Label("Getal 2",Label.CENTER);
      lblGetal2.setBounds(20,50,100,20);
      lblGetal2.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblGetal2.setForeground(new Color(255,255,255));
      lblGetal2.setBackground(new Color(255,0,0));
      add(lblGetal2);
      lblSom = new Label("Som",Label.CENTER);
      lblSom.setBounds(20,120,100,20);
      lblSom.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblSom.setForeground(new Color(255,255,255));
      lblSom.setBackground(new Color(255,0,0));
      add(lblSom);
      lblVerschil = new Label("Verschil",Label.CENTER);
      lblVerschil.setBounds(20,150,100,20);
      lblVerschil.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblVerschil.setForeground(new Color(255,255,255));
      lblVerschil.setBackground(new Color(255,0,0));
      add(lblVerschil);
      lblProduct = new Label("Product",Label.CENTER);
      lblProduct.setBounds(20,180,100,20);
      lblProduct.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblProduct.setForeground(new Color(255,255,255));
      lblProduct.setBackground(new Color(255,0,0));
      add(lblProduct);
      lblQuotient = new Label("Quotient",Label.CENTER);
      lblQuotient.setBounds(20,210,100,20);
      lblQuotient.setFont(new Font("TimesRoman",Font.PLAIN,18));
      lblQuotient.setForeground(new Color(255,255,255));
      lblQuotient.setBackground(new Color(255,0,0));
      add(lblQuotient);
      btnBereken = new Button("Bereken");
      btnBereken.setBounds(90,80,100,30);
      btnBereken.setFont(new Font("TimesRoman",Font.PLAIN,18));
      btnBereken.setForeground(new Color(255,255,255));
      btnBereken.setBackground(new Color(100,100,100));
      add(btnBereken);
      txtGetal1 = new TextField();
      txtGetal1.setBounds(150,20,80,25);
      txtGetal1.setFont(new Font("Dialog",Font.PLAIN,18));
      add(txtGetal1);
      txtGetal2 = new TextField();
      txtGetal2.setBounds(150,50,80,25);
      txtGetal2.setFont(new Font("Dialog",Font.PLAIN,18));
      add(txtGetal2);
      txtSom = new TextField();
      txtSom.setBounds(150,120,80,25);
      txtSom.setFont(new Font("Dialog",Font.PLAIN,18));
      txtSom.setEnabled(false);
      add(txtSom);
      txtVerschil = new TextField();
      txtVerschil.setBounds(150,150,80,25);
      txtVerschil.setFont(new Font("Dialog",Font.PLAIN,18));
      txtVerschil.setEnabled(false);
      add(txtVerschil);
      txtProduct = new TextField();
      txtProduct.setBounds(150,180,80,25);
      txtProduct.setFont(new Font("Dialog",Font.PLAIN,18));
      txtProduct.setEnabled(false);
      add(txtProduct);
      txtQuotient = new TextField();
      txtQuotient.setBounds(150,210,80,25);
      txtQuotient.setFont(new Font("Dialog",Font.PLAIN,18));
      txtQuotient.setEnabled(false);
      add(txtQuotient);
      btnBereken.addActionListener(this);
   }

   public void actionPerformed(ActionEvent e)  
   { 
      if (e.getSource() == btnBereken)
      {
          int g1=Integer.parseInt(txtGetal1.getText());
          int g2=Integer.parseInt(txtGetal2.getText());
          txtVerschil.setText(String.valueOf(g1-g2));
          txtSom.setText(String.valueOf(g1+g2));
          txtProduct.setText(String.valueOf(g1*g2));
          double q=0;
          if (g2!=0)  {q=(double)g1/g2;};
          if (g2==0)   
             {txtQuotient.setText(" ");}
          else
             { txtQuotient.setText(String.valueOf(q));};
      } 
   }
}

  18.3.3. Foutmeldingen voorkomen

Als je de methode actionPerformed programmeert zoals hierboven dan zul je tijdens het lopen van het applet soms een foutmelding krijgen.
Dat komt door de opdracht int g1=Integer.parseInt(txtGetal1.getText());
Door die opdracht wordt de string in het tekstvak omgezet in een getal. Maar als er geen getal in het tekstvak staat geeft Java een foutmelding. Er wordt wel gezegd dat die methode een exception opwerpt.
De methode parseInt werpt een exception op als de aangeboden string iets anders dan cijfers bevat. In dat geval kan het programma niet normaal doorgaan.
Je kunt er echter voor zorgen dat er geen foutmelding wordt gegeven, en dat het programma toch normaal doorgaat. Dat gebeurt met een zogenaamde try-catch-opdracht.
Je kunt de opdracht, die misschien een foutmelding zal geven, in de body van een try-opdracht zetten. In het geval dat er inderdaad een exception optreedt, gaat het dan verder in de body van het catch-gedeelte. Gaat echter alles goed, dan wordt het catch-gedeelte overgeslagen. Bijvoorbeeld:

try
{ int g1=Integer.parseInt(txtGetal1.getText());
  int g1=Integer.parseInt(txtGetal1.getText());
  txtSom.setText(String.valueOf(g1+g2)); enz.
}
catch (Exception e)
{ txtSom.setText("geen getal!");
}

In het catch-gedeelte wordt de opgeworpen exception als het ware opgevangen.
Achter het woord catch moet een parameter worden gedeclareerd (Exception e). Via deze parameter is te achterhalen wat er precies fout is gegaan. In het geval van parseInt is dat zo ook wel duidelijk, maar de parameter moet toch gedeclareerd worden, ook als we hem niet gebruiken.
In de body van try kunnen meerdere opdrachten staan. Bij de eerste exception gaat het echter verder bij catch. Bij de rest van de opdrachten achter try mag je er dus van uitgaan dat er geen exception is opgetreden.
Let op dat de bodies van het try- en het catch-gedeelte tussen accolades moeten staan, zelfs als er maar één opdracht in staat.
Het type Exception, waarvan achter catch een variabele wordt gedeclareerd, is een klasse met allerlei subklassen: NumberFormatException, NullPointerException, InterruptedException, enz.
Het is toegestaan om bij één try-opdracht meerdere catch-gedeeltes te plaatsen. Die kun je dan parameters van verschillend (sub-)type geven. Bij het optreden van een exception wordt de eerste afhandeling gekozen met een passend type. Een voorbeeld vormt het lezen van files.
Fouten die daarbij kunnen optreden zijn dat de file in het geheel niet bestaat (FileNotFoundException), of dat de file weliswaar bestaat, maar toch niet gelezen kan worden (IOException). Met één try-catch-catch opdracht kun je op beide mogelijkheden anticiperen:
try { /* opdrachten om de file te lezen */ }
catch (FileNotFoundException fnfe) { uitvoer.setText("de file bestaat niet"); }
catch (IOException ioe) { uitvoer.setText("de file is onleesbaar"); }

Bij sommige typen exception is het verplicht de exception op te vangen, en controleert de compiler of je het wel doet. Als je dan toch geen speciale actie wilt ondernemen als reactie op de exception, kun je de body van catch leeg laten, maar de try-catch moet er beslist staan.

  18.3.4. Een plaatje tonen.

Als je een plaatje wilt tonen moet je de volgende vier dingen toevoegen aan je programma:
  1. aan het begin een extra package importeren, namelijk:
    import java.net.*;
  2. Je moet drie dingen declareren
    • ten eerste moet je een image declareren
      Image pl;
    • ten tweede: Een URL (het adres van de site waar het plaatje staat, meestal de plaats waar het applet ook staat)
      URL adres;
    • ten derde: De MediaTracker declareren, die het laden regelt
      MediaTracker mt;
      // Images kunnen ook worden getoond zonder mediaTracker maar dan flikkert het scherm meestal
  3. In de methode init plaats je de volgende opdrachten:
    • mt = new MediaTracker(this);
    • // Als je de URL geeft moet dat met een try-catch, want het kan zijn dat de opgegeven URL niet bestaat
      // Hier kan er eigenlijk niets mis gaan omdat getDocumentBase() betekent dat je
      // dezelfde URL moet hebben als die waar het applet in staat

      try {
      adres = getDocumentBase();
      }
      catch (Exception e) {}
    • // Nu zeggen we welk plaatje straks in de variabele pl moet komen.
      // Alleen Gif- en JPG-bestanden zijn toegestaan
      // Het plaatje wordt nu nog niet ingeladen
      pl = getImage(adres,"school.jpg");
    • // vertel de MediaTracker dat hij het laden in de gaten moet houden, en dat het plaatje nr. 1 krijgt
      // Het plaatje wordt nog steeds niet ingeladen
      mt.addImage(pl,1);
    • // nu wordt het plaatje geladen (het kunnen ook meer zijn trouwens)
      // dit moet in een try catch blok want als er iets mis gaat bij het laden
      // moeten de opdrachten in het catch-blok worden uitgevoerd.
      // Daar staat niets, dus dan gebeurt er ook niets bijzonders.
      try {
      mt.waitForAll();
      }
      catch (InterruptedException e) {}

  4. In de methode paint plaats je de volgende opdrachten:
    // het plaatje wordt getekend, de linkerbovenhoek is (300,20)
    // de afmetingen zijn hetzelfde als die van het plaatje
    g.drawImage(pl,300,20,this);
    of:
    // het plaatje wordt getekend, de linkerbovenhoek is (300,20)
    // de afmetingen zijn 300 bij 200
    g.drawImage(pl,300,20,300,200,this);

  18.3.5. De volledige code

De volledige code, met het plaatje erbij, en zonder foutmeldingen, ziet er dan als volgt uit:

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

public class Oefening4 extends Applet implements ActionListener 
{ 
   Label lblGetal1;
   Label lblGetal2;
   Label lblSom;
   Label lblVerschil;
   Label lblProduct;
   Label lblQuotient;
   Button btnBereken;
   TextField txtGetal1;
   TextField txtGetal2;
   TextField txtSom;
   TextField txtVerschil;
   TextField txtProduct;
   TextField txtQuotient;
   
   Image plaatje; 
   URL adres_plaatje; 
   MediaTracker mt; 

public void init()
   {
      setLayout(null);
      setSize(600,250);
      mt = new MediaTracker(this);
      try 
      { 
      adres_plaatje = getDocumentBase(); 
      } 
      catch (Exception e1) {} 
      plaatje = getImage(adres_plaatje,"school.jpg"); 
      mt.addImage(plaatje,1);
      try { 
               mt.waitForAll(); 
          } 
      catch (InterruptedException  e1) {} 
 
      lblGetal1 = new Label("Getal 1",Label.CENTER);
      lblGetal1.setBounds(20,20,100,20);
      lblGetal1.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblGetal1.setForeground(new Color(255,255,255));
      lblGetal1.setBackground(new Color(255,0,0));
      add(lblGetal1);
      lblGetal2 = new Label("Getal 2",Label.CENTER);
      lblGetal2.setBounds(20,50,100,20);
      lblGetal2.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblGetal2.setForeground(new Color(255,255,255));
      lblGetal2.setBackground(new Color(255,0,0));
      add(lblGetal2);
      lblSom = new Label("Som",Label.CENTER);
      lblSom.setBounds(20,120,100,20);
      lblSom.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblSom.setForeground(new Color(255,255,255));
      lblSom.setBackground(new Color(255,0,0));
      add(lblSom);
      lblVerschil = new Label("Verschil",Label.CENTER);
      lblVerschil.setBounds(20,150,100,20);
      lblVerschil.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblVerschil.setForeground(new Color(255,255,255));
      lblVerschil.setBackground(new Color(255,0,0));
      add(lblVerschil);
      lblProduct = new Label("Product",Label.CENTER);
      lblProduct.setBounds(20,180,100,20);
      lblProduct.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblProduct.setForeground(new Color(255,255,255));
      lblProduct.setBackground(new Color(255,0,0));
      add(lblProduct);
      lblQuotient = new Label("Quotient",Label.CENTER);
      lblQuotient.setBounds(20,210,100,20);
      lblQuotient.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      lblQuotient.setForeground(new Color(255,255,255));
      lblQuotient.setBackground(new Color(255,0,0));
      add(lblQuotient);
      btnBereken = new Button("Bereken");
      btnBereken.setBounds(90,80,100,30);
      btnBereken.setFont(new Font("TimesRoman", Font.PLAIN, 18));
      btnBereken.setForeground(new Color(255,255,255));
      btnBereken.setBackground(new Color(100,100,100));
      add(btnBereken);
      txtGetal1 = new TextField();
      txtGetal1.setBounds(150,20,80,25);
      txtGetal1.setFont(new Font("Dialog", Font.PLAIN, 18));
      add(txtGetal1);
      txtGetal2 = new TextField();
      txtGetal2.setBounds(150,50,80,25);
      txtGetal2.setFont(new Font("Dialog", Font.PLAIN, 18));
      add(txtGetal2);
      txtSom = new TextField();
      txtSom.setBounds(150,120,80,25);
      txtSom.setFont(new Font("Dialog", Font.PLAIN, 18));
      txtSom.setEnabled(false);
      add(txtSom);
      txtVerschil = new TextField();
      txtVerschil.setBounds(150,150,80,25);
      txtVerschil.setFont(new Font("Dialog", Font.PLAIN, 18));
      txtVerschil.setEnabled(false);
      add(txtVerschil);
      txtProduct = new TextField();
      txtProduct.setBounds(150,180,80,25);
      txtProduct.setFont(new Font("Dialog", Font.PLAIN, 18));
      txtProduct.setEnabled(false);
      add(txtProduct);
      txtQuotient = new TextField();
      txtQuotient.setBounds(150,210,80,25);
      txtQuotient.setFont(new Font("Dialog", Font.PLAIN, 18));
      txtQuotient.setEnabled(false);
      add(txtQuotient);
      btnBereken.addActionListener(this);
   }
   
   public void actionPerformed(ActionEvent e)  
   { 
        if (e.getSource() == btnBereken)
        {
          try
          { 
             int g1=Integer.parseInt(txtGetal1.getText());    
             int g2=Integer.parseInt(txtGetal2.getText());
             txtSom.setText(String.valueOf(g1+g2));
             txtVerschil.setText(String.valueOf(g1-g2));
             txtProduct.setText(String.valueOf(g1*g2));
             double q=0;
             if (g2!=0)  {q=(double)g1/g2;};
             if (g2==0)  
             {
               txtQuotient.setText(" ");
             }
             else
             {
               txtQuotient.setText(String.valueOf(q));};
             } 
          
          catch (Exception e1)
          { 
              txtSom.setText("geen getal!");
          }
        } 
   }
   public void paint(Graphics g)  
   { 
        g.drawImage(plaatje,250,20,300,220,this); 
   }   
}

Opgaven.
Maak nu opgave 3 van hoofdstuk 18 (Java)