Skip navigation.
University » Corsi precedenti (it) » IGEA » 2006-07 » 28/03/07

Pulsantiera


Scrivere un programma Java che crei una finestra con un alcuni bottoni. Il numero di bottoni e le relative etichette devono essere chieste all’utente. Il programma offre all’utente, ripetutamente, la possibilità di cambiare le etichette ai bottoni, finché l’utente non si dichiari soddisfatto. L’interazione tra l’utente e il programma avviene tramite la console.

Svolgimento ragionato

Per prima cosa importiamo le classi che ci occorrono. Siccome usiamo le Swing, importiamo tutte le clasi dei package java.awt e javax.swing, e inoltre la classe java.util.Scanner:

import java.awt.*;
import javax.swing.*;
import java.util.Scanner;

Scegliamo di inserire tutto il codice all’interno del metodo main() della nostra classe, che chiameremo Pulsantiera:

public class Pulsantiera {
 
  public static void main(String[] args) {
 
    //Codice del metodo main
    //...
    //...
 
  }
 
}

Per prima cosa il metodo main() chiede all’utente il numero di bottoni da inserire. A tal fine crea un oggetto di tipo Scanner, che chiameremo lettore, con il compito di leggere parole e numeri dalla console (System.in):

Scanner lettore = new Scanner(System.in);
System.out.print("Numero di bottoni da inserire: ");
int n = lettore.nextInt();

Ora che conosciamo il numero n di bottoni, creiamo una finestra (JFrame) e predisponiamola ad accogliere n componenti. Come gestore del layout della lastra dei contenuti della finestra useremo il GridLayout, disponendo un solo bottone per ogni riga. In altre parole, il nostro GridLayout sarà costituito da n righe e 1 colonna.

JFrame finestra = new JFrame("Pulsantiera");
Container lastraContenuti = finestra.getContentPane();
//Ora creo un nuovo oggetto di tipo GridLayout e lo passo alla lastra dei contenuti,
//senza memorizzarne il riferimento in alcuna variabile:
lastraContenuti.setLayout(new GridLayout(n, 1));

Perfetto, ora possiamo aggiungere n bottoni, inizialmente senza etichetta, alla lastra dei contenuti. Poiché non sappiamo quanto valga n a tempo di compilazione (il programma lo scoprirà soltanto quando sarà eseguito) abbiamo bisogno di un ciclo per aggiungere i bottoni. Usiamo il ciclo for, facendogli compiere n iterazioni:

for(int i=0; i<n; i++) {
  JButton b = new JButton();
  lastraContenuti.add(b);
}

Il codice che abbiamo appena scritto funziona, ma soffre di un problema importante: una volta che abbiamo addizionato un bottone alla lastra dei contenuti perdiamo il riferimento al bottone stesso, in quanto la variabile b è definita soltanto (ed ha senso soltanto) all’interno del ciclo. Dunque in futuro non saremo in grado di modificare le etichette dei bottoni!

Corriamo al riparo facendo ricorso ad un array, che ci consente di memorizzare, in n variabili con un unico nome, i riferimenti agli n bottoni. Per prima cosa creiamo un array di (riferimenti a) oggetti di tipo JButton, contenente n elementi:

JButton[] bottoni = new JButton[n];

Sottolineiamo il fatto che abbiamo creato un array di riferimenti ad oggetti, ma non gli oggetti stessi. Per creare i singoli oggetti (i bottoni) recuperiamo il ciclo che avevamo scritto prima: nel ciclo già creavamo n bottoni. Ora si tratta di inserire nell’array i riferimenti ai bottoni di volta in volta creati. Il ciclo diventa dunque:

for(int i=0; i<n; i++) {
  JButton b = new JButton();
  lastraContenuti.add(b);
  bottoni[i] = b;
}

Ora siamo pronti a visualizzare la finestra. Tramite il metodo pack() facciamo sì che le sue dimensioni siano calcolate automaticamente in base alle dimensioni delle sue componenti:

finestra.pack();
finestra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
finestra.setVisible(true);

Compiliamo ed eseguiamo questa prima parte del programma per verificare che funzioni correttamente.

Bene. Offriamo all’utente la possibilità di cambiare le etichette dei bottoni. Il programma deve domandare ripetutamente se l’utente vuole cambiare le etichette, finché l’utente non si dichiari soddisfatto. Ciò si può ottenere attraverso l’uso di un ciclo while.

System.out.print("Vuoi cambiare qualche etichetta? (S/N): ");
String cambiare = lettore.next();
while(cambiare.equals("S") || cambiare.equals("s")) {
 
  //Codice per chiedere le nuove etichette e cambiarle
  //...
  //...
 
  System.out.print("Vuoi cambiare di nuovo qualche etichetta? (S/N): ");
  cambiare = lettore.next();
 
}

Alcune osservazioni:

  • La domanda deve essere ripetuta in due posti: fuori dal ciclo while, perché deve essere richiesta prima della sua prima eventuale esecuzione; e alla fine dello stesso, perché deve essere posta di nuovo per determinare se bisognerà entrare nuovamente nel ciclo.
  • Per confrontare la stringa cambiare con la stringa "S" (opzione Sì) usiamo il metodo equals della classe String. L’uso dell’operatore == (es. if(cambiare=="S")) sarebbe errato, perché compirebbe soltanto un test di uguaglianza di riferimenti (test che fallirebbe in ogni caso). Invece l’operatore equals verifica l’uguaglianza profonda delle stringhe: verifica cioè se le stringhe hanno lo stesso contenuto.
  • Poiché l’utente potrebbe immettere la esse minuscola o maiuscola, verifichiamo entrambi i casi e li poniamo in OR.

Non resta che inserire dentro il corpo del while il codice per cambiare le etichette dei bottoni. E’ molto semplice: si tratta di effettuare un ciclo for su tutti gli n bottoni. Nell’i-esima iterazione del ciclo chiediamo all’utente l’etichetta dell’i-esimo bottone (dell’array) e la impostiamo attraverso il metodo setText() della classe JButton:

for(int i=0; i<n; i++) {
  System.out.print("Etichetta del bottone numero " + (i+1) + ": ");
  bottoni[i].setText(lettore.next());
  finestra.pack();
}

Osservazioni:

  • Poiché gli array iniziano da 0, mentre gli esseri umani spesso iniziano a contare da 1, abbiamo ritenuto più “gradevole” visualizzare i numeri a partire da 1: per questo nella print() visualizziamo il numero i+1.
  • Per risparmiare spazio non abbiamo salvato il risultato dell’invocazione di scanner.next() in una variabile di tipo String, ma lo abbiamo passato direttamente al metodo setText() di JButton.
  • Dopo la modifica di ogni etichetta abbiamo ridimensionato la finestra per adattarla alle nuove dimensioni dell’etichetta stessa.

Soluzione completa

Vedi il file Pulsantiera.java

Commenti dei visitatori


Accedi per lasciare commenti.