Paola Magillo, Univestita' di Genova, Corso di Programmazione II per SMID, a.a. 2004-2005.

Lezione 12:

INTERFACCE GRAFICHE IN JAVA - III

Finestre di dialogo

Nella lezione 8 abbiamo menzionato l'esistenza delle finestre di dialogo...

Finestra di dialogo = finestra secondaria di un'applicazione, serve per mostrare informazioni e/o richiedere informazioni all'utente. E' intesa come finestra temporanea.
Viene mostrata in seguito a una azione dell'utente su una finestra chiamante. Esempio: se aziono il bottone per la stampa mi appare la finestra di dialogo che chiede quale stampante, quante pagine...
La finestra di dialogo contiene dispositivi (es. bottoni) con cui l'utente la chiude dopo aver ricevuto e/o dato le informazioni stabilite.

Un dialogo dipende funzionalmente dalla finestra chiamante. La finestra chiamante di solito e' la finestra principale (frame) dell'applicazione, ma puo' essere anche un'altra finestra di dialogo, che a sua volta dipende, direttamente o tramite altre finestre di dialogo, dalla finestra principale (dialoghi a cascata).

La dipendenza funzionale comporta che:

Questi comportamenti sono gestiti automaticamente dal sistema.

Classe Dialog

Finestra adatta ad essere usata come finestra di dialogo.
Viene costruita come dipendente da un'altra finestra (specificata in argomento al costruttore, ved. dopo).
Essendo intesa come finestra temporanea, il sistema puo' mostrarla con tutte le decorazioni o con un sotto-insieme (es. senza i dispositivi di controllo per redimensionamento).

Costruttori della classe Dialog:

Un dialogo viene creato vuoto. Poi bisogna riempirlo esattamente come si fa con i frame (aggiungere con "add" tutti i componenti e poi dimensionare con "pack") poiche' entrambi sono finestre.

Metodi interessanti della classe Dialog:

Esempio

La classe DialogExample.java realizza un'applicazione con due finestre:

Il dialogo e' modale, percio' l'utente non puo' interagire con il frame finche' non ha chiuso il dialogo.

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

class DialogExample extends Frame
{
  Button apriDialogo; // su questa finestra
  Dialog mioDialogo;
  Button chiudiDialogo; // su finestra di dialogo

  DialogExample()
  {
    /* costruzione del contenuto di questa finestra */
    apriDialogo = new Button("apri dialogo");
    add(apriDialogo);
    pack();
    /* costruzione della finestra di dialogo */
    mioDialogo = new Dialog(this,"Finestra di dialogo",true);
    mioDialogo.setLayout(new GridLayout(2,1));
    mioDialogo.add(new Label("ciao, sono una finestra di dialogo..."));
    mioDialogo.add(chiudiDialogo = new Button("chiudi dialogo"));
    mioDialogo.pack();
    /* comportamento del bottone sulla finestra principale */
    ActionListener apriListener = new ActionListener()
    {
       public void actionPerformed(ActionEvent e)
       {  mioDialogo.setVisible(true);  }
    };
    apriDialogo.addActionListener(apriListener);
    /* comportamento del bottone sulla finestra di dialogo */
    ActionListener chiudiListener = new ActionListener()
    {
       public void actionPerformed(ActionEvent e)
       {  mioDialogo.setVisible(false);  }
    };
    chiudiDialogo.addActionListener(chiudiListener);
  }

  public static void main(String[] args)
  {
    DialogExample ee = new DialogExample();
    ee.setVisible(true);
  }
}

La classe DialogExample realizza la finestra principale, sotto-classe di Frame. Il costruttore della classe DialogExample costruisce anche il dialogo e lo tiene nella variabile mioDialogo.
La callback del bottone apriDialogo presente sulla finestra principale mostra il dialogo; la callback del bottone chiudiDialogo presente sul dialogo lo nasconde.
La finestra principale invece viene mostrata direttamente dal main.

Applet

Un applet e' come un pannello, ma puo' essere messo, invece che in una finestra, in una pagina web. Serve per realizzare applicazioni Java che possono essere eseguite in remoto attraverso una pagina web.

Classe Applet

La classe Java Applet e' sotto-classe di Panel, a sua volta sotto-classe di Container.
Sta nel package java.applet (che bisogna importare, come si fa con java.awt).

La classe ha i seguenti metodi che regolano il "ciclo di vita" di un applet nella pagina web:

Come inserire un applet in una pagina web

