Paola Magillo, Univestita' di Genova, Corso di Interfacce Utente per Informatica, a.a. 2007-2008.

INTERFACCE GRAFICHE IN JAVA - IV

[Per corso su Java vedere http://java.sun.com/docs/books/tutorial/]

Altri contenitori

Pannelli a schedario

Permettono a piu' componenti (di solito pannelli) di condividere lo stesso spazio.
Ogni componente viene gestita come una scheda con linguetta sporgente. Selezionando la linguetta l'utente stabilisce quale scheda va mostrata davanti alle altre.

Per aggiungere componenti allo schedario non si usa "add" ma si usa un metodo apposito:

Il titolo e' la stringa da mostrare sulla linguetta. L'icona (se presente) viene anch'essa mostrata sulla linguetta.

La componente selezionata e' quella la cui scheda e' in questo momento davanti alle altre, e quindi quella che l'utente vede e con cui puo' interagire.

Per assegnare / ottenere la componente selezionata:

I metodi per gestire lo schedario (ordinamento, selezione, abilitazione / disabilitazione di schede) identificando le componenti tramite indici interi.

Toolbar

Barra orizzontale o verticale contenente componenti (in genere bottoni con etichette grafiche).

Puo' essere trascinata e posizionata a piacere su uno dei quattro lati della finestra che la ospita o fuori dalla sua finestra e il sistema automaticamente la colloca in finestra indipendente apposita.


Il contenitore deve usare BorderLayout. La toolbar deve stare in una delle quattro zone diverse da CENTER. La zona CENTER puo' ospitare (e di solito ospita) un'altra componente. Le altre tre zone devono essere vuote.

Posso aggiungere qualsiasi tipo di componenti ad una toolbar, di solito sono bottoni.
I componenti sono disposti in fila nell'ordine in cui li ho inseriti. Posso controllarne l'allineamento specificando setAlignmentX/Y per ciascun bottone che aggiungo.

Esempio: toolbar con tre bottoni, uno spazio (separatore) e poi un altro bottone.

toolbar = new JToolBar();
toolbar.add(new JButton("uno"));
toolbar.add(new JButton("due"));
toolbar.add(new JButton("tre"));
toolbar.addSeparator();
toolbar.add(new JButton("ultimo"));

Per stabilire se la toolbar puo' essere spostata trascinandola:

toolbar.setFloatable(true/false);

Finestre interne

Per implementare finestre di documento all'interno della finestra principale di un'applicazione.

Devo avere:

Le finestre all'interno del finto schermo hanno decorazioni che forniscono i controlli tipici delle finestre a top-level (chiusura, iconificazione...), ma sono aggiunte e gestite da Swing invece che dal window manager. Per questo, possono differire dalle decorazioni delle finestre top-level (in particolare da quelle della finestra che le contiene).

Creazione

L'esempio ExIntFrame.java crea una finestra (sottoclasse di JFrame) con una finestra interna:

class ExIntFRame extends JFrame
{
  JDesktopPane desktop = null;
  JInternalFrame f1 = null;

  ExIntFRame()
  {
    desktop = new JDesktopPane();
    setContentPane(desktop);
    f1 = new JInternalFrame("titolo 1",true,true,true,true);
    f1.setSize(new Dimension(200,50));
    f1.setVisible(true);
    desktop.add(f1);
    setSize(new Dimension(500,500));
    setVisible(true);
  }
}
Il costruttore della classe ExIntFRame stabilisce che il pannello di contenuto del frame e' un pannello desktop.
Crea f1 finestra interna al mio frame, con possibilita' di essere redimensionata, chiusa, massimizzata ed iconificata (i quattro true nel costruttore), di dimensione 200x50 pixel ed inizialmente mappata (visibile) sul desktop del mio frame.
Stabilisce che le dimensioni del mio frame sono 500x500 pixel cioe' piu' grandi della finestra interna.

In generale f1 invece di essere un JInternalFrame sara' di una sottoclasse di JInternalFrame che definisce anche un contenuto per la finestra interna.

Differenze e similarita' tra frame ed internal frame

La gerarchia di componenti sotto di un JInternalFrame ricalca quella che ho sotto un JFrame. Anche un JInternalFrame ha pannello di contenuto e devo aggiungere componenti al pannello di contenuto.
Anche JInternalFrame ha metodo pack per stabilirne le dimensioni ottimali in base al contenuto. Bisogna sempre assegnare le dimensioni di un internal frame prima di visualizzarlo.

Internal frame non ricevono eventi di finestra (WindowEvent) come i frame, invece ricevono eventi di classe InternalFrameEvent, che sono analoghi.

Dialoghi pronti all'uso

Una finestra di dialogo (classi Dialog / JDialog) quando viene creata e' vuoto.

In Swing esistono option panels, tipi di pannelli predefiniti che si possono mettere dentro un dialogo. Contengono:

Esempio

  1. JOptionPane option = new JOptionPane ("Hai capito?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
  2. JDialog dialog = option.createDialog(frame,"Una domanda...");
  3. dialog.pack();
  4. dialog.setVisible(true);
  5. int n = ((Integer)option.getValue()).intValue();

L'istruzione 1 crea un option panel cosi':

L'istruzione 2 crea dialogo che dipende funzionalmente da un frame ed ha come pannello di contenuto l'option panel appena creato. La stringa "Una domanda..." apparira' come titolo sul bordo (se il WM lo mettera').

Le istruzioni 3 e 4 dimensionano il dialogo e lo mostrano.

I due bottoni presenti nel pannello hanno automaticamente l'effetto di chiudere la finestra di dialogo, quando premuti. Chiuso il dialogo, il controllo passa all'istruzione successiva (5).

L'istruzione 5 legge il numero del bottone premuto per chiudere il dialogo.

Mostrare dialoghi

Classe JOptionPane ha metodi per mostrare dialoghi modali dipendenti funzionalmente da un frame:

Premere uno dei bottoni presenti sul dialogo ne provoca la chiusura.
Questi metodi ritornano il numero del bottone premuto per chiudere il dialogo.

Esistono anche dialoghi predefiniti che consentono immissione di una stringa.

Esempi

1) Esattamente lo stesso esempio visto prima:
int n = JOptionPane.showConfirmDialog
                (frame,
                 "Hai capito?",
                 "Una domanda...",
                 JOptionPane.YES_NO_OPTION,
                 JOptionPane.QUESTION_MESSAGE);
