Sei sulla pagina 1di 15

Gestori di layout

Un gestore di layout una classe che stabilisce in quale modo i componenti devono essere disposti, quando vengono aggiunti ad un contenitore. Le istanze delle classi JFrame e JPanel sono create rispettivamente con i seguenti gestori di layout predefiniti: BorderLayout; FlowLayout. BorderLayout e FlowLayout sono sottoclassi dirette della superclasse cosmica Object e appartengono al package java.awt.

Obj ect

BorderLayout

FlowLayout

Layout dei frame: BorderLayout


Ogni istanza della classe JFrame suddivisa in cinque aree, denominate NORTH, SOUTH, EAST, WEST, CENTER.

Barra del titolo


NORTH

WEST

CENTER

EAST

SOUTH

Quando si aggiunge un componente (tipicamente un pannello) al pannello del contenuto del frame, possibile indicare in quale delle cinque aree caricarlo. A tal scopo si usa il seguente metodo della classe Container:

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

public Component add(Component comp, Object vincoli) Aggiunge il componente comp al contenitore secondo i vincoli rappresentati dal parametro vincoli. Il parametro vincoli pu coincidere con una delle seguenti costanti simboliche della classe BorderLayout1:
-

public public public public public

static static static static static

final final final final final

String String String String String

NORTH SOUTH EAST WEST CENTER

All'interno di ogni area possible aggiungere un solo componente.

Esempio
L'istruzione contentPane.add(panel, BorderLayout.NORTH); aggiunge il pannello panel nell'area NORTH del contenitore contentPane. Se non si specifica dove caricare il componente, l'area predefinita CENTER.

Costruttori della classe BorderLayout


public BorderLayout() Crea un gestore di layout senza spazi tra i componenti.

public BorderLayout(int hgap, int vgap) Crea un gestore di layout con gli spazi specificati tra i componenti. Lo spazio orizzontale denotato con hgap; quello verticale con vgap.

Nota: Quando si crea una istanza della classe JFrame, non necessario creare esplicitamente un'istanza di BorderLayout poich ci avviene automaticamente.

Esempio: frame con cinque pannelli colorati


Il codice seguente crea un frame contenente 5 pannelli di diversi colori, disposti nelle 5 aree determinate dal layout manager di default. Il frame generato mostrato in figura 1. import import import import import java.awt.BorderLayout; java.awt.Color; java.awt.Container; javax.swing.JFrame; javax.swing.JPanel;

