Programmazione per TWM: Esercitazione di laboratorio #23 (20/05)

Gli obiettivi di questa esercitazione sono: imparare a utilizzare i gestori del layout e gli ascoltatori di eventi dell'AWT, saper costruire semplici interfacce utente grafiche (capitolo 12).

Raccomandazioni: Ove non altrimenti indicato, rispondete alle domande prima ragionando su carta e poi provando a editare, compilare ed eseguire. Gli esercizi etichettati con l'asterisco (*) sono più difficili: affrontateli dopo aver risolto gli altri.

Esercizio 1

Obiettivo: capire come usare gli ascoltatori interni ed esterni, con e senza parametri nel costruttore.

Attività:

  1. Considerate il codice seguente:
    public class Es1 {
      public static void main(String[] args) {
        Finestra1 f = new Finestra1();
        f.pack();
        f.setVisible(true);
      }
    }  
    import java.awt.*;
    import java.awt.event.*;
    
    public class Finestra1 extends Frame {
      public Finestra1() {
        Label etichetta;
        etichetta = new Label("Questo testo cambia quando premi il pulsante",Label.CENTER);
        Button pulsante = new Button("Premi per cambiare il testo sopra");
        this.add(etichetta,BorderLayout.NORTH);
        this.add(pulsante,BorderLayout.SOUTH);
        this.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        pulsante.addActionListener(new CambiaTesto());
      }
    
      class CambiaTesto implements ActionListener {
        private int conta=1;
    
        public void actionPerformed(ActionEvent e) {
          etichetta.setText("Hai premuto "+(conta++)+" volt"+(conta<2?"a":"e"));
        }
      }
    }  
    Il codice contiene un errore. Quale? Provate a cercarlo senza compilare.
    Se dopo 2 minuti non avete ancora trovato l'errore provate a compilare. Qual è l'errore?
    Come potete riparare l'errore potendo solo spostare la riga Label etichetta;? Dove va messa? Perché?
  2. Considerate questa variante di Finestra1:
    import java.awt.*;
    import java.awt.event.*;
    
    public class Finestra2 extends Frame {
      public Finestra2() {
        Label etichetta;
        etichetta = new Label("Questo testo cambia quando premi il pulsante",Label.CENTER);
        Button pulsante = new Button("Premi per cambiare il testo sopra");
        this.add(etichetta,BorderLayout.NORTH);
        this.add(pulsante,BorderLayout.SOUTH);
        this.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        pulsante.addActionListener(new CambiaTesto());
      }
    }
    
    class CambiaTesto implements ActionListener {
      private int conta=1;
    
      public void actionPerformed(ActionEvent e) {
        etichetta.setText("Hai premuto "+(conta++)+" volt"+(conta<2?"a":"e"));
      }
    }
    
    Quali sono le differenze con la prima versione? Questa seconda versione viene compilata senza errori? Spostando la riga di codice Label etichetta;, come nell'attività precedente, viene compilata senza errori? Perché?
  3. Considerate quest'altra variante di Finestra1 e Finestra2:
    import java.awt.*;
    import java.awt.event.*;
    
    public class Finestra3 extends Frame {
      public Finestra3() {
        Label etichetta;
        etichetta = new Label("Questo testo cambia quando premi il pulsante",Label.CENTER);
        Button pulsante = new Button("Premi per cambiare il testo sopra");
        this.add(etichetta,BorderLayout.NORTH);
        this.add(pulsante,BorderLayout.SOUTH);
        this.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        pulsante.addActionListener(new CambiaTesto(...));
      }
    }
    
    class CambiaTesto implements ActionListener {
      private int conta=1;
      private Label etichetta;
    
      public CambiaTesto(Label etichetta) {this.etichetta = etichetta;}
    
      public void actionPerformed(ActionEvent e) {
        etichetta.setText("Hai premuto "+(conta++)+" volt"+(conta<2?"a":"e"));
      }
    }
    
    Cosa dovete sostituire ai puntini per far compilare correttamente il programma?
    Sostituite le 2 occorrenze di Finestra1 con Finestra3 nel programma Es1 e verificate che tutto funzioni bene.
    Sostituite le 5 occorrenze della parola etichetta in CambiaTesto con la parola lab. Funziona tutto correttamente o si deve cambiare anche qualcosa nel codice di Finestra3? Perché?
    Spostando la riga di codice Label etichetta; come nella prima attività funziona ancora tutto correttamente? Perché?
  4. Quale tra Finesta1 e Finestra3 è una finestra con ascoltatore interno? Quale tra le due è una finestra con ascoltatore esterno con passaggio di parametro?

Esercizio 2

Obiettivo: saper utilizzare i gestori del layout.

