Tutorial GUI con componente swing

Un'applicazione per convertire da °C a °F

Per usare l'applicazione basta inserire un numero nella casella di testo etichettata Temperatura Celsius, premere il pulsante con la didascalia "Converti" e legere la temperatura corrispondente espressa in °F. L'applicazione sarà dotata dei pulsanti di riduzione a icona, ingrandimento e chiusura e porterà il titolo nella barra del titolo.

Il programmatore costruisce prima l'interfaccia grafica, disponendo i vari componenti sul form, poi scrive il codice di gestione dell'evento generato dalla pressione del pulsante.

Creare il progetto.

Avviare NetBeans

Nel menu File scegliere la voce New Project.

Si apre un riquadro di dialogo. Nella colonna Categories selezionare General.

Nella colonna Projects scegliere Java Application.

Premere il pulsante Next.

Assegnare il nome al progetto: ConvertitoreCF e lasciare i valori di default nelle caselle sottstanti.

La casella "Create Main Class" non deve essere spuntata. Nota: Un'applicazione con interfaccia grafica non necessita di una classe "Main" come punto di inizio del programma, perchè quando si lancia l'applicazione si apre l'interfaccia grafica che permette all'utente di scegliere i comandi da menu o dai pulsanti.

Clic sul pulsante "Finish".

Adesso Bisogna aggiungere un form al progetto, allo scopo di collocare i componenti dell'interfaccia.

