[Per corso su Java vedere http://java.sun.com/docs/books/tutorial/]
Una interfaccia e' fatta da tre tipi di componenti:
Tutti questi elementi (finestre top-level, contenitori, dispositivi) in Java sono detti componenti e sono classi che ereditano dalla classe base Component (oppure MenuComponent) in AWT, e da JComponent in Swing.
Le finestre top-level sono anch'esse contenitori, detti contenitori top-level. Un contenitore puo' contenere dispositivi o altri contenitori. Un contenitore intermedio e' contenuto in un altro contenitore, che puo' essere top-level o intermedio.
Ogni contenitore ha un layout manager che stabilisce in che modo gli oggetti devono essere dislocati al suo interno.
Descritta da foresta di alberi dove la relazione padre-figlio
rispecchia la relazione di contenimento.
Tanti alberi quante le finestre top-level dell'interfaccia
(es: 2 alberi se ho una finestra principale e un dialogo).
Nota bene: La "gerarchia" di contenimento non ha niente a che vedere con la "gerarchia" delle classi nel paradigma object-oriented.
Nel seguito le classi il cui nome inizia con "J" sono Swing, le altre AWT. Swing ha piu' classi di componenti rispetto ad AWT.
Realizzati come finestre top-level nell'ambiente in cui sara' eseguito il programma Java.
Contenitori di uso generale:
Contenitori per usi speciali:
Vari tipi di bottoni:
Vari tipi di menu':
Altri dispositivi di controllo:
Dispositivi per mostrare informazioni, non sensibili a input:
Dispositivi per mostrare / acquisire informazioni formattate (eventualmente editabili):
Finestra top-level di tipo adatto ad essere usata come finestra primaria di
applicazione.
Verra' mostrata con tutte le decorazioni del WM (window manager):
bordo, barra del titolo, controlli (per chiusura, iconificazione ecc.).
Creare un frame (vediamo Frame, e' uguale con JFrame):
Un frame puo' avere una barra di menu' (classe MenuBar o JMenuBar). Aggiungere la barra di menu' ad un frame:
Finestra top-level di tipo adatto ad essere usata come finestra di dialogo
(finestra secondaria di un'applicazione che serve
per mostrare informazioni e richiere input).
E' intesa come finestra temporanea.
Puo' avere tutte o un sottoinsieme delle decorazioni, dipende dal WM.
Dipende funzionalmente da un'altra (tipicamente da un frame).
Quando distruggo un frame, distruggo anche tutti i suoi dialoghi.
Quando iconifico / deiconifico il frame, spariscono / riappaiono
i suoi dialoghi.
Questo comportamento e' gestito automaticamente dal sistema.
Creare un dialogo dipendente da una finestra t (vediamo Dialog, e' uguale con JDialog):
Un frame o dialogo quando viene creato e' vuoto.
Per riempirlo devo aggiungere componenti.
Prima devo aver stabilito il layout manager, che determina come
posizionare le componenti aggiunte.
In AWT aggiungo componenti al frame/dialogo stesso,
che e' un contenitore. Se t e' il frame o dialogo):
t.add(...)
In Swing le aggiungo al suo pannello del contenuto (content pane,
contenitore contenuto nel frame/dialogo che lo copre interamente):
t.getContentPane().add(...);
Per quanto riguarda i dialoghi, esistono anche dialoghi pronti all'uso, con contenuto gia' predisposto (li vedremo).
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.
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.
Tutti i contenitori hanno un metodo per stabilire il layout manager:
c.setLayout(layout);
Tutti i contenitori hanno un metodo per aggiungere componenti nel contenitore:
c.add(componente); c.add(componente,posizione);A seconda del tipo di layout manager presente, va usata l'una o l'altra forma del metodo add.
Posso aggiungere e anche togliere componenti da un contenitore a run-time. Simmetrico al metodo add esiste metodo remove.
I componenti sono messi uno dopo l'altro orizzontalmente finche' ci stanno, poi si va a capo e si forma un'altra linea, ecc.
layout = new FlowLayout(); layout = new FlowLayout(allineamento); layout = new FlowLayout(spazX,spazY); layout = new FlowLayout(allineamento,spazX,spazY);L'allineamento puo' essere FlowLayout.LEFT, FlowLayout.RIGHT oppure FlowLayout.CENTER (componenti allineate a sinistra, a destra o centrate).
Si usa la forma di add senza posizione, le componenti sono messe in fila nello stesso ordine in cui sono aggiunte.
Il contenitore e' diviso in 5 zone:
+--------------------------+ | NORTH | +------+------------+------+ | EAST | CENTER | WEST | +------+------------+------+ | SOUTH | +--------------------------+ layout = new BorderLayout(); layout = new BorderLayout(spazX,spazY);
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,
non mettere piu' di un componente per zona!
E' permesso lasciare vuote alcune zone.
Il contenitore e' organizzato a tabella con un certo numero di righe e colonne.
layout = new GridLayout(numrighe,numcolonne); layout = new GridLayout(numrighe,numcolonne,spazX,spazY);
Si usa la forma di add senza posizione, le componenti sono prese nell'ordine e vanno a riempire la griglia riga dopo riga.
+---+---+---+---+ | 1 | 2 | 3 | 4 | +---+---+---+---+ | 5 | 6 | 7 | 8 | +---+---+---+---+
FlowLayout, BorderLayout, GridLayout sono i piu' usati. FlowLayout e' quello di default.
L'esempio ExLayout.java (AWT) e ExJLayout.java (Swing) li mostra in azione. Il programma accetta Flow, Border, o Grid come opzioni da command line. 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.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
GridBagLayout: tabella con righe e colonne dove un componente puo' occupare piu' righe e/o piu' colonne.
CardLayout: permette a due componenti di coesistere su un'area essendo visualizzati in alternativa uno all'altro (ma la stessa cosa si ottiene usando pannello a schedario (JTabbedPane)
BoxLayout: (solo in Swing) i componenti sono messi in fila orizzontalmente o verticalmente, permette controllo accurato di allineamento, spaziatura, dimensioni delle componenti al suo interno
Componenti possono dare al layout manager suggerimenti relativi a dimensioni e allineamento. Ma non e' detto che siano rispettati...
Ogni componente ha tre dimensioni (minima, massima, preferita) di cui il layout manager del contenitore in cui la componente si trova puo' tenere conto.
Ogni componente ha anche due allineamenti (orizzontale, verticale) di cui il layout manager puo' tenere conto.
Queste dimensioni e allineamenti di un componente 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).
Java AWT fornisce metodi solo per leggere queste dimensioni e
allineamenti (nome che inizia per "get"),
mentre non posso assegnarli esplicitamente.
Per assegnarli l'unico modo e' scrivere una sotto-classe che
ridefinisce la funzione "get" corrispondente.
Java Swing fornisce anche metodi per assegnarli
(nome che inizia per "set").
Per tutte le classi di componenti:
La funzione setSize e' garantita produrre la dimensione
specificata solo per le componenti top-level (finestre).
Nelle componenti non top-level puo' essere prevaricata
dal layout manager del contenitore in cui la componente e' posta.
Va chiamata dopo aver aggiunto tutte le componenti e sottocomponenti alla finestra e prima di mapparla.
Mappare / demappare (mostrare / nascondere) finestra top-level su schermo:
Classe Panel / JPanel.
panel = new Panel(); panel = new Panel(layout);Se non specificato, il layout manager e' FlowLayout.
Classe ScrollPane / JScrollPane.
Consente di visualizzare (una parte alla volta) un contenuto piu' grande
dell'area occupata sullo schermo dal pannello.
In AWT:
panel = new ScrollPane(); panel = new ScrollPane(scrolling);
Il criterio usato per decidere se mostrare le barre (parametro scrolling) puo' essere uno tra:
In Swing:
panel = new JScrollPane(); panel = new JScrollPane(comp); panel = new JScrollPane(scrollY,scrollX); panel = new JScrollPane(comp,scrollY,scrollX);comp e' la componente da collocare all'interno del pannello.
Importante impostare le dimensioni del pannello (con setPreferredSize), altrimenti per default il pannello si dimensiona grande quanto la componente contenuta al suo interno.
Pannello bipartito con linea di divisione
orizzontale o verticale.
Contiene due componenti dalle parti opposte del divisorio.
L'utente puo' trascrinare col mouse il divisorio per stabilire
quanto spazio va dato a ciascuna delle due parti.
panel = new JSplitPane(); panel = new JSplitPane(direzione); panel = new JSplitPane(true/false); panel = new JSplitPane(direzione,comp1,comp2); panel = new JSplitPane(direzione,true/false,comp1,comp2);La direzione e' una fra JSplitPane.HORIZONTAL_SPLIT (defalult) e JSplitPane.VERTICAL_SPLIT.
Uno split pane puo' contenere solo due componenti e non ha bisogno di specificare layout manager.
Se non ho specificato le due componenti alla creazione, posso aggiungerle dopo con add nella forma senza specifica della posizione (la prima componente aggiunta e' quella in alto / a sinistra), oppure con setTopComponent(Component) e analogo con Bottom, Left, Right.
Posso cambiare la direzione del divisorio con setOrientation(direzione).
Per default il pannello determina la posizione del divisorio in base alle dimensioni preferite dei due componenti che contiene.
Per spostare il divisorio:
panel.setDividerLocation(percentuale); panel.setDividerLocation(pixel);Le posizioni ammissibili per il divisorio risentono delle dimensioni minime dei due componenti che contiene.
Creare finestra con barra di menu', un'area di testo grande centrale provvista di barre di scorrimento, un'area messaggi in fondo, una fila di bottoni sotto la barra di menu', una lista (che potrebbe essere l'indice dei documenti consultabili nell'area centrale) lateralmente a sinistra, sempre a sinistra, sotto la lista una maschera per la ricerca.
Posso usare: