Paola Magillo, Univestita' di Genova, Corso di Programmazione II per SMID, a.a. 2008-2009.

Lezione 09:

INTERFACCE GRAFICHE IN JAVA - III

Contenitori intermedi in Java

Pannelli senza barre di scorrimento

Classe Java Swing "JPanel".

Costruttori:

Pannelli con barre di scorrimento

Classe Java Swing "JScrollPane".

Consente di visualizzare (una parte alla volta) un contenuto piu' grande dell'area occupata sullo schermo dal pannello.

Costruttori:

Questo tipo di pannello ha il suo proprio layout manager che non puo' essere cambiato; deve essere creato fornendo la componente da mettere dentro.
I due ulteriori parametri specificano i criteri da usare per decidere se mostrare le barre di scorrimento, i valori possibili sono (per es. per la barra verticale, per l'orizzontale e' analogo):
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS (barra sempre),
JScrollPane.VETTICAL_SCROLLBAR_AS_NEEDED (barra solo se il contenuto e' piu' grande del contenitore, default)
e JScrollPane.VERTICAL_SCROLLBAR_NEVER (barra mai).

Bisogna fare in modo che il componente contenuto in un pannello a barre di scorrimento abbia preferred size maggiore di quello del pannello, altrimenti i due sono dimensionati grandi uguali, rendendo inutili le barre di scorrimento.
Per ottenere questo bisogna impostare il preferred size di uno e/o dell'altro.

Esempio: ExJScrollPane.java
Definisce una finestra con un pannello a barre che contiene un'etichetta (JLabel).
L'etichetta ha come scritta una stringa lunga in carattere grande, in modo che il suo preferred size sia grande (vedere il codice anche come esempio di come si imposta la font di carattere per un componente).
Inoltre l'etichetta disegna i suoi bordi, in modo che possiamo vederne l'estensione.
Il pannello a barre contiene l'etichetta e imposta il proprio preferred size a dimensione minore del preferred size dell'etichetta.
Provate a vedere che succede lasciando che il pannello a barre si dimensioni come da default (commentare setPreferredSize); e provate a impostare esplicitamente il preferred size di entrambi gli oggetti (es. l'etichetta 300x300 pixel e il pannello a barre 200x200).

Menu' e voci di menu' in Java

Un Menu' permette di scegliere un'opzione da una lista di voci prefissata.

Un menu' consiste di:

Esempio: Menu' FILE sulla barra di menu' di una applicazione, permette di scegliere operazioni sui file: creazione, apertura, chiusura, stampa, salvataggio.

In condizioni normali ha l'aspetto di un'etichetta (titolo del menu'). Quando l'utente preme il mouse sul rettangolo, appare una tendina con una lista di scelte (le voci del menu') rappresentate da etichette testuali o grafiche.
L'utente si sposta col mouse all'interno della tendina e seleziona la voce desiderata.
La selezione genera un evento.

Tipi di menu'

Un menu' puo' essere:

Voci di menu'

I tipi di voci di menu' ricalcano i tipi di bottoni (bottone semplice, check box o radio).
Gli ultimi due tipi di voci hanno due stati possibili (selezionato o non selezionato) graficamente hanno associato un riquadro o altro elemento, visualizzato di lato, che puo' essere selezionato oppure no.

Classi Java Swing per i menu'

Costruzione di menu'

  1. costruire il singolo menu'
  2. collegare il menu' al resto dell'interfaccia mettendolo nella barra di menu' della finestra oppure inserendolo come sotto-menu' di un altro menu' (per realizzare menu' a cascata)

Passo 1) Costruisco un menu' vuoto, costruisco le voci e le aggiungo al menu', esempio:

  menu1 = new JMenu("Primo menu'");
  menu1.add (new JMenuItem("voce semplice"));
  menu1.add (new JCheckBoxMenuItem("voce check box"));
  menu1.add (new JRadioButton("voce radio"));
Crea un menu' con tre voci: una semplice, una a check box, una radio.
Il menu' non e' ancora collegato al resto dell'interfaccia.

Attenzione: anche i radio button menu item devono essere aggiunti allo stesso gruppo per diventare mutuamente esclusivi (come i radio button, ved. lezione 8).

Passo 2a) Inserisco il menu' sulla barra di menu' di una finestra:

  bar = new JMenuBar();    // crea la barra
  frame.setJMenuBar(bar);  // la mette sulla finestra
  bar.add(menu1);          // aggiunge il menu' alla barra
