swing e la programmazione a eventi prova finale – ingegneria del software davide mazza...
TRANSCRIPT
Swing e la programmazione a eventi
Prova Finale – Ingegneria del SoftwareDavide [email protected]://home.dei.polimi.it/mazza
2
Lo stile basato su eventi
I componenti interagiscono attraverso l’invio di messaggi broadcast o multicast “Attenzione! C’è una nuova notizia di Politica” “Sono interessato alle notizie di Sport”
Ogni componente notifica un cambiamento nel proprio stato o in quello dell’ambiente inviando un messaggio In tal caso agisce da “generatore dell’evento”
Tutti i componenti interessati all’evento descritto da tale messaggio ne ricevono copia In tal caso agiscono da “ascoltatori dell’evento”
In generale, il generatore dell’evento non conosce né il numero né l’identità degli ascoltatori
3
Occorrenzadell’evento A
Osservatori
Realtà
Applicazione
Ascoltatoreevento A
Ascoltatoreevento A
Ascoltatoreevento B
Occorrenzadell’evento B
Notificadell’evento A Notifica dell’evento B
listeners
Caratteristiche generali
Con il paradigma a eventi L’applicazione è puramente “reattiva” Non è possibile identificare staticamente un flusso di controllo
unitario Il programma principale si limita a inizializzare l’applicazione,
istanziando gli osservatori e associandovi gli opportuni handler
4
Vantaggi
Utili per sistemi altamente dinamici ed evolutivi, in cui nuovi moduli si possono aggiungere o possono essere eliminati
Per comunicare tra di loro, i moduli non devono conoscere le rispettive identità come invece accade in Java
nomeModulo.nomeServizio (parametri) Si parla più in generale di paradigma di progettazione
"publish and subscribe" moduli che generano eventi ("publish") moduli che sottoscrivono l'interesse ad essere notificati
dell'occorrenza di certi eventi ("subscribe")
5
Gestore degli eventi
subscribe x
subscribe y
subscribe zx
y
In pratica
6
Modello a eventi in Java
Un’applicazione può essere costruita come componenti che interagiscono attraverso eventi
Qui noi vediamo il package javax.swing libreria che fornisce le classi che consentono la progettazione
delle interfacce utente secondo lo stile ad eventi
Swing
8
UI e GUI
UI: User Interface L'interfaccia utente costituisce il mezzo con il quale l'utente
interagisce con l'applicazione
GUI: Graphical User Interface
Fondamentale per l'usabilità del software
Come si progetta?
9
Progettazione
Separare GUI e parte funzionale La GUI si preoccupa di interagire con l'utente
visualizzare accettare input
La parte funzionale contiene la logica applicativa
Vantaggi GUI modificabile senza toccare la parte funzionale e viceversa La parte funzionale può essere testata automaticamente senza
interagire con l’interfaccia grafica Diverse strategie "look&feel" per la stessa applicazione
Spesso le modifiche si incentrano sulla GUI al fine di migliorare l'usabilità
10
AWT e Swing
Abstract Windowing Toolkit (AWT)
Sono un residuo di precedenti versioni di JAVA fornisce ancora alcune importanti componenti al funzionamento e creazione di elementi di interfaccia
Swing
Costruite sopra AWT Consentono di realizzare applicazioni con un “look and feel” più
aggiornato e elegante Più semplici da usare rispetto alle librerie AWT Il nome di tutti le classi Swing inizia con J (Es. JButton, Jframe, ecc) Per motivi di compatibilità è bene non includere componenti Swing ed
AWT in una stessa interfaccia
11
Model-View-Controller
Swing si basa su un “paradigma” di progettazione che si incontra anche in altri campi: Un componente ha un suo “modello logico” Un componente ha un suo “aspetto visuale” Un componente ha “comportamenti” che consentono la sua
interazione con il resto dell’applicazione
Esempio: JButton Model: Premuto/Rilasciato (variabile booleana) View: dipende dal look&feel Controller: azioni associate agli eventi del pulsante
12
Un’interfaccia Swing
Tre elementi fondamentali Contenitori
Finestre, Panelli
Elementi Interattivi e visuali Pulsanti, Menù, Caselle di teso
Eventi Pulsante premuto, Focus, resize
13
Components e Container
Tutti gli elementi che hanno una rappresentazioni grafica sono dei Component Sono sotto classi di java.awt.Component Esempi: JLabel, JTextArea, JButton
Sia i contenitori che gli elementi interattivi sono Component
I contenitori sono implementati dalla classe java.awt.Container Sotto classe di java.awt.Component Esempi: JFrame, JPanel
14
Container
I Container possono contenere un insieme di Component
Dato che tutti i Container sono dei Component posso avere un meccanismo a scatole cinesi Un container può contenere altri Container Esempio: una finestra contiene diversi pannelli, e i
pannelli contengono vari pulsanti Non tutti i Component sono Container!
Container.add(Component c) Container.add(Component c, parametri …)
I parametri specificano come il componente verrà posizionato nel contenitore
15
Frame
Un frame Definisce l’intelaiatura dell’interfaccia
Fornisce un rettangolo, “decorato” alla maniera delle finestre cui siamo abituati
E’ un oggetto COMPLESSO!
Riceve Eventi come close, resize,riduzione ad icona, ecc
16
JFrame
Come in tutta la programmazione ad oggetti occorre conoscere la “gerarchia” entro la quale si colloca JFrame
Per conoscere la “derivazione” di ogni oggetto delle librerie GUI di Swing si deve fare ricorso alla documentazione in linea di Java http://java.sun.com/j2se/1.5/docs/api/
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
javax.swing.JFrame
17
Scorrendo la gerarchia
Component “A component is an object having a graphical representation
that can be displayed on the screen and that can interact with the user. Examples of components are the buttons, checkboxes, and scrollbars of a typical graphical user interface”
Component è quindi una classe molto generale e definisce un sacco di metodi
Container Un Component con la proprietà di essere abilitato a contenere
altri Component Prevede metodi di tipo “add” per aggiungere componenti
Prevede anche metodi per rappresentare il contenitore e i suoi contenuti e per aggiornarne l’immagine
18
Scorrendo la gerarchia
Window È un particolare contenitore che può apparire sullo schermo come
entità propria, ma non ha bordi, barre e controlli Possiede metodi per mostrare la finestra, nascondere la finestra,
posizionare la finestra e aggiustare l’ordine di comparizione relativamente ad altre finestre
Frame Si tratta di Window con bordi e barra del titolo, oltre alle caratteristiche
solite di un’interfaccia (minimizzazione, iconizzazione, chiusura, resizing)
JFrame È un Frame AWT a cui SWING aggiunge una serie di metodi per
ridefinire i dettagli grafici. Ad esempio l metodo setSize(int l, int h) permette di determinare le dimensioni del
Frame Il metodo setLocation(int x, int y) consente di definire le coordinate del
pixel in alto a sinistra del frame nel riferimento dello schermo
19
Cosa possiamo fare con un JFrame?
Aggiungere un titolo usando il costruttore ereditato
Possiamo aggiungere componenti nel suo pannello principale: frame.getContentPane().add(label) frame.add(label)
Settare le dimensioni delle finestra
Associare un azione all’evento di chiusura della finestra
Mostrare la finestra all’utente
20
HelloWorldSwing
import javax.swing.*;
public class HelloWorld extends JFrame{
public HelloWorld (){super("HelloWorld!");setSize(200, 100);setDefaultCloseOperation(EXIT_ON_CLOSE);add(new JLabel("Hello World!"));
setVisible(true);}
public static void main(String[] args) {new HelloWorld();
}}
21
Aggiungiamo componenti
Dobbiamo sapere: Da dove prendere i componenti?
Una lista/descrizione delle librerie disponibili Come costruirli e personalizzarli?
Costruttori e modificatori Come usarli?
Quali eventi sono in grado di raccogliere e quali i listener necessari
Come disporli sui frame che costituiscono la nostra applicazione? Layout manager
22
JApplet JDialog JFrame
JPanelJScrollPane JSplitPane JTabbedPane
Container
Top-level container
General-purpose container
23
JInternalFrame JLayeredPane
Permette di inserire componenti a vari livelli di profondità
JToolBar
Permette di inserire frame dentro altri frame
Permette di semplificare l’attivazione di determinate funzioni per mezzo di semplici pulsanti
Container
Special-purpose container
24
JButtons
Include buttons, radioButtons, checkbox, MenuItem, ToggleButton
JComboBox JList JMenu
JSlider JTextField
Include JPasswordField, JTextArea
Controlli di base
25
JLabel
Può includere immagini e/o testo
JProgressBar Jcomponent.setToolTipText(String)
Visualizzatori di informazioni non editabili
26
JColorChooser JFileChooser JTable
JTextComponent
JTextField, JPasswordField, JTextArea, JEditorPane, JTextPane
JTree
Visualizzatori di informazioni formattate editabili
27
Layout
Java gestisce la disposizione dei componenti dentro i Container mediante oggetti che si chiamano LayoutManager Incapsulano gli algoritmi per il posizionamento delle
componenti di una GUI Il LayoutManager mantiene l’algoritmo separato in una classe a
parte È un’interfaccia che descrive come un componente deve
comunicare con il suo LayoutManager Esiste un’ampia collezione di LayoutManager, ma se si
vuole si può creare il proprio Noi vediamo solo i LayoutManager più comuni: FlowLayout,
BorderLayout, GridLayout, CardLayout e GridBagLayout L’associazione avviene tramite il metodo setLayout() di cui
è provvista la classe Container (e quindi tutte le sue sottoclassi) p.setLayout(new BorderLayout());
28
FlowLayout
E’ il più semplice. La sua strategia è: Rispettare la dimensione di tutti i
componenti Disporre i componenti in
orizzontale finché non viene riempita tutta una riga, altrimenti iniziare su una nuova riga
Se non c’è spazio i componenti non vengono visualizzati
E’ possibile allineare i componenti a sinistra, destra o al centro
E’ possibile specificare la distanza verticale e orizzontale
public static void main(String[] args) {JFrame frame = new JFrame("Flow");frame.setLayout(new FlowLayout());frame.add(new JButton("Button1"));frame.add(new JButton("Button2"));frame.add(new JButton("Button3"));frame.add(new JButton("Button4"));frame.add(new JButton("Button5"));frame.pack();frame.setVisible(true);
}
29
BorderLayout
Definisce 5 aree logiche: NORTH, SOUTH, CENTER, EAST e WEST Richiede la dimensione preferita del componente (altezza e
larghezza) Se il componente è NORTH o SOUTH setta l’altezza al valore
preferito e la larghezza in modo da occupare tutto lo spazio orizzontale
Se il componente è EAST o WEST setta la larghezza al valore preferito e l’altezza in modo da occupare tutto lo spazio verticale restante
Se il componente è CENTER setta l’altezza e la larghezza in modo da occupare tutto lo spazio centrale restante
Quindi Le posizioni NORTH e SOUTH servono quando vogliare fissare l’altezza
di un componente al valore preferito Le posizioni EAST e WEST servono quando vogliamo fissare la larghezza
di un componente al valore preferito La parte CENTER è quella che si espande
30
Esempio
public static void main(String[] args) {JFrame frame = new JFrame("Border");frame.setLayout(new BorderLayout());frame.add(new JButton("North"), BorderLayout.NORTH);frame.add(new JButton("South"), BorderLayout.SOUTH);frame.add(new JButton("Center"), BorderLayout.CENTER);frame.add(new JButton("East"), BorderLayout.EAST);frame.add(new JButton("West"), BorderLayout.WEST);frame.pack();frame.setVisible(true);
}
31
GridLayout
Dispone i componenti su una griglia
public static void main(String[] args) {JFrame frame = new JFrame("Grid");frame.setLayout(new GridLayout(3,4));for (int x=0; x<12; x++)
frame.add(new JButton(""+x));frame.pack();frame.setVisible(true);
}
32
Stratificazione
public static void main(String[] args) {JPanel panel_flow=new JPanel(new
FlowLayout(FlowLayout.CENTER,20,20));panel_flow.setBorder(BorderFactory.createTitledBorder("Flow Layout"));panel_flow.add(new JLabel("JLabel"));panel_flow.add(new JTextField("JTextField"));panel_flow.add(new JButton("JButton"));JPanel panel_grid=new JPanel(new GridLayout(3,1));panel_grid.setBorder(BorderFactory.createTitledBorder("Grid Layout"));panel_grid.add(new JButton("JButton_1"));panel_grid.add(new JButton("JButton_2"));panel_grid.add(panel_flow);
JFrame f = new JFrame("Example");f.add(panel_grid);f.pack();f.setVisible(true);
}
33
Layout di Default
Nel JPanel il layout di default è: FlowLayout
Nel JFrame il layout di default è: BorderLayout
34
Eventi
L’interazione tra gli elementi dell’interfaccia e la logica applicativa è gestita tramite eventi
Gli EventListener sono interfacce definite per catturare e processare tipi di eventi particolari
Un listener deve Essere associato al componente Essere informato quando il componente genera un evento del
tipo richiesto Rispondere facendo qualcosa di appropriato
35
EventHandler
Devono avere tre pezzi di codice
Dichiarazione Estendono o implementano listener esistenti public class MyClass implements ActionListener {
Associazione tra handler (ovvero listener) e istanza someComponent.addActionListener(instanceOfMyClass);
Definizione del codice che implementa i metodi dell’interfaccia listener public void actionPerformed(ActionEvent e) { ...
36
Un primo esempio
public class Demo extends JFrame implements ActionListener { JButton button = new JButton("Click me!");public Demo() {
button.addActionListener(this); getContentPane().add(button); pack(); setVisible(true);
}public void actionPerformed(ActionEvent e) {
button.setBackground(Color.RED); }public static void main(String[] args) {
new Demo();}
}
37
Eventi e Listener
FocusListenerFocusEventfocus
WindowListenerWindowEventcambiamenti nella finestra
ActionListenerActionEventbottoni, menu,...
AdjustmentListenerAdjustmentEventscrollbar
TextListenerTextEventinput di testo
ItemListenerItemEventSelezione elem
KeyListenerKeyEventKeyboard
MouseListener, MouseMotionListener
MouseEventMouse
handlerEventoCategoria
38
Swing e Thread
Nelle Swing, la gestione degli eventi e il ridisegno delle finestre e dei componenti grafici è affidata ad un unico thread Dispatching Thread
Perché un unico thread? Perché le Swing non sono thread safe! L’accesso ad un oggetto da parte di più thread può causare problemi!
Dispatching Thread: Viene eseguito in background Processa gli elementi presenti nella coda degli eventi
grafici Anche il ri-disegno dei componenti è un evento (paint)
39
Esempio Completo
public class Calcolatrice extends JFrame {
private JButton somma;
private JTextField num1;
private JTextField num2;
private JTextField tot;
public Calcolatrice(){
[…]
}
//Gestione Evento
[…]
public static void main(String[] args) {
new Calcolatrice();
}
}
40
Esempio Completo - Costruttore
public Calcolatrice(){
super("Semplice Calcolatrice");
setDefaultCloseOperation(EXIT_ON_CLOSE);
somma = new JButton("somma");
num1 = new JTextField("1",5);
num2 = new JTextField("1",5);
tot = new JTextField("0",5);
somma.addActionListener(new AzioneSomma());
setLayout(new FlowLayout());
add(num1);
add(num2);
add(somma);
add(tot);
pack();
setVisible(true);
}
41
Esempio Completo – Gestore dell’Evento
public class Calcolatrice extends JFrame {
private JButton somma;
private JTextField num1;
private JTextField num2;
private JTextField tot;
public Calcolatrice(){
}
//Gestione Evento
private class AzioneSomma implements ActionListener{public void actionPerformed(ActionEvent arg0) {
int n1= Integer.parseInt(num1.getText());int n2= Integer.parseInt(num2.getText());tot.setText("" + (n1+n2));
}
}
42
Link utili
Swing Tutorial:http://download.oracle.com/javase/tutorial/uiswing/index.html
Java Api:http://java.sun.com/javase/6/docs/api/