2)
JOptionPane.showMessageDialog(frame, "messaggio", "titolo",
                              JOptionPane.PLAIN_MESSAGE);

Object[] options = {"questa", "quella", "l'altra"};
int n = JOptionPane.showOptionDialog(frame, "Quale delle tre?", "titolo",
        JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE,
        new ImageIcon("icon.gif"), options, options[2]);

Come e' stato chiuso il dialogo

Esistono costanti per indicare il bottone premuto per chiudere il dialogo: JDialog.OK_OPTION, JDialog.YES_OPTION, JDialog.NO_OPTION, JDialog.CANCEL_OPTION.

Invece la costante JDialog.CLOSE_OPTION indica che il dialogo e' stato chiuso agendo sul bordo della finestra.

Supporto predefinito per operazioni particolari

Scelta di un file

Consente di navigare nel file system e scegliere o scrivere il nome di un file.

In AWT:

  1. creare la finestra di dialogo e stabilire se e' finestra per caricamento o per salvataggio di file
    chiediFile = new FileDialog(finestra, "titolo");
    chiediFile.setMode(FileDialog.LOAD
    oppure FileDialog.SAVE);
    dove finestra e' la finestra da cui il dialogo dipende
  2. mostrare il dialogo
    chiediFile.setVisible(true);
    l'interazione con l'utente e' gestita automaticamente dal sistema, finche' utente non chiude il dialogo premendo bottone OK o CANCEL
  3. ottenere il nome del file e, se il nome esiste, prendere il file
    String fileName = chiediFile.getFile();
    String dirName = chiediFile.getDirectory();
    if ( (fileName != null) && (fileName.length()>0) )
    {
    ...aprire file dirName + fileName...
    }

In Swing:

  1. Creare il file chooser
    fc = new JFileChooser();
  2. Chiamare uno dei seguenti metodi che mostrano un dialogo modale contenente il file chooser
    int scelta = fc.showOpenDialog(finestra);
    int scelta = fc.showSaveDialog(finestra);
    int scelta = fc.showDialog(finestra,"titolo");
    dove finestra e' la componente da cui il dialogo deve dipendere.
  3. Leggere il valore di ritorno, che puo' essere JFileChooser.APPROVE_OPTION o JFileChooser.CANCEL_OPTION e, in caso di approvazione, prendere il file
    if (scelta==JFileChooser.APPROVE_OPTION)
    {
    ...aprire il file fc.getSelectedFile().getPath()...
    }
Altri metodi consentono di assegnare directory corrente, definire filtri, personalizzare.

Scelta di un colore (solo Swing)

JColorChooser consente selezione di un colore o da una tavolozza, o mediante terna RGB (rosso, verde, blu) o mediante terna HSB (tinta, saturazione, luminosita').