Attività:

  1. Sostituire i puntini per far comparire 2 pulsanti nella finestra (suggerimento: ha a che fare con i gestori del layout. Provate per prima cosa a levare semplicemente i puntini. Quanti pulsanti compaiono? Perché?):
    import java.awt.*;
    import java.awt.event.*;
    public class Es2 {
      public static void main(String[] args) {
        Frame f = new Frame();
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        ...
        f.add(new Button("B1"));
        f.add(new Button("B2"));
        f.setBounds(100,100,200,200);
        f.setVisible(true);
      }
    }
      
  2. Modificate il codice di Es2 per aggiungere un Panel con sfondo rosso e con due nuovi pulsanti nella parte alta della finestra. I pulsanti B1 e B2 devono essere uno a destra e l'altro a sinistra. (Suggerimento: fate attenzione al gestore del layout della finestra)
  3. Usando il numero opportuno di Panel con gli opportuni gestori del layout, modificate il codice di Es2 per far apparire due pulsanti a sinistra, tre a destra ed uno al centro. Il pulsante al centro non deve cambiare dimensione quando si cambia la dimensione della finestra.

Esercizio 3

Obiettivo: saper utilizzare il meccanismo degli eventi dell'AWT.

Attività:

  1. Considerate il codice seguente:
    import java.awt.*;
    import java.awt.event.*;
    
    public class Es3 {
      public static void main(String[] args) {
        Frame f = new Frame();
        f.addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        Panel centrale = new Panel();
        Button ba = new Button("a");
        Button bb = new Button("b");
        Button bc = new Button("c");
        centrale.add(ba);
        centrale.add(bb);
        centrale.add(bc);
        Label display = new Label();
        f.add(centrale,BorderLayout.CENTER);
        f.add(display,BorderLayout.NORTH);
        ba.addActionListener(new Echo(display));
        f.setVisible(true);
      }
    }
    
    class Echo implements ActionListener {
      private Label l;
      public Echo(Label l) {this.l = l;}
      public void actionPerformed(ActionEvent e) {
        String display = l.getText();
        String nuovodisplay = display.concat(e.getActionCommand());
        l.setText(nuovodisplay);
      }
    }  
    Aggiungere le opportune righe di codice a Es3 per fare in modo che anche i pulsanti b e c, quando vengono premuti, aggiungano lettere al display.
  2. Aggiungere un secondo display in basso e fare in modo che i pulsanti a e b aggiungano lettere a quello in alto, mentre c a quello in basso.
  3. Modificando solo Es3 fare in modo che il pulsante c aggiunga lettere ad entrambi i display.
  4. (*) Aggiungere un pulsante cancella e un opportuno ascoltatore per far cancellare l'ultima lettera aggiunga al display superiore.
  5. Completate il codice seguente per fare in modo che quando si clicca sul pulsante verde venga selezionato il colore verde e solo quando si clicca sul pulsante colora il pannello venga colorato del colore selezionato in precedenza:
    import java.awt.*;
    import java.awt.event.*;
    
    public class Es4 {
      public static void main(String[] args) {
        Frame f = new FinestraColori();
        f.setVisible(true);
      }
    }
    
    class FinestraColori extends Frame {
      private Panel pannelloColorato;
      private Color colore;
      private Label l_colore;
    
      public FinestraColori() {
        addWindowListener(new WindowAdapter() {
          public void windowClosing(WindowEvent e) {
            System.exit(0);
          }
        });
        Panel p1 = new Panel();
        p1.setLayout(new BorderLayout());
        Button b_rosso = new Button("rosso");
        b_rosso.addActionListener(new SelezionaRosso());
        Button b_verde = new Button("verde");
        ...
        l_colore = new Label("rosso",Label.CENTER);
        colore = Color.red;
        pannelloColorato = new Panel();
        pannelloColorato.setBackground(colore);
        p1.add(b_rosso,BorderLayout.NORTH);
        p1.add(b_verde,BorderLayout.SOUTH);
        p1.add(l_colore,BorderLayout.CENTER);
        add(p1,BorderLayout.EAST);
        add(pannelloColorato,BorderLayout.CENTER);
        Button cambiaColore = new Button("colora");
        add(cambiaColore,BorderLayout.SOUTH);
        setBounds(100,100,300,200);
        ....addActionListener(new ColoraPannello());
      }
      class ColoraPannello implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          pannelloColorato.setBackground(colore);
          pannelloColorato.repaint(1);
        }
      }
      class SelezionaRosso implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          colore = Color.red;
          l_colore.setText("rosso");
        }
      }
      class SelezionaVerde implements ActionListener {
        public void actionPerformed(ActionEvent e) {
          colore = Color.green;
          l_colore.setText("verde");
        }
      }
    }
  6. Modificando solo il codice di FinestraColori e non quello degli ascoltatori, fare in modo che quando si clicca sui pulsanti rosso e verde il pannello venga colorato del colore corrispondente.
  7. Scrivete un solo ascoltatore al posto di SelezionaRosso e SelezionaVerde. Modificate il codice di FinestraColori per far utilizzare solo il nuovo ascoltatore.

Valid HTML 4.01! Valid CSS! Last modified: 2003-05-20