[Per corso su Java vedere http://java.sun.com/docs/books/tutorial/]
Gli eventi sono classificati a seconda della loro causa scatenante, che puo' essere:
Classi di eventi hanno nomi del tipo XXXEvent dove XXX e' la causa. Es: MouseEvent...
Ogni classe di componente e' una potenziale sorgente di certe classi di eventi. Es: un bottone puo' originare eventi di classe "azionamento" (classe ActionEvent).
Posso registrare un event listener per ricevere eventi di una certa classe da una certa componente dell'interfaccia.
Vi e' un'interfaccia event listener per ogni classe di evento:
L'interfaccia listener prevede uno o piu' metodi che scattano quando
il listener riceve un evento di quella classe.
Essendo un listener interfaccia e non classe,
l'implenentazione dei metodi non e' definita.
Stabilita la classe di eventi che voglio catturare, devo creare
una classe che implementi il listener corrispondente,
fornendo il codice dei suoi metodi.
Poi creo un oggetto di tale classe e lo
associo alla componente sulla quale voglio catturare gli
eventi.
Esempio: voglio catturare azionamento di un bottone.
Questo paradigma si chiama delegation perche' il bottone delega l'azione da eseguire ad un altro oggetto (il listener).
Posso associare lo stesso event listener a piu' componenti nell'interfaccia: questi reagiranno allo stesso evento nello stesso modo.
Posso associare piu' event listener allo stesso oggetto: questo avra' piu' reazioni.
Una classe puo' implementare piu' interfacce listener.
Potra' essere usata per dare la stessa reazione a componenti
sensibili a tipi diversi di eventi.
Esempio (ExQuit.java):
bottone quit e chiusura di finestra, entrambi terminano applicazione.
import java.awt.*; import java.awt.event.*; public class ExQuit extends Frame { Button quitButton; public ExQuit() { quitButton = new Button("Click me to quit!"); add(quitButton); QuitListener listener = new QuitListener(); quitButton.addActionListener(listener); addWindowListener(listener); pack(); } class QuitListener extends WindowAdapter implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } public void windowClosing(WindowEvent e) { System.exit(0); } } public static void main(String[] args) { ExQuit app = new ExQuit(); app.setVisible(true); } }
Tutti i metodi dei listener hanno parametri come segue:
public void nomeFunzione(XXXEvent e)Nel body della funzione posso chiamare su e i metodi della classe di evento XXXEvent per reperire informazioni che servono per reagire all'evento. Esempio:
Il fatto che i listeners siano interfacce e non classi (cioe' che non implementino i metodi) implica che per i listener che hanno piu' metodi devo fornire un'implementazione di tutti i metodi, inclusi quelli che non mi interessano (l'implementazione di questi non fara' nulla: {}).
Per comodita' sono forniti adapters che forniscono implementazione standard di un listener (dove tutti i metodi non fanno nulla): creo sottoclasse dell'adapter ridefinendo solo i metodi che mi interessano.
Esempio:
La classe WindowEvent corrisponde a eventi sulle finestre
top-level: apertura / chiusura, iconificazione / deiconificazione...
La classe WindowListener ha un metodo per ciascuno
degli eventi di cui sopra.
Se voglio reagire solo all'evento di chiusura:
Classi di eventi che qualsiasi componente puo' catturare:
Nota: nelle varie sotto-classi di componenti alcuni di questi eventi sono gestiti internamente. Esempio: un campo di input testuale reagisce a guadagno / perdita del focus e a battitura di caratteri da tastiera in modo autonomo.
ComponentListener prevede i seguenti metodi di reazione ad eventi:
FocusListener prevede i seguenti metodi:
KeyListener prevede i seguenti metodi:
La classe di eventi MouseEvent ha due listener. Sono separati gli eventi di movimento del mouse, che comportano molto lavoro per gestirli (ogni movimento di un pixel genera un evento) ed e' previsto un listener a parte per questi.
MouseListener reagisce a tutti gli eventi tranne quelli di movimento, con i metodi:
MouseMotionListener reagisce agli eventi di movimento del mouse, con i metodi:
I contenitori top-level (frame e dialoghi) possono catturare eventi di classe WindowEvent.
Il WindowListener corrispondente prevede i seguenti metodi di reazione ad eventi:
A seconda della classe di dispositivo. Li vedremo man mano.
Classe Label, JLabel e' etichetta testuale in AWT, testuale e/o grafica in Swing.
Creazione in AWT:
Label label = new Label("stringa di testo");
Creazione in Swing:
ImageIcon icon = new ImageIcon("immagine.gif"); label1 = new JLabel("solo testo"); label2 = new JLabel("testo e immagine",icon); label3 = new JLabel(icon);Puo' esserci un ultimo argomento: l'allineamento, che puo' essere JLabel.LEFT, JLabel.RIGHT, JLabel.CENTER, JLabel.LEADING, JLabel.TRAILING.
Ci sono altri metodi per stabilire allineamento orizzontale / verticale dell'etichetta, spaziatura.
Classe Button / JButton.
Creazione (in Swing):
button = new JButton("titolo"); button = new JButton("titolo",icona); button = new JButton(icona);La prima chiamata e' legale anche con Button (in AWT).
L'esempio ExJButtons.java mostra
tre tipi di bottoni java.
Serve anche il file immagine buttonicon.gif.
Bottone di comando puo' catturare evento di azionamento ActionEvent: l'utente ha azionato il bottone, in che modo dipende dalla piattaforma (di solito col mouse).
Il corrispondente ActionListener ha un solo metodo actionPerformed che scatta quando il bottone e' azionato.
In ciascuna finestra top-level posso definire al piu' un solo bottone "di default" che e' sensibile anche alla pressione del tasto "return" (il sistema distingue graficamente tale bottone). In Swing:
finestratop.getRootPane().setDefaultButton(bottone);
Bottone a due stati (selezionato o non selezionato) o check box: Checkbox / JCheckBox.
Creazione:
Bottone a due stati puo' catturare evento di cambio stato ItemEvent. In Swing anche evento di azionamento ActionEvent (gia' visto per bottone di comando).
ItemListener prevede un solo metodo ItemStateChanged, che scatta quando il bottone cambia stato (da selezionato a deselezionato o viceversa).
Il programma legge il nuovo stato con e.getStateChange(), dove e e' l'evento, che ritorna uno fra ItemEvent.SELECTED e ItemEvent.DESELECTED.
boolean isSelected() ritorna true se componente e' selezionato
setSelected(boolean) forza selezione
Gruppo di bottoni radio e' un gruppo di bottoni a due stati dove in ogni istante un solo bottone puo' essere selezionato.
La pressione di un bottone del gruppo provoca automaticamente il rilascio di tutti gli altri bottoni del gruppo. Gruppi di radio-bottoni servono a implementare scelte mutuamente esclusive.
In AWT:
Esempio:
CheckboxGroup cbg = new CheckboxGroup(); add(new Checkbox("uno", cbg, true)); add(new Checkbox("due", cbg, false)); add(new Checkbox("tre", cbg, false));L'ultimo argomento booleano stabilisce se il bottone e' inizialmente selezionato (di default non e' selezionato).
In Swing:
Esempio:
rb1 = new JRadioButton("uno",true); rb2 = new JRadioButton("due"); rb3 = new JRadioButton("tre"); ButtonGroup bg = new ButtonGroup(); bg.add(rb1); bg.add(rb2); bg.add(rb3);
Radio button cattura stessi eventi di check box.
In Swing, quando utente preme un bottone radio in un gruppo, si generano tre eventi:
L'esempio ExButtons.java mostra i
tre tipi di bottoni (di comando, check box, radio).
Provare ad aggiungere gestione degli eventi.
Menu' permette scelta di un'opzione da una lista di voci che e' presentata come una tendina a scomparsa.
Un menu' puo' essere:
Esempio di menu' inseriti in barra:
bar = new MenuBar(); frame.setMenuBar(bar); menu1 = new Menu("Primo menu'"); bar.add(menu1); menu2 = new Menu("Altro menu'"); bar.add(menu2);
Analogamente si crea menu' pop-up:
pop = new PopupMenu("Menu' pop-up");Codice analogo nel caso Swing.
Ogni voce del menu' (menu item) ha caratteristiche analoghe a un bottone. Le classi di voci di menu' rispecchiano le classi di bottoni: MenuItem, CheckboxMenuItem in AWT, JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem in Swing.
Creo le varie voci separatamente e poi le aggiungo ad un Menu / JMenu. Un Menu / JMenu puo' essere usato come voce di un altro menu', realizzando in tal modo un menu' a cascata.
Esempio:
menu1 = new Menu("Primo menu'"); menu1.add (new MenuItem("voce semplice")); menu1.add (new CheckboxMenuItem("voce a due stati")); menu2 = new Menu("sotto menu'"); menu1.add (menu2); menu2.add("una voce"); menu2.add("altra voce");Crea un menu' (menu1) con tre voci: una semplice, una a check box e una costituita da un sottomenu' (menu2).
In piu' in Swing posso mettere testo e/o icone nelle voci di menu':
item = JMenuItem(stringa); item = JMenuItem(icona); item = JMenuItem(stringa,icona);Analogo per JCheckBoxMenuItem con in piu' ultimo argomento booleano (opzionale) che specifica se voce e' inizialmente selezionata o no.
In piu' in Swing ho classe JRadioBoxMenuItem per realizzare voci a due stati mutuamente esclusive.
Quelle che reagiscono a eventi sono le singole voci dei menu'.
Le voci che sono sottomenu' le gestisce automaticamente il sistema (la loro reazione e' mostrare la tendina del sottomenu').
Per assegnare un menu' pop-up ad un componente, si associa a quel componente
un MouseListener che faccia apparire il menu' pop-up
quando l'utente aziona il mouse.
Esempio (PopFrame.java): frame con
associato menu' pop-up
public class PopFrame extends Frame { PopupMenu popup; public PopFrame() { popup = new PopupMenu("A Popup Menu"); add(popup); MenuItem mi1 = new MenuItem("aaa"); popup.add(mi1); MenuItem mi2 = new MenuItem("bbb"); popup.add(mi2); setSize(new Dimension(200,100)); MouseListener listener = new PopupListener(); addMouseListener(listener); } class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) popup.show(e.getComponent(), e.getX(), e.getY()); } } }
Scorciatoie da tastiera.
Tutte le classi componenti hanno in comune un insieme di metodi per leggere / assegnare certe proprieta' generali.
Tutte le classi componenti hanno inoltre in comune un insieme di eventi che possono catturare (visti prima).
Queste caratteristiche comuni sono definite nella classe base Component (in AWT) e JComponent (in Swing). Nota: la classe JComponent deriva per ereditarieta' da Component, per cui JComponent ha tutti i metodi di Component ed altri in piu'.
Mappatura di un componente su schermo:
Per abilita' si intende capacita' di un componente ad interagire con l'utente.
I bordi servono non solo come ornamento ma anche per raggruppare assieme dispositivi logicamente correlati, eventualmente aggiungendo un titolo.
Ci vari tipi di bordi, in un bordo si possono inserire titoli e/o grafica. Esempi:
crea bordo a linea semplice, nero, senza titolo
comp.setBorder(BorderFactory.createLineBorder(Color.black));
crea bordo come prima piu' titolo posizionato al centro sotto
il riquadro incorniciato dal bordo
b1 = BorderFactory.createLineBorder(Color.black);
b2 = BorderFactory.createTitledBorder(b1,"titolo",
TitleBorder.CENTER,TitleBorder.BELOW_BOTTOM);
comp.setBorder(b2);
Riga di spiegazione a comparsa e scomparsa. Associabile a qualsiasi componente. Appare quando utente si ferma col mouse sopra la componente.
Esempio: comp.setToolTipText("Questo e' il messaggio");