Java lezione 11
-
Upload
sergio-ronchi -
Category
Software
-
view
46 -
download
0
Transcript of Java lezione 11
Applicazioni GUI
Package java.awt
La prima finestraPer creare una finestra è necessario istanziare un oggetto che sia una sottoclasse di Frame. Si noti inoltre l’uso di show() per visualizzare la finestra e di alcuni metodi per settare le sue caratteristiche.import java.awt.*;import java.awt.event.*;public class MiaFinestra extends Frame{
public MiaFinestra(String title, int left, int top, int width, int height) {
setBounds(left,top,width,height);setTitle(title);
}
public static void main(String args[]){
MiaFinestra f=new MiaFinestra(“Hello Win”,100,200,300,200);
f.show();}
}Si noti che la finestra non si chiude.
Gestione evento di chiusura
Per chiudere una Frame è necessario gestire l’evento windowClosing() che è un metodo dell’interfaccia WindowListener. Purtroppo l’interfaccia WindowListener contiene altri metodi atti a gestire tutto ciò che accade a un Frame. Sappiamo che implementando un’interfaccia sarei obbligato a ridefinire tutti i metodi. Per evitare questo esiste una classe WindowAdapter che implementa per noi la WindowListener, ma noi questa classe non la possiamo estendere perché dobbiamo già estendere Frame.Per risolvere il problema esiste la tecnica delle classe innestate
(inner classes) che permette di definire una classe internamente ad un’altra.
public MiaFinestra(String title, int left, int top, int width, int height) { ……
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){ dispose(); System.exit(0);}
});
}
Uso di componentiUn’applicazione GUI oltre ad avere una Frame di supporto avrà dei
componenti (pulsanti (Button), menu (Menu,MenuBar, MenuItem), caselle di testo (TextField,TextArea), caselle combianate (Choice), opzioni a scelta multipla (CheckBox), opzioni a scelta singola (CheckBox), Liste (List)..) da posizionare sulla Frame.La costruzione dell’interfaccia viene nel costruttore:public class MiaFinestra extends Frame{ private Button pulsante=new Button(“Premi qui”);
public MiaFinestra(String title, int left, int top, int width, int height) {
…….this.add(pulsante); //Aggiungiamo il pusante sulla
Frame }
….. }Si noti che non è stata garantita la posizione del pulsante. In
questo caso il pulsante ha occupato tutto lo spazio disponibile.
Posizionamento e LayoutIl posizionamento dei componenti dipende dal Layout che il nostro
contenitore possiede: in java esistono diversi tipi di Layout, ma analazziamo prima cosa succede se utilizziamo un contenitore privo di Layout.
public class MiaFinestra extends Frame{ private Button pulsante=new Button(“Premi qui”);
public MiaFinestra(String title, int left, int top, int width, int height) {
…….setLayout(null); //Layout nullothis.add(pulsante); //Aggiungiamo il pusante sulla Framepulsante.setBounds(100,100,100,50); //posizionato per
coordinate }
….. }Il Layout nullo a volte viene usato, ma ha il difetto che non permette
il posizionamento automatico in caso di ridimensionamento della finestra.
BorderLayoutNORTH
SOUTH
WES
T EASTCENTER
Impostando il Lauout in questo modo:setLayout(new BorderLayout());Potrò inserire i componenti in uno qualsiasi dei settoricon questa istruzione:this.add(pulsante,BorderLayout.SOUTH);Il componente occuperà tutto lo spazio disponibile.Ogni settore invece di contenere un componente potrebbe contenere un
Pannello (Panel) che a sua volta potrà fungere da contenitore per componenti con un certo Layout.public MiaFinestra(String title, int left, int top, int width, int height) { …….
Panel pnlSud=new Panel()this.setLayout(new BorderLayout());this.add(pnlSud,BorderLayout.SOUTH);pnlSud.setLayout(new BorderLayout());pnlSud.add(pulsante,BorderLayout.EAST);
}
GridLayoutImpostando il Lauout in questo modo:setLayout(new GridLayout(3,4));Potrò inserire i componenti in uno qualsiasi dei settoricon questa istruzione:this.add(pulsante1);This.add(pulsante2);...Il componente occuperà tutto lo spazio disponibile.L’ordine di riempimento della griglia va da sinistra a destra e dall’alto in basso.
I costruttori sia di GridLayout, sia di BorderLayout prevedono altre versioni attraverso le quali è anche possibile stabilire il gap, orizzontale e verticale, tra i vari settori
GridLayout(int rows, int cols, int hgap, int vgap)
Altri LayoutEsistono poi altri Layout tra cui segnaliamo:
FlowLayout: i componenti vengono aggiunti a flusso, cioè uno dopo l’altro da sinistra a
destra, e se non c’è spazio si va a capo. La disposizione varia dimensionando
la finestra.
CardLayout: i componenti vengono posti uno sopra l’altro come in un mazzo di carte.
GridBagLayout: Una griglia evoluta con unione celle e celle con dimensioni diverse.
L’utente potrebbe anche impostare dei Layout personalizzati. Infatti tutti i Layout visti sono normali classi, quindi nulla ci vieterebbe di scriverne di simili implementando le interfacce LayoutManager e LayoutManager2
Gestione eventiTutti i componenti rispondono ad eventi. Alcuni sono comuni a tutti, altri sono specifici. Quelli comuni sono insiti nel fatto che tutti i componenti estendono Component. Component prevede alcuni metodi per aggiungere il componente a un Listener (addXXXListener(…)) e in particolare i seguenti:• addFocusListener() -> quando il componente riceve il fuoco• addKeyListener() -> alla pressione di un tasto sulla keyboard• addMouseListener() -> click dei pulsanti del mouse• addMouseMotionListener() -> movimento del mouse
Questi citati, più altri, cono comuni a tutti i componenti. Quelli specifici sono ad esempio:
Button addActionListener() -> click sul pulsanteTextField addActionListener() -> pressione di Invio
addTextListener -> modifica del testo contenutoTextArea addTextListener -> modifica testo contenutoChekBox,List,Choice addItemListener -> click su un elemento della listaMenu, MenuItem addActionLister -> click su una voce di menu
Interfacce ListenerAd ogni metodo addXXXListener corrisponde una interfaccia XXXListener, ad esempio il metodo addActionListener è definito così:
public void addActionListener(ActionListener a)
Le interfacce XXXListener appartengono tutte al package java.awt.event e contengono metodi per gestire i vari eventi, ad esempio
public interface ActionListener extends EventListener{ public void actionPerformed(ActionEvent e);}
Tale interfaccia deve essere implementata per poter ridefinire a piacimento il metodo di gestione dell’evento. In alcuni casi per non essere obbligati a ridefinire tutti i metodi si ricorre all’uso di inner classes basate sulle classi XXXAdapter.WindowListener -> WindowAdapterMouseListener -> MouseAdapter....
Esempio: click su un pulsante
1) Implemantazione di ActionListerpublic class MiaFinestra extends Frame implements ActionListener{ private Button pulsante=new Pulsante(“Premi qui”); public MiaFinestra() { ….. pulsante.addActionListener(this); //la mia classe è un ActionListener } public void actionPerformed(ActionEvent e) { System.out.println(“Evento actionPerformed”); Object obj=e.getSource(); //l’oggetto che ha generato l’evento
if(obj==pulsante) System.out.println(“Ho premuto su pulsante”);String cmd=e.getActionCommand(); //il testo contenuto nel componenteSystem.out.prinln(cmd);
}}
Esempio: click su un pulsante
2) Uso di un’altra classe gestore di eventipublic class MiaFinestra extends Frame { private Button pulsante=new Pulsante(“Premi qui”); public MiaFinestra() { ….. pulsante.addActionListener(new GestoreEventi()); }}-----------------------------------------------------------------------------------------public class GestoreEventi implements ActionListener,……{ public void actionPerformed(ActionEvent e) {
String cmd=e.getActionCommand(); //il testo contenuto nel componenteSystem.out.prinln(cmd);
}}
Esempio: click su un pulsante
3) Uso di classi innestate (modalità usata dagli strumenti visuali di sviluppo)public class MiaFinestra extends Frame { private Button pulsante=new Pulsante(“Premi qui”); public MiaFinestra() { ….. pulsante.addActionListener(
new ActionListener(){ public void actionPerformed(ActionEvent e)
{ pulsante_click(ActionEvent e); }}
); } /////////////////////////////////////////////////////// public void pulsante_click(ActionEvent e) {
//INSERISCI IL TUO CODICE QUI }}
Come disegnare su una finestra
E’ possibile disegnare sia direttamente sul Frame, sia su un Pannello, sia su un Canvas (una specie di pannello specifico per il disegno). Per disegnare si deve usare la classe astratta Graphics. In quanto astratta non è possibile creare una sua istanza, ma la si ricava tramite il metodo getGraphics() di Component. Tuttavia è più comune e più sicuro disegnare utilizzando un overriding del metodo paint(). Il metodo paint() viene chiamato automaticamente dalla VM quando il componente viene creato, non è mai possibile chiamarlo esplicitamente (al limite è possibile chiamare repaint() per fare un refresh).public class MiaFinestra extends Frame{ public void paint(Graphics g) { g.drawOval(50,50,100,100); } }Il paint viene richiamato automaticamente ogni volta che la finestra viene rivisualizzata, dopo essere stata coperta, iconificata, spostata, ecc..