Posso costruire altri menu' e aggiungerli alla barra. Saranno aggiunti in ordine da sinistra verso destra.

Passo 2b) Inserisco invece il menu' come sotto-menu' di un altro, realizzando in tal modo un menu' a cascata. Basta aggiungerlo come se fosse una voce di menu':

  menu2 = new JMenu("super menu'");
  menu2.add (menu1);       // voce costituita da sotto menu'
  menu2.add("una voce");   // voce normale
  menu2.add("altra voce"); // voce normale
Adesso sara' menu2 che dovro' aggiungere alla barra.

Eventi nei menu'

Quelle che reagiscono a eventi sono le singole voci dei menu', con gli stessi action listener previsti per i bottoni dei tipi corrispondenti, ved. lezione 8.

Le voci che sono sottomenu' le gestisce automaticamente il sistema (la loro reazione e' mostrare la tendina del sottomenu').

Esempio

Il programma ExJMenu.java costruisce una finestra con tre menu': due posti sulla barra e uno posto come sotto-menu' del primo di questi. Ogni scelta ha come callback la stampa dell'etichetta della voce di menu' selezionata.

Finestre (contenitori top-level) in Java

Un'interfaccia utente ha una o piu' finestre:

Le finestre sono disegnate direttamente sullo sfondo dello schermo (desktop), mentre di tutti gli altri elementi di inrfaccia sono disegnati all'interno delle finestre.

Java definisce solo l'interno (il contenuto) della finestra.
A questo il sistema (es. Windows) aggiunge il bordo con barra del titolo, dispositivi di controllo per chiusura, redimensionamento, iconificazione. Queste parti aggiunte si chiamano decorazioni.

Java non ha il controllo sul bordo, lo ha il sistema. Java puo' dare suggerimenti (hints) al sistema, che a sua discrezione li considera oppure no.

Per default il layout manager di una finestra e' BorderLayout.

Una finestra viene creata vuota, le dovro' aggiungere componenti (dispositivi con eventuali contenitori intermedi).

Finestra principale (classe JFrame)

Finestra adatta ad essere usata come finestra primaria di un'applicazione.
Verra' mostrata dal sistema con tutte le decorazioni.

Costruttori della classe JFrame:

Un frame puo' avere una barra di menu' (classe "JMenuBar"). Aggiungere la barra di menu' ad un frame f:

  JMenuBar bar = new JMenuBar();
  f.setJMenuBar(bar);
Alla barra di menu' poi aggiungero' menu'...

Finestra di dialogo (classe JDialog e altre)

Finestra secondaria di un'applicazione, serve per mostrare informazioni e/o richiedere informazioni all'utente.
E' intesa come finestra temporanea, percio' il sistema puo' mostrarla con tutte le decorazioni o con un sotto-insieme (es. senza i dispositivi di controllo per redimensionamento).
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 deve contenere dispositivi (es. bottoni) con cui l'utente la possa chiudere 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.

Una finestra di dialogo viene costruita come dipendente da un'altra finestra specificata in argomento al costruttore.

Costruttori della classe JDialog:

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.

Esempio

In ExJDialog.java abbiamo un'applicazione con due finestre:

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

La classe ExJDialog realizza la finestra principale, sotto-classe di JFrame. Il costruttore della classe ExJDialog 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.

Finestre di dialogo gia' pronte

Ci sono tipologie di finestre di dialogo ricorrenti, per esempio molte hanno questa struttura:

Percio' Java Swing offre una serie di finestre di dialogo gia' fatte, con struttura fissa e dettagli personalizzabili (es. quale messaggio, quanti bottoni, quali stringhe sui bottoni).
Queste sono fornite dalla classe JOptionPane, la quale ha metodi chiamati "showXXXDialog", ciascuno dei quali si comporta cosi':

  1. costruisce al volo una finestra di dialogo modale con certe caratteristiche (messaggio, numero di bottoni...), che variano secondo cosa e' XXX
  2. e al volo la mostra, lasciandola su schermo fino a che l'utente non la chiude premendo uno dei bottoni presenti sulla finestra di dialogo stessa (per tutto questo tempo l'esecuzione del programma principale viene bloccata)
  3. se la finestra di dialogo aveva piu' di un bottone, il metodo showXXXDialog ritorna un numero corrispondente al bottone che l'utente ha premuto per chiudere la finestra di dialogo
  4. tale valore di ritorno posso usarlo nel codice che segue la chiamata a showXXXDialog per decidere cosa fare

