Una interfaccia e' fatta da:
Vedere "A Visual Guide to Swing Components", http://java.sun.com/docs/books/tutorial/ui/features/components.html
In Java tutti questi sono detti componenti e, tranne le finestre top-level, sono classi che ereditano (direttamente o indirettamente) dalla classe base JComponent (a sua volta sotto-classe della classe AWT Component).
Le finestre topo-level invece ereditano indirettamente dalla classe AWT Window (a sua volta sotto-classe della classe AWT Component).
Citiamo solo i piu' interessanti. Per gli altri e anche per descrizione dettagliata delle classi e dei loro metodi ved. il manuale in linea http://java.sun.com/j2se/1.4.2/docs/api/index.html.
Contenitori Top-level o finestre:
Contenitori intermedi:
Dispositivi attivi o di controllo (grafica e comportamento, cioe' anche input dall'utente, ciascun tipo di dispositivo di controllo e' adatto a ricevere un certo tipo di input):
Dispositivi inerti (solo grafica, cioe' solo output verso l'utente):
Dispositivi specifici per scopi particolari:
Un contenitore puo' contenere dispositivi o altri contenitori. Un contenitore intermedio e' contenuto in un altro contenitore, che puo' essere top-level o intermedio.
Si ha una gerarchia di contenimento separata per ogni finestra dell'interfaccia (es: due se ho una finestra principale e una finestra di dialogo).
La gerarchia di contenimento e' descritta da un albero dove la relazione padre-figlio rispecchia la relazione di contenimento.
Nota bene:
La "gerarchia" di contenimento rappresenta la relazione
di contenimento fra i componenti
(componente figlio occupa un'area di schermo "ritagliata" dentro
quella del componente padre).
Non ha niente a che vedere con la "gerarchia" delle
classi nel paradigma object-oriented (che rappresenta invece
la relazione super-classe / sotto-classe).
Ogni contenitore ha un layout manager che stabilisce in
che modo gli oggetti devono essere dislocati al suo interno.
Fanno eccezione alcuni contenitori piu' sofisticati
(es. JScrollPane, JSplitPane)
che hanno un proprio modo predefinito di disporre il contenuto).
Processo di stabilire automaticamente dimensioni e posizione delle componenti all'interno di un contenitore. Ogni contenitore (sia top-level che intermedio) ha un layout manager.
I layout manager sono oggetti di classi che implementano l'interfaccia Java AWT "LayoutManager".
Potrei lavorare senza layout manager, ma allora dovrei fornire posizione assoluta di ogni componente all'interno del contenitore, ed avrei problemi quando il contenitore top-level viene redimensionato dall'utente.
La super-classe Container ha i seguenti metodi, che percio' sono ereditati da tutte le classi di contenitori:
Questo si applica ai contenitori di tipo generale (es. JPanel e il pannello di contenuto di una finestra).
I contenitori che hanno un proprio modo predefinito di disporre il contenuto (es. JScrollPane, JSplitPane) spesso hanno anche proprie funzioni per aggiungere componenti.
Il programma ExLayout.java accetta Flow, Border, o Grid come opzioni da command line e mostra questi tre layout in azione. Crea 5 etichette con sfondo di colori diversi e le dispone secondo il layout specificato.
Inizialmente impacchetta la finestra nel minimo spazio sufficiente. Quando l'utente cambia le dimensioni alla finestra, il layout manager ne riadatta il contenuto.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
I componenti sono messi uno dopo l'altro orizzontalmente finche' ci stanno, poi si va a capo e si forma un'altra linea, ecc.
Costruttori della classe FlowLayout:
Per aggiungere componenti si usa il metodo "add" nella forma senza posizione. I componenti sono messi in fila nello stesso ordine in cui sono aggiunti.
Il contenitore e' diviso in 5 zone:
+--------------------------+ | NORTH | +------+------------+------+ | EAST | CENTER | WEST | +------+------------+------+ | SOUTH | +--------------------------+
La zona CENTER tende ad occupare tutto lo spazio eccedente quando la finestra viene allargata.
Cosruttori della classe BorderLayout:
Per aggiungere componenti si usa la forma di "add"
con la posizione, che
e' una fra BorderLayout.NORTH, BorderLayout.SOUTH,
BorderLayout.EAST, BorderLayout.WEST, BorderLayout.CENTER.
Il componente viene aggiunto a quella specificata tra le 5 zone.
Va messo un solo componente per zona!
E' permesso lasciare vuote alcune zone, che assumeranno dimensione nulla.
Il contenitore e' organizzato a tabella con un certo numero di righe e colonne.
Cosruttori della classe GridLayout:
Per aggiungere componenti si usa la forma di "add" senza posizione.
I componenti vengono aggiunti nell'ordine a riempire la griglia riga
dopo riga:
+---+---+---+---+ | 1 | 2 | 3 | 4 | +---+---+---+---+ | 5 | 6 | 7 | 8 | +---+---+---+---+Se voglio lasciare vuote delle posizioni, metto come riempitivo una etichetta (classe JLabel) senza testo.
I contenitori top-level (finestre) hanno metodo
Da chiamare dopo aver aggiunto tutte le componenti e sottocomponenti alla finestra e prima di renderla visibile.
Usa i layout manager di tutti i contenitori presenti nella gerarchia di contenimento che ha per radice la finestra.
Le finestre appena costruite sono per default non visibili, le devo rendere visibili da programma con apposita istruzione (setVisible).
Gli altri componenti sono per default visibili all'interno del
contenitore che li contiene, purche' questo sia visibile.
Un componente sara' visibile sullo schermo se e' visibile e lo sono
anche tutti i contenitori risalendo la gerarchia di contenimento
fino alla finestra radice.
Esistono i metodi (comuni a tutti i componenti perche' appartengono alla super-classe Component):
Serve per mostrare informazioni (es. un titolo, un messaggio di istruzioni o di errore...). Occupa un'area rettangolare con bordi non segnati, e puo' contenere una stringa e/o un'immagine.
Esempi:
Ne abbiamo visto uno con etichetta testo
in SwingExample (ved. lezione scorsa).
Vediamo tutte le possibilita' in ExJLabel,
serve anche il file immagine fiore.gif
(nel sorgente ci sono le tre alternative, due commentate e una no,
bisogna editare e cambiare per vedere le altre).
Serve per invocare un'operazione (es. per chiudere una finestra).
Ha l'aspetto di un rettangolo con bordi ben segnati e e puo' contenere una stringa e/o un'immagine (che indica l'operazione corrispondente).
Sensibile al click del mouse (evento di azionamento del bottone). Durante il click il bottone cambia aspetto per dare feedback che e' stato azionato.
Esempi:
Ne abbiamo visto uno con etichetta testo
in SwingExample (ved. lezione scorsa).
Vediamo tutte le possibilita' in ExJButtons,
serve anche il file immagine fiore.gif.
Serve per impostare selezione o non selezione di una scelta.
Ha l'aspetto di una casellina con un'etichetta testuale accanto.
Il quadrato puo' contenere un segno, la cui presenza
o assenza denota lo stato della scelta.
Ha uno stato interno booleano (per dire selezionato
o non selezionato), con i metodi setState e getState.
Sensibile al click del mouse (due eventi:
azionamento e cambiamento di stato).
Al click lo stato del bottone si inverte (da selezionato a non selezionato
o viceversa), dandone feedback grafico.
Esempi: rimandati a dopo i bottoni radio.
Metodi interessanti della classe ItemEvent, parametro della funzione (callback) itemStateChanged di ItemListener:
I bottoni radio sono simili ai check box, ma sono presenti a gruppi e in ogni momento solo un bottone del gruppo puo' essere selezionato (selezionarne uno automaticamente disseleziona quello precedente).
Si dice che le scelte sono mutuamente esclusive.
Per ottenere un gruppo di radio button devo:
Esempio:
rb1 = new JRadioButton("uno",true); // e' inizialmente "on"
rb2 = new JRadioButton("due");
rb3 = new JRadioButton("tre");
ButtonGroup bg = new ButtonGroup();
bg.add(rb1);
bg.add(rb2);
bg.add(rb3);
Quando utente preme un bottone radio in un gruppo, si generano tre eventi:
Java distingue graficamente i JCheckBox (scelte indipendenti) dai JRadioButton (che fanno parte di un gruppo di scelte esclusive) tramite diversa foma della casellina.
Il programma
Ex3Buttons mostra i
tre tipi di bottoni (di comando, check box, radio).
Esercizio: aggiungere la gestione degli eventi (facendo stampare qualcosa su standard output ad ogni bottone).
Permette l'introduzione di input testuale. Esempio: nome utente per login.
Ha l'aspetto di un'area rettangolare in cui l'utente inserisce il testo. Quando l'utente clicca all'interno dell'area, appare un cursore, i caratteri digitati successivamente sulla tastiera sono diretti al campo di input e vengono mostrati (echo) come feedback.
Sensibile a quando l'utente preme return all'interno dell'area di inserimento (evento di azionamento).
Posso leggere e modificare la stringa contenuta: metodi getText e setText
Il campo di testo puo' essere editabile (default) o non editabile (puo' essere utile renderlo non editabile in alcune situazioni): metodi isEditable e setEditable.
Esempio: rimandato a dopo l'area di testo.
Area di testo a piu' linee (eventualmente posso collocarla dentro un pannello con barre di scorrimento).
La gestione degli eventi e' complessa. Posso gestire anche selezione di parti di testo...
Metodi interessanti della classe TextArea:
Il programma ExJText mostra un
campo e un'area di testo. L'area di testo riporta ogni volta
cio' che l'utente digita nel campo di testo.
I metodi elencati qui sono in tutte le classi di componenti perche' ereditati dalla super-classe comune Component (talvolta JComponent).
Un componente puo' essere disabilitato cioe' gli puo' essere impedito di ricevere eventi. Per default e' abilitato.
Di solito si disabilitano i dispositivi di controllo che corrispondono ad opzioni non sensate nello stato corrente dell'applicazione. I dispositivi non attivi sono distinguibili graficamente (es: colore meno intenso).
Le dimensioni di un componente non sono in genere fissate:
Esistono funzioni per assegnare a un componente delle dimensioni
specificate, ma di solito queste non verranno rispettate da Java,
per i motivi sopra elencati.
Infatti Java assegna le dimensioni ai componenti secondo un processo di
calcolo (innescato per es. dalla funzione "pack").
Per assegnare dimensioni e posizione a un componente, Java tiene conto di informazioni fornite dal componente:
Metodi interessanti:
Le dimensioni preferite e gli allineamenti hanno valori di default (es. per un bottone la dimensione preferita e' quella grande a sufficienza per mostrare tutta l'etichetta e non piu' grande del necessario).