clic destro sul nome del progetto ConveritoreCF e, dal menu contestuale scegliere New -> JFrame Form (JFrame è la classe della libreria Swing che genera la finestra in cui verrà eseguita l'applicazione).

Si apre un riquadro di dialogo. Assegnare il nome alla classe: ConvertitoreCelsiusGUI e assegnare il nome Celsius nella casella "package".

Cliccare il pulsante Finish.

Sul lato destro compare una tavolozza dei componenti (Palette), dalla quale si sceglie il componente che serve e lo si trascina sul form nell'area di progetto.

Al di sopra dell'area di progetto ci sono due pulsanti: Source e Design. Premendo il pulsante source si accede alla vista del codice che è stato creato automaticamente quando si è aggiunto il componente JFrame. Si vede che esiste un metodo denominato initComponents, che provvede alla creazione delle dichiarazione e all'inizializzazione dei componenti dell'interfaccia grafica. C'è anche il metodo che per chiudere l'applicazione (exit on close.

Sulla destra compare anche il pannello delle proprietà che permette di assegnare gli attributi ai componenti.

Il riquadro Inspector fornisce una visione delle relazioni di dipendenza dei componenti inseriti sull'interfaccia grafica. Permette anche di modificare il nome dei componenti.

Creazione dell'interfaccia grafica dell'applicazione

Quando si trascina un componente dalla Palette all'area di progetto, viene creato automaticamente l'appropriato codice (dichiarazione ed inizializzazione).

Impostare il titolo della finestra dell'applicazione. Nel riquadro Inspector fare clic sul nome JFrame. Nel riquadro delle proprietà modificare il valore della riga title in Convertitore Celsius, premendo il pulsante con i puntini (…), che si trova alla fine della riga.

Aggiungere un componente JTextField. Nel riquadro Palette trascinare un componente JTextField nell'area del progetto e posizionarlo nell'angolo superiore sinistro.

Aggiungere un componente JLabel. Dal riquadro Palette trascinare un componente JLabel sull'area di progetto. Posizionarlo alla destra del campo JTextField, allineandolo con l'aiuto delle linee guida.

Aggiungere un JButton. Dal riquadro Palette trascinare un JButton sull'area del progetto. Posizionarlo a sinistra, immediatamente sotto il campo JTextField.

Aggiungere un componente JLabel. Dal riquadro Palette trascinare un componente JLabel sull'area di progetto. Posizionarlo alla destra del campo JButton, allineandolo con l'aiuto delle linee guida.

Modificare la didascalia dei componenti. Mediante il doppio clic sul componente, modificare la didascalia: alla prima label assegnare il testo Celsius, alla seconda assegnare il testo: Fahrenheit, al pulsante assegnare il testo: Converti.

Assegnare la dimensione ai componenti. Tenendo premuto il tasto Shift, fare clic sulla casella di testo e poi sul pulsante per selezionarli entrambi. con il tasto destro del mause aprire il menu contestuale e scegliere la voce: Same Size -> Same Width. Prestare attenzione che non sia selezionato anche il JFrame stesso, altrimenti la voce di menu non sarà attiva.

La finestra dell'applicazione risuterà grande rispetto ai componenti che contiene. Ridurre le dimensioni del JFrame agendo sulla maniglia dell'angolo inferiore destro, fino a quando i componenti siano completamente contenuti nel frame, scegliendo a piacere lo spazio extra che si vuole inserire intorno ad essi. L'utente dell'applicazione potrà in ogni caso allargare la finestra.

Si suggerisce di osservare il codice che è stato aggiunto automaticamente, durante la costruzione dell'interfaccia grafica, aprendo la scheda Source.

Cambiare i nomi di Default delle Variabili. Nel riquadro Inspector, per ogni componente, compare prima il nome della variabile e, tra parentesi quadre, compare il tipo dell'oggetto. Ad esempio, jTextField1 significa che jTextField1 è il nome della variabile e JTextField è il suo tipo.

Fare clic destro sul nome della variabile e scegliere la voce Change variable name dal menu contestuale. I nuovi nomi delle variabili potrebbero essere: tempTxt per la casella di testo, celsiusLbl per la prima label, convertiBtn per il pulsante e fahrenheitLbl per la seconda label. È consuetudine far seguire ai nomi un'abbreviazione relativa al tipo, allo scopo di aiutare il programmatore ad evitare di usare le variabili in contesti incompatibili. Ogni modifica effettuata nel riquadro Inspector viene applicata automaticamente al codice sorgente.

Registrare un evento.

Quando un utente interagisce con i componenti dell'interfaccia grafica (sceglie una voce di menu, clicca su un pulsante, ecc.), il componente genera un messaggio - chiamato oggetto evento - che verrà consegnato a tutti gli oggetti che si sono registrati come ascoltatori (listener) di quell'evento.

Nell'area del progetto fare clic sul pulsante per selezionarlo. Assicurarsi che non sia selezionato anche il JFrame, altrimenti la voce di menu non è attiva. Clic destro sul pulsante Converti e, dal menu contestuale, scegliere la voce Events -> Action -> ActionPerformed. In questo modo si genera il codice per scrivere il gestore dell'evento pulsante premuto. Il programmatore dovrà completare il corpo del codice del gestore, per svolgere la funzionalità richiesta.

Aggiungere le istruzioni per calcolare la temperatura in °Fahrenheit: Nel gestore dell'evento convertiBtnActionPerformed inserire il seguente codice:

//Parse degrees Celsius as a double and convert to Fahrenheit.

    int tempFahr = (int)((Double.parseDouble(tempTxt.getText())) * 1.8 + 32);

    fahrenheitLbl.setText(tempFahr + " Fahrenheit");

Eseguire l'applicazione.

Per eseguire l'applicazione scegliere Run -> Run Main Project dal menu dell'ambiente di sviluppo. La prima volta che si esegue questa applicazione compare un riquadro di dialogo che chiede di specificare la classe principale dell'applicazione. Accettare la classe proposta: ConvertitoreCelsiusGUI e premere il pulsante Ok. A questo punto dovrebbe aprirsi la finestra dell'applicazione.

Esercizi

Modificare le proprietà dei componenti ed osservare come cambia l'aspetto dell'interfaccia.

Generalizzare il programma usando un componente Combo Box dal quale scegliere le unità di misura tra cui effettuare la conversione e scrivere le opportune operazioni di conversione.
Suggerimento: vedere la soluzione più avanti, nella sezione che descrive la versione AWT.

Dichiarare le due variabili della classe:

double coeff;

double zero;

Trascinare un componente ComboBox sul form e collocarlo prima del pulsante. Assegnare il nome cb.

Modificare la proprietà model sostituendo le voci item1, item2, ecc. con quelle che si desidera che compaiano nell'elenco a discesa, ad esempio:

scegli U.M.

°C -> °F"

m3 -> litri

joule -> Calorie

pollici -> cm

libbre->grammi

Trascinare un componente Label sull'area Design ed assegnargli il nome um1. Cancellare il testo.

Trascinare un componente Label sull'area Design ed assegnargli il nome um2. Cancellare il testo.

Trascinare un componente Label sull'area Design ed assegnargli il nome aUM. Cancellare il testo.

Incolonnare ed allineare le 3 label. Accanto alla prima label disporre un componente TextField. Assegnargli il nome DaUM

Trascinare un componente Button sull'area del Design. Assegnargli il nome daCaF e modificare la didascalia in "Converti".

Aprire la scheda Events del componente ComboBox e creare il gestore dell'evento itemStateChanged

Completare il gestore dell'evento:

  private void cbItemStateChanged(java.awt.event.ItemEvent evt) {

    int i;

    

      i = cb.getSelectedIndex();

      switch(i) {

        case 1:

          coeff = 180.0/100.0;

          zero = 32.0;

          um1.setText("Gradi Centigradi");

          um2.setText("Gradi Fahrenheit");

          break;

        case 2:

          coeff = 1000.0;

          zero = 0.0;

          um1.setText("Metri Cubi");

          um2.setText("Litri");

          break;

        case 3:

          coeff = 0.2389;

          zero = 0.0;

          um1.setText("Joule");

          um2.setText("Calorie");

          break;

        case 4:

          coeff = 2.54;

          zero = 0.0;

          um1.setText("Pollici");

          um2.setText("centimetri");

          break;

        case 5:

          coeff = 453.6;

          zero = 0.0;

          um1.setText("Libbre");

          um2.setText("grammi");

          break;

      }

    

  }

Modificare il gestore dell'evento generato dal pulsante.

  private void daCaFActionPerformed(java.awt.event.ActionEvent evt) {

    String bottone = evt.getActionCommand();

    double umDa, umA;;

      if (bottone.equals("Converti")) {

      try {

        String numeroLetto = daUm.getText();

          umDa = Double.valueOf(numeroLetto).doubleValue();

          umA = zero + umDa*coeff;

          aUm.setText(""+umA);

          }

          catch(Exception exc) {

         daUm.setText("usare . per separare i decimali");

          aUm.setText("");

        }

      }

    }

  }

-- F I N E --


Versione AWT

organizzazione del programma

Questo programma impiega le tre classi:


esempio

classe Gestore Finestra

Ridefinisce il metodo onClosing per consentire di chiudere la finestra con il pulsante X sulla barra del titolo. Non ha campi (proprietà) e non ha il costruttore.

1 import java.io.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 class GestoreFinestra implements WindowListener {
5     public void windowIconified(WindowEvent e) {}
6     public void windowDeiconified(WindowEvent e){}
7     public void windowActivated(WindowEvent e){}
8     public void windowDeactivated(WindowEvent e){}
9     public void windowOpened(WindowEvent e){}
10     public void windowClosed(WindowEvent e){}
11    public void windowClosing(WindowEvent e){
12         System.exit(0);
13    }
14 }

La classe Cnv

Posiziona i componenti su un pannello ed inserisce il pannello in una finestra.

Contiene il gestore dell'evento "Pulsante Premuto".

Consente di scegliere da una casella combinata le unità di misura a cui si vuole applicare la conversione.

In un file di nome Cnv.java inserire anche le direttive seguenti:

1import java.awt.*;
2import java.awt.event.*;

Poi scrivere la dichiarazione per la classe:

3public class Cnv extends Frame implements ActionListener, ItemListener {

La classe Cnv eredita le proprietà e i metodi dalla classe Frame quindi il programma verrà eseguito in una finestra.

La classe ridefinisce i gestori (ActionListener e ItemListener) degli eventi generati dal pulsante e dalla casella combinata.


Proprietà della classe

4    double coeff, zero;
5     int scelta;
6    private Panel p = new Panel();
7    private Choice cb = new Choice();
8    private Label um1 = new Label("");
9    private Label um2 = new Label("");
10    private TextField DaUM = new TextField(5);
11    private Label aUM= new Label("");
12    private Button daCaF = new Button("Converti");

Commenti

Nella linea 4 si dichiarano due variabili ti tipo double, la prima, coeff, rappresenta il coefficiente di conversione da una unità di misura ad un'altra, la seconda, zero, serve a contenere un eventuale traslazione dell'inizio della scala (come ad esempio da °C a °F)

Nella linea 5 si dichiara una variabile intera, scelta, che viene usata per memorizzare la conversione scelta.

Nelle linee da 6 a 12 si dichiarano proprietà private, cioè accessibili solo tramite i metodi della classe, Ognuna delle quali è il riferimento ad un componente, creato dinamicamente, con l'operatore new.

Si tenga presenta che il testo "Converti" che compare sul pulsante creato nella riga 12 è usato dal programma di gestione dell'evento per riconoscere il tasto che è stato premuto.


il Costruttore

13  public Cnv(){
14     addWindowListener(new GestoreFinestra());
15    daCaF.addActionListener(this);
16    cb.addItemListener(this);
17    vociComboBox();
18    p.setLayout(null);
19    p.add(cb);
20    p.add(um1);
21    p.add(DaUM);
22    p.add(um2);
23     p.add(aUM);
24    p.add(daCaF);
25    cb.setBounds(10,10,100,20);
26    um1.setBounds(10,35,100,15);
27    DaUM.setBounds(10,50,100,20);
28    um2.setBounds(150,35,100,15);
29    aUM.setBounds(150,50,100,20);
30    daCaF.setBounds(80,100,80,20);
31    add(p);
32  }

Commenti

Il Costruttore è una funzione che si riconosce perchè ha lo stesso nome della classe.

Il Costruttore ha lo scopo di inizializzare le proprietà della classe.

Linea 14: Si crea (new) un'istanza della classe GestoreFinestra che rappresenta la destinataria dei messaggi generati dagli eventi che si verificano sulla Finestra.

Linea 15: il pulsante (daCaF) invia i messaggi generati dall'evento "onClick" al gestore che si trova in questa (this) stessa classe.

Linea 16: la casella combinata (cb) invia i messaggi generati dall'evento "l'elemento scelto è cambiato" al gestore che si trova in questa (this) stessa classe.

Linea 17: viene richiamato il metodo "vociComboBox()" che ha lo scopo di aggiungere le varie righe che compariranno quando si apre la casella a discesa.

Linea 18: si elimina il layout associato per default al pannello, in modo che i componenti verranno posizionati esplicitamente.

Linea 19: si aggiunge la casella combinata al pannello.

Linee 20÷24: si aggiungono i componenti al pannello.

Linee 25÷30: si posizionano i componenti sul pannello.

Linee 31: si aggiunge il pannello alla finestra.


Metodi della classe: vociComboBox()

32   private void vociComboBox() {
33     cb.add("scegli U.M.");
34    cb.add("°C -> °F");
35    cb.add("m3 -> litri");
36    cb.add("joule -> Calorie");
37    cb.add("pollici -> cm");
38    cb.add("libbre->grammi");
39  }

Commenti

Si richiama il metodo add del componente Combo Box per scrivere le voci che dovranno apparire quando si apre la casella a discesa.


il gestore di evento

40  public void itemStateChanged(ItemEvent e) {
41    int i;
42    if (e.getStateChange()==ItemEvent.SELECTED) {
43      i = cb.getSelectedIndex();
44      switch(i) {
45        case 1:
46          coeff = 180.0/100.0;
47          zero = 32.0;
48          um1.setText("Gradi Centigradi");
49          um2.setText("Gradi Fahrenheit");
50          break;
51        case 2:
52          coeff = 1000.0;
53          zero = 0.0;
54          um1.setText("Metri Cubi");
55          um2.setText("Litri");
56          break;
57        case 3:
58          coeff = 0.2389;
59          zero = 0.0;
60          um1.setText("Joule");
41          um2.setText("Calorie");
62          break;
63        case 4:
64          coeff = 2.54;
65          zero = 0.0;
66          um1.setText("Pollici");
67          um2.setText("centimetri");
68          break;
69        case 5:
70          coeff = 453.6;
71          zero = 0.0;
72          um1.setText("Libbre");
73          um2.setText("grammi");
74          break;
75      }
76    }
77  }

Commenti



Linea :

Linea 15:

Linea 16:

Linea 17:

Linea 18:

Linea 19:

Linee 20÷24:

Linee 25÷30:

Linee 31:

il gestore di evento richiamato dal pulsante

78  public void actionPerformed(ActionEvent e) {
79    String bottone = e.getActionCommand();
80    double umDa, umA;
81      if (bottone.equals("Converti")) {
82      try {
83        String numeroLetto = daUm.getText();
84          umDa = Double.valueOf(numeroLetto).doubleValue();
85          umA = zero + umDa*coeff;
86          aUm.setText(""+umA);
87          }
88          catch(Exception exc) {
89         daUm.setText("usare . per separare i decimali");
90          aUm.setText("");
91        }
92      }
93    }
94  }

Commenti


La classe principale

95  public class ConvertitoreUM {
96    public static void main(String argv[]) {
97    Cnv f = new Cnv();
98    f.setSize(280,180);
99    f.setLocation(10,100);
100    f.setVisible(true);
101    }
102  }

Commenti