Elenco dei metodi:

Il layout di base e' il seguente:

+-----+------------------+
|     |   messaggio      |
|icona|------------------+
|     |   campo input    |
+-----+------------------+
|  bottoni per chiudere  |
+------------------------+
Il messaggio puo' essere una stringa o un'icona.
Inoltre, essendo una finestra, avra' una barra del titolo con titolo

Dialogo con solo messaggio

showMessageDialog(finestra da cui dipende, messaggio, stringa titolo, tipo, icona)

Solo i primi due parametri sono obbligatori.
Il tipo e' una delle seguenti costanti di classe JOptionPane: ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE, QUESTION_MESSAGE, PLAIN_MESSAGE, e determina quale e' l'icona di default.
L'ultimo parametro (icona) si puo' omettere e verra' messa l'icona di default.

Esempio:

JOptionPane.showMessageDialog(f, "Attenzione:\nparametro errato",
            "Errore", JOptionPane.ERROR_MESSAGE,
            new ImageIcon("error_icon.gif"));
Mostra finestra di dialogo con titolo "Errore" sulla barra del titolo, il messaggio "Attenzione parametro errato" (su due righe), e icona caricata dal file di nome error_icon.gif.

Dialogo con richiesta di conferma

showConfirmDialog(finestra da cui dipende, messaggio, stringa titolo, tipo dei bottoni, tipo, icona)

Solo i primi due parametri sono obbligatori.
Il tipo dei bottoni e' una delle seguenti costanti di classe JOptionPane: YES_NO_OPTION, YES_NO_CANCEL_OPTION e determina quali bottoni saranno presenti.
Il tipo e' come in ShowMessageDialog (ved. sopra).
Il metodo ritorna un valore intero, che e' una delle seguenti costanti di classe JOptionPane: YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION (quando il dialogo e' stato chiuso premendo il bottone indicato), CLOSED_OPTION (quando il dialogo e' stato chiuso col dispositivo di chiusura presente sul bordo della finestra). Il valore di ritorno e' usato per decidere cosa fare...

Esempio:

int n = JOptionPane.showConfirmDialog(f, "Vuoi continuare?",
            "Errore", JOptionPane.YES_NO_OPTION);
if (n==JOptionPane.YES_OPTION) ... azioni da fare se bottone "yes"...
else ...azioni da fare se bottone no...
Mostra finestra di dialogo con titolo "Errore" sulla barra del titolo, il messaggio "Vuoi continuare?", due bottoni "yes" e "no".
Viene messa l'icona di default per i confirm dialog.

Dialogo con richiesta di input

Forma 1: showInputDialog(finestra da cui dipende, messaggio, titolo, tipo, icona)

Solo i primi due parametri sono obbligatori.
Sotto il messaggio compare un campo di testo editabile in cui l'utente puo' scrivere una stringa.
Il tipo e' come in ShowMessageDialog (ved. sopra).

Il metodo ritorna la stringa presente nel campo quando l'utente chiude la finestra (null se finestra chiusa con cancel).

Forma 2: showInputDialog(finestra da cui dipende, messaggio, titolo, tipo, icona, array di oggetti da scegliere, scelta di default)

Il tipo e' come in ShowMessageDialog (ved. sopra).
l'array di oggetti da scegliere contiene stringhe o icone, che verranno visualizzare in un combo box.
la scelta di default e' l'indice nell'array dell'elemento inizialmente scelto.

Esempio 1:

String s = JOptionPane.showInputDialog(f, "Please input a value");
chiede di mettere una stringa.

Esempio 2:

Object[] possibleValues = { "First", "Second", "Third" };
Object selectedValue = JOptionPane.showInputDialog(f,
       "Choose one", "Input", JOptionPane.INFORMATION_MESSAGE,
       null, possibleValues, possibleValues[0]);
chiede selezione fra le stringhe "First", "Second", "Third", di cui per default e' selezionata la prima.