Supponiamo che l'applet chiami "MioApplet.class" e che si trovi nella sotto-directory "example" rispetto alla directory dove sta il file miaPagina.html:

                   |
     +-------------+-------------+
     |                           |
miaPagina.html                example
                                 |
                            MioApplet.class

Allora la pagina miaPagina.html dovra' contenere la chiamata dell'applet con la seguente sintassi:

<APPLET CODE="MioApplet.class" CODEBASE="example/" WIDTH="400" HEIGHT="300">
</APPLET>
Quando la pagina viene caricata, il bytecode dell'applet viene caricato sul client, viene creata un'istanza della classe e su di essa vengono chiamati i metodi init e start.
L'applet (che e' un pannello) viene inserito nella pagina web.

Esempio

Applet che contiene un bottone e un'etichetta, l'etichetta mostra sempre il numero di click subiti dal bottone (analogo dell'esempio di interfaccia grafica visto nella lezione 7).

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

public class AppletExample extends Applet
{
    private static String labelPrefix = "Number of clicks: ";
    private int numClicks = 0;
    Label label = null;
    Button button = null;

    /* METODI DI APPLET */
    public void init()
    {
        /* aspetto */
        label = new Label(labelPrefix + "0    ");
        button = new Button("Click me!");
        setLayout(new GridLayout(2, 1));
        add(button);
        add(label);
        /* comportamento */
        ActionListener buttonListener = new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {   numClicks++;
                label.setText(labelPrefix + numClicks);
            }
        };
        button.addActionListener(buttonListener);
    }
    public void stop()  {  numClicks = 0;  }
    public void start()  {  label.setText(labelPrefix + "0    ");  }
}

Per provare un applet in fase di sviluppo, senza scomodare un browser, si puo' usare "appletviewer" (comando come "java"). Per esempio, supponendo che l'applet sia inserito nella pagina miaPagina.html:

  appletviewer miaPagina.html

Che cosa un applet puo' e non puo' fare

Un applet e' un pannello, dunque puo':

Inoltre puo':

Ma e' soggetto a restrizioni per esigenze di sicurezza in rete:

Pero' se l'applet viene eseguito sul server stesso (il server e' anche client) le restrizioni non si applicano.

Passare parametri a un applet

In una applicazione ordinaria (non applet) posso passare agromenti stringhe da command-line alla funzione main (ved. lezione 2).

Analogamente in un applet posso passare agromenti stringhe dalla pagina web che lo ospita alla funzione init dell'applet. Questi sono detti parametri dell'applet. Esempio di sintassi (con un argomento intero e una stringa) per specificare parametri:

<APPLET CODE=MioApplet.class WIDTH=300 HEIGHT=200>
<PARAM NAME="unNumero" VALUE=10>
<PARAM NAME="unaStringa" VALUE="pippo">
</APPLET>

Per leggere i valori dei parametri da dentro l'applet, si usa la funzione della classe Applet:

Una volta avuta la stringa poi, se rappresenta un numero, bisogna convertirla a numero, cosi' come si fa con i parametri da command-line della funzione main (ved. lezione 2).

Esempio:

 int ilNumero;
 String laStringa;
 String aux;
 aux = getParameter("unNumero");
 ilNumero = Integer.parseInt(aux);
 laStringa = getParameter("unaStringa");

Applet e applicazione

Come far si' che un applet possa funzionare anche come applicazione ordinaria?
Un applet e' anche un pannello, quindi posso metterlo in un frame. Nella classe che realizza il mio applet (sotto-classe di Applet) scrivo anche metodo main che:

  1. crea il mio applet e chiama init su di esso (init per gli applet sostituisce il costruttore)
  2. crea un frame
  3. aggiunge l'applet al frame e impacchetta
  4. mostra il frame (con dentro l'applet)

Per far funzionare l'esempio di prima anche come applicazione, basta aggiungere come metodo della classe AppletExample:

    /* METODI PER FARLO FUNZIONARE COME APPLICAZIONE */
    public static void main(String[] args)
    {
      Frame f = new Frame();
      AppletExample app = new AppletExample();
      app.init();
      f.add(app);
      f.pack();
      WindowListener frameListener = new WindowAdapter()
      {
         public void windowClosing(WindowEvent e)
         {   System.exit(0);  }
      };
      f.addWindowListener(frameListener);
      f.setVisible(true);
    }  
Qui abbiamo anche associato alla chiusura della finestra un window listener per terminare l'applicazione, in modo da ottenere lo stesso effetto che nell'esempio della lezione 7.