public class CreaFrame {


1

In realt esistono altre costanti che sono consultabili alla pagina http://docs.oracle.com/javase/7/docs/api/java/awt/BorderLayout.html, ma quelle indicate sono sufficienti per i nostri scopi. Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

public static void main(String[] args) { final int LARGHEZZA= 300; final int ALTEZZA = 150; final int ASCISSA = 100; final int ORDINATA = 100; final String TITOLO = "Frame con 5 pannelli colorati"; //crea il frame JFrame aframe = new JFrame(TITOLO); aframe.setSize(LARGHEZZA, ALTEZZA); aframe.setLocation(ASCISSA, ORDINATA); aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //crea JPanel JPanel JPanel JPanel JPanel i pannelli nPanel = new wPanel = new ePanel = new sPanel = new cPanel = new JPanel(); JPanel(); JPanel(); JPanel(); JPanel();

//colora i pannelli nPanel.setBackground(Color.YELLOW); wPanel.setBackground(Color.WHITE); ePanel.setBackground(Color.GREEN); sPanel.setBackground(Color.BLUE); cPanel.setBackground(Color.RED); //aggiunge i pannelli al contentPane Container contentPane = aframe.getContentPane(); contentPane.add(nPanel, BorderLayout.NORTH); contentPane.add(wPanel, BorderLayout.WEST); contentPane.add(ePanel, BorderLayout.EAST); contentPane.add(sPanel, BorderLayout.SOUTH); contentPane.add(cPanel, BorderLayout.CENTER); //visualizza il frame aframe.setVisible(true); } }

Figura 1 - Frame con 5 pannelli disposti nelle 5 aree disponibili

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

Layout dei pannelli: FlowLayout


Il gestore di layout FlowLayout consente di inserire i componenti in un contenitore da sinistra verso destra, come avviene per le linee di un testo. Quando una linea piena, va a capo. I componenti che si trovano su una linea vengono centrati, per default.

Costruttori della classe FlowLayout


public FlowLayout() Crea un'istanza di FlowLayout con un allineamento centrale per i componenti e uno spazio orizzontale/verticale tra i componenti di 5 unit.

public FlowLayout(int align) Crea un'istanza di FlowLayout con l'allineamento specificato da align per i componenti e uno spazio orizzontale/verticale tra i componenti di 5 unit.

public FlowLayout(int align, int hgap, int vgap) Crea un'istanza di FlowLayout con l'allineamento specificato da align per i componenti e uno spazio orizzontale/verticale indicato rispettivamente da hgap e vgap.

Le costanti utilizzate per indicare l'allineamento, sono cos definite 2:


public static final int LEFT public static final int CENTER public static final int RIGHT

Esempio: pannello con 2 pulsanti


Il codice seguente mostra come vengono disposti due pulsanti allinterno di una istanza di JPanel, che ha un flow layout come layout manager di default. La ui generata visibile in figura 2. import import import import java.awt.Container; javax.swing.JButton; javax.swing.JFrame; javax.swing.JPanel;

public class CreaFrame { public static void main(String[] args) { final int LARGHEZZA= 300; final int ALTEZZA = 150; final int ASCISSA = 100; final int ORDINATA = 100; final String TITOLO = "Frame con pannello e 2 pulsanti"; //crea il frame JFrame aframe = new JFrame(TITOLO); aframe.setSize(LARGHEZZA, ALTEZZA);
2

In realt esistono altre costanti che sono consultabili alla pagina http://docs.oracle.com/javase/7/docs/api/java/awt/FlowLayout.html, ma quelle indicate sono sufficienti per i nostri scopi. Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

aframe.setLocation(ASCISSA, ORDINATA); aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //crea il pannello JPanel panel = new JPanel(); //crea i due pulsanti JButton button1 = new JButton("button1"); JButton button2 = new JButton("button2"); //aggiunge i pulsanti al pannello panel.add(button1); panel.add(button2); //aggiunge il pan nello al contentPane Container contentPane = aframe.getContentPane(); contentPane.add(panel); //visualizza il frame aframe.setVisible(true); } }

Figura 2 - Frame con 2 pulsanti inseriti in un pannello

Cambiare il gestore di layout predefinito


E' possibile modificare il gestore di layout predefinito mediante il metodo setLayout della classe Container: public void setLayout(LayoutManager mgr) Imposta il gestore di layout a mgr.

Esempio
Per cambiare il gestore di layout di una finestra frame da BorderLayout a FlowLayout, sufficiente scrivere: frame.setLayout(new FlowLayout()); Viceversa, per cambiare il gestore di layout di un pannello panel da FlowLayout a BorderLayout, si scriver: panel.setLayout(new BorderLayout());
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

Non utilizzare un gestore di layout


Talvolta pu essere utile o necessario non servirsi di un gestore di layout, per poter collocare un componente in una posizione "assoluta". In casi come questo occorre: 1. annullare ogni gestore di layout, passando come parametro al metodo setLayout il valore null; 2. specificare la posizione e la dimensione del componente, utilizzando il metodo setBounds.

Esempio
Consideriamo il frame di figura 2 e posizioniamo i pulsanti in modo assoluto. import import import import java.awt.Container; javax.swing.JButton; javax.swing.JFrame; javax.swing.JPanel;

public class CreaFrame { public static void main(String[] args) { final int LARGHEZZA= 300; final int ALTEZZA = 150; final int ASCISSA = 100; final int ORDINATA = 100; final String TITOLO = "Frame con posizionamento assoluto"; //crea il frame JFrame aframe = new JFrame(TITOLO); aframe.setSize(LARGHEZZA, ALTEZZA); aframe.setLocation(ASCISSA, ORDINATA); aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //crea il pannello JPanel panel = new JPanel(); //crea i due pulsanti JButton button1 = new JButton("button1"); JButton button2 = new JButton("button2"); //aggiunge i pulsanti al pannello in posizione assoluta panel.setLayout(null); panel.add(button1); panel.add(button2); button1.setBounds(0,0,100,50); button2.setBounds(100,50,100,50); //aggiunge il pan nello al contentPane Container contentPane = aframe.getContentPane(); contentPane.add(panel); //visualizza il frame aframe.setVisible(true);
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

} } Il frame generato visibile in figura 3.

Figura 3 - Frame con posizionamento assoluto di componenti

Occorre considerare che il posizionamento assoluto pu non essere la scelta migliore poich i componenti, in tal caso, rimangono in posizione fissa anche quando il frame viene ridimensionato dallutente.

BoxLayout
Il BoxLayout inserisce i componenti orizzontalmente o verticalmente in ununica riga o colonna. La classe dotata di un solo costruttore:

public BoxLayout(Container target, int axis) target il contenitore a cui si vuole applicare il layout; axis lasse lungo il quale organizzare i componenti e pu assumere come valore

una delle seguenti costanti intere della classe BoxLayout: X_AXIS, dispone i componenti lungo lasse X da sinistra a destra; Y_AXIS, dispone i componenti lungo lasse Y dallalto verso il basso; LINE_AXIS, dispone i componenti nella direzione di una riga di testo, in base alle propriet di orientamento del componente che li contiene; PAGE_AXIS, dispone i componenti nella direzione del flusso delle linee di una pagina, in base alle propriet di orientamento del componente che li contiene.

Chiariamo meglio il significato di LINE_AXIS e PAGE_AXIS. LINE_AXIS significa che se il contenitore ha propriet di orientamento orizzontale/verticale, i componenti sono disposti orizzontalmente/verticalmente. Nel caso di orientamento verticale, i componenti sono sempre disposti dallalto verso il basso. Nel caso di orientamento orizzontale, se il contenitore ha un orientamento da sinistra a destra, i componenti vengono disposti da sinistra a destra, altrimenti vengono disposti da destra a sinistra. PAGE_AXIS significa che se il contenitore ha propriet di orientamento orizzontale, i componenti sono disposti verticalmente, altrimenti sono disposti orizzontalmente. Nel caso di orientamento verticale, i componenti sono sempre disposti dallalto verso il basso. Nel caso di orientamento orizzontale, se il contenitore ha un orientamento da

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

sinistra a destra, i componenti vengono disposti da sinistra a destra, altrimenti vengono disposti da destra a sinistra. In ogni caso, lordine di visualizzazione dei componenti coincide con lordine di inserimento nel contenitore.

Esempio di BoxLayout
Il frame dellesempio contiene un pannello centrale, il cui layout manager stato impostato a BoxLayout e un pannello a sud, con layout manager di default FlowLayout. Il frame creato mostrato in figura 4.

Figura 4 - Frame con due pannelli di cui uno avente layout manager BoxLayout

import import import import import import import

java.awt.BorderLayout; java.awt.Component; java.awt.Container; javax.swing.BoxLayout; javax.swing.JButton; javax.swing.JFrame; javax.swing.JPanel;

public class CreaFrame { public static void main(String[] args) { final String TITOLO = "Esempio di BoxLayout"; //crea il frame JFrame aframe = new JFrame(TITOLO); aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //crea un pannello centrale con gestore di layout BoxLayout JPanel centerPanel = new JPanel(); BoxLayout centerPanelLayout = new BoxLayout(centerPanel, BoxLayout.Y_AXIS); centerPanel.setLayout(centerPanelLayout); //crea un pannello centrale con gestore di layout predefinito FlowLayout
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

(1)

JPanel southPanel = new JPanel(); //crea e aggiunge tre pulsanti al pannello centrale con allineamento centrato JButton button = new JButton("button"); button.setAlignmentX(Component.CENTER_ALIGNMENT); JButton shortButton = new JButton("short"); shortButton.setAlignmentX(Component.CENTER_ALIGNMENT); JButton longButton = new JButton("long-long - long button"); longButton.setAlignmentX(Component.CENTER_ALIGNMENT); centerPanel.add(button); centerPanel.add(shortButton); centerPanel.add(longButton); //crea e aggiunge due pulsanti al pannello sud JButton okButton = new JButton("OK"); JButton cancelButton = new JButton("Cancel"); southPanel.add(okButton); southPanel.add(cancelButton); //aggiunge i pannelli al contentPane Container contentPane = aframe.getContentPane(); contentPane.add(centerPanel, BorderLayout.CENTER); contentPane.add(southPanel, BorderLayout.SOUTH); //visualizza il frame aframe.pack(); aframe.setVisible(true);

(2)

} }

(1) - Si osservi che non per impostare il layout manager di un pannello a BoxLayout occorre prima creare una istanza di BoxLayout: BoxLayout centerPanelLayout = new BoxLayout(centerPanel, BoxLayout.Y_AXIS) e solo successivamente impostare il layout manager del pannello con il metodo setLayout: centerPanel.setLayout(centerPanelLayout). Non possibile, invece, usare la forma abbreviata: JPanel centerPanel = new JPanel(new BoxLayout(centerPanel, BoxLayout.Y_AXIS)); perch il parametro centerPanel di BoxLayout coincid con listanza del pannello che si sta creando. e questo genera un errore in fase di compilazione. (2) - Il codice presente in questa sezione crea i pulsanti da inserire nel pannello con BoxLayout e ne imposta un allineamento centrato.

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

La classe Box
La classe Box consente di creare pannelli che hanno come layout manager di default il BoxLayout, invece del FlowLayout. La classe Box ha un solo costruttore:

public Box (int axis) Crea un Box che visualizza i suoi componenti lungo lasse specificato. Il parametro axis pu essere una delle costanti intere di BoxLayout: X-AXIS, Y_AXIS, LINE_AXIS, PAGE_AXIS. Metodi utili della classe Box
Per migliorare lallineamento dei componenti, la classe Box consente di creare alcuni tipi di componenti invisibili che fungono da riempitivo (filler) per le zone che si vogliono mantenere vuote. I componenti invisibili sono di tre tipi: rigid area, struts e glue. Esamineremo solo rigid area e glue, poich luso di struts sconsigliato.

public static Component createRigidArea (Dimension d) Crea un componente invisibile che mantiene sempre la stessa dimensione d. Tale componente da utilizzare quando si vuole mantenere uno spazio di dimensione fissa tra altri due componenti. Per esempio, se si vuole inserire uno spazio vuoto di 5 pixel tra due componenti di un box con orientamento orizzontale da sinistra a destra, occorre scrivere:
container.add(firstComponent); container.add(Box.createRigidArea(new Dimension(5,0))); container.add(secondComponent); Un oggetto Dimension3 incapsula la larghezza e laltezza di un componente. Larghezza e altezza sono numeri interi. La figura 5 mostra qual leffetto dellutilizzo di una rigid area.

Figura 5 - Utilizzo di una rigid area per separare due componenti Immagine tratta da http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html

public static Component createGlue () Crea un componente invisibile che si pu espandere, nel modo ritenuto pi opportuno, per occupare lo spazio vuoto interno a un contenitore.
3

Si veda http://docs.oracle.com/javase/7/docs/api/java/awt/Dimension.html

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

10

public static Component createHorizontalGlue () Dispone lo spazio vuoto orizzontale, che in condizioni normali si troverebbe alla destra dei componenti, tra i due componenti stessi.
La figura 6 mostra leffetto dellutilizzo di tale componente.

Figura 6 - Utilizzo di un componente glue per separare due componenti Immagine tratta da http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html

Il codice necessario per creare uno spazio vuoto come quello di figura 6 : container.add(firstComponent); container.add(Box.createHorizontalGlue()); container.add(secondComponent);

Dispone lo spazio vuoto verticale, che in condizioni normali si troverebbe sotto i componenti, tra i due componenti stessi.

public static Component createVerticalGlue ()

La classe Box.Filler
Nel caso in cui nessuna delle soluzioni proposte sia utilizzabile, possibile creare uno spazio vuoto personalizzato con la classe Box.Filler, utilizzando il seguente costruttore:

public Box.Filler (Dimension min, Dimension pref, Dimension max) Crea un componente invisibile con le dimensioni minime (min), preferite (pref) e massime (max) specificate.
Il codice seguente crea uno spazio vuoto tra due componenti di larghezza minima e preferita pari a 5 pixel e di larghezza massima pari al massimo valore Short (2 15-1). Laltezza invece impostata a 100. container.add(firstComponent); Dimension minSize = new Dimension(5, 100); Dimension prefSize = new Dimension(5, 100); Dimension maxSize = new Dimension(Short.MAX_VALUE, 100); container.add(new Box.Filler(minSize, prefSize, maxSize)); container.add(secondComponent); La figura 7 mostra leffetto prodotto dal codice.

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

11

Figura 7 - Utilizzo di un componente Box.Filler per separare due componenti Immagine tratta da http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html

Esempio di Box e Box.filler


Il frame dellesempio contiene tre pannelli: un pannello a nord con due pulsanti separati da una rigid area, un pannello centrale con due pulsanti separati da un glue orizzontale e un pannello a sud con due pulsanti separati da un box filler. Il frame creato mostrato in figura 8. import import import import import import import java.awt.BorderLayout; java.awt.Container; java.awt.Dimension; javax.swing.Box; javax.swing.JButton; javax.swing.JFrame; javax.swing.JPanel;

public class CreaFrame { public static void main(String[] args) { final String TITOLO = "Esempio di Box e Box.Filler"; //crea il frame JFrame aframe = new JFrame(TITOLO); aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //esempio di rigid area JPanel northPanel = new JPanel(); JButton button1 = new JButton("button 1"); JButton button2 = new JButton("button 2"); northPanel.add(button1); northPanel.add(Box.createRigidArea(new Dimension(50, northPanel.add(button2); //esempio di glue JPanel centerPanel = new JPanel(); JButton button3 = new JButton("button 3");
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

0)));

12

JButton button4 = new JButton("button 4"); centerPanel.add(button3); centerPanel.add(Box.createHorizontalGlue()); centerPanel.add(button4); //esempio di box filler JPanel southPanel = new JPanel(); JButton button5 = new JButton("button 5"); JButton button6 = new JButton("button 6"); southPanel.add(button5); Dimension minSize = new Dimension(20, 100); Dimension prefSize = new Dimension(20, 100); Dimension maxSize = new Dimension(Short.MAX_VALUE, 100); southPanel.add(new Box.Filler(minSize, prefSize, maxSize)); southPanel.add(button6); //aggiunge i pannelli al contentPane Container contentPane = aframe.getContentPane(); contentPane.add(northPanel, BorderLayout.NORTH); contentPane.add(centerPanel, BorderLayout.CENTER); contentPane.add(southPanel, BorderLayout.SOUTH); //visualizza il frame aframe.pack(); aframe.setVisible(true); } }

Figura 8 - Frame con componenti separati da componenti invisibili

La classe GridLayout
Il GridLayout inserisce i componenti in una griglia le cui celle hanno tutte la stessa dimensione. Ogni componente occupa tutto il contenuto della cella in cui si trova. I costruttori sono tre:

Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

13

public GridLayout()

Crea una griglia con una sola colonna e una sola riga.

public GridLayout(int rows, int cols)

Crea una griglia con il numero di righe (rows) e colonne (cols) specificato.

public GridLayout(int rows, int cols, int hgap, int vgap)

Crea una griglia con il numero di righe e colonne specificato e definisce lo spazio orizzontale (hgap) e verticale (vgap) tra le celle.

Le celle della griglia sono indicizzate con una numerazione progressiva che parte da 1 e prosegue da sinistra a destra a partire dallalto. Per esempio, una griglia di 3 righe e 2 colonne avr le celle cos indicizzate:

1 3 5

2 4 6

I componenti vengono inseriti seguendo lordinamento degli indici delle celle.

Esempio di GridLayout
Lesempio crea in layout a griglia con due colonne e due righe, come mostrato in figura 9. import java.awt.Container; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; public class CreaFrame { public static void main(String[] args) { final String TITOLO = "Esempio di GridLayout"; //crea il frame JFrame aframe = new JFrame(TITOLO);
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

14

aframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //imposta il layout del contentPane a GridLayout Container contentPane = aframe.getContentPane(); contentPane.setLayout(new GridLayout(2,2)); //crea i pulsanti e li inserisce nella griglia 2x2 contentPane.add(new JButton("1")); contentPane.add(new JButton("2")); contentPane.add(new JButton("3")); contentPane.add(new JButton("4")); //visualizza il frame aframe.pack(); aframe.setVisible(true); } }

Figura 9 - Frame con GridLayout

Altri layout manager


Altri gestori di layout pi complessi sono: GridBagLayout, CardLayout, GroupLayout, SpringLayout. Maggiori dettagli si possono trovare allurl http://download.oracle.com/javase/tutorial/uiswing/layout/visual.html#card. Inoltre, sempre possibile creare un layout personalizzato, anche se il compito non banale. Un esempio di layout personalizzato dal nome FormLayout visibile allurl http://www.scribd.com/doc/29332215/Esercizio7-Gui-Prenotazioni-Soluzione

_______________________________________________________________
Quest'opera stata rilasciata con licenza Creative Commons Attribution-ShareAlike 3.0 Unported. Per leggere una copia della licenza visita il sito web http://creativecommons.org/licenses/by-sa/3.0/ o spedisci una lettera a Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
Bocchi Cinzia Ultimo aggiornamento: 01/02/2013

15