Swing e la programmazione a eventi - Politecnico di...
Transcript of Swing e la programmazione a eventi - Politecnico di...
Swing e la programmazione a eventi�
Prova Finale – Ingegneria del Software �Davide Mazza�[email protected]�http://home.dei.polimi.it/mazza�
2
Lo stile basato su eventi�
l I componenti interagiscono attraverso l’invio di messaggi broadcast o multicast �l “Attenzione! C’è una nuova notizia di Politica”�l “Sono interessato alle notizie di Sport”�
l Ogni componente notifica un cambiamento nel proprio stato o in quello dell’ambiente inviando un messaggio �l In tal caso agisce da “generatore dell’evento”�
l Tutti i componenti interessati all’evento descritto da tale messaggio ne ricevono copia�l In tal caso agiscono da “ascoltatori dell’evento”�
l In generale, il generatore dell’evento non conosce né il numero né l’identità degli ascoltatori�
3
Occorrenza�dell’evento A �
Osservatori�
Realtà�Applicazione �
Ascoltatore�evento A �
Ascoltatore�evento A �
Ascoltatore�evento B �
Occorrenza�dell’evento B �
Notifica�dell’evento A � Notifica dell’evento B �
listeners�
Caratteristiche generali�
l Con il paradigma a eventi�l L’applicazione è puramente “reattiva”�l Non è possibile identificare staticamente un flusso di controllo unitario �
l Il programma principale si limita a inizializzare l’applicazione, istanziando gli osservatori e associandovi gli opportuni handler�
4
Vantaggi�
l Utili per sistemi altamente dinamici ed evolutivi, in cui nuovi moduli si possono aggiungere o possono essere eliminati�
l Per comunicare tra di loro, i moduli non devono conoscere le rispettive identità�l come invece accade in Java�
l nomeModulo.nomeServizio (parametri)�l Si parla più in generale di paradigma di progettazione "publish
and subscribe"�l moduli che generano eventi ("publish")�l moduli che sottoscrivono l'interesse ad essere notificati
dell'occorrenza di certi eventi ("subscribe")�
5
Gestore degli eventi�
subscribe x�
subscribe y�
subscribe z�x�
y�
In pratica�
6
Modello a eventi in Java�
l Un’applicazione può essere costruita come componenti che interagiscono attraverso eventi�
l Qui noi vediamo il package javax.swing �l libreria che fornisce le classi che consentono la progettazione delle
interfacce utente secondo lo stile ad eventi�
Swing�
8
UI e GUI �
l UI: User Interface�l L'interfaccia utente costituisce il mezzo con il quale l'utente
interagisce con l'applicazione��l GUI: Graphical User Interface��l Fondamentale per l'usabilità del software�
l Come si progetta?�
9
Progettazione �
l Separare GUI e parte funzionale �l La GUI si preoccupa di interagire con l'utente�
l visualizzare�l accettare input �
l La parte funzionale contiene la logica applicativa��l Vantaggi�
l GUI modificabile senza toccare la parte funzionale e viceversa�l La parte funzionale può essere testata automaticamente senza
interagire con l’interfaccia grafica�l Diverse strategie "look&feel" per la stessa applicazione�
l Spesso le modifiche si incentrano sulla GUI al fine di migliorare l'usabilità�
�
10
AWT e Swing �
l Abstract Windowing Toolkit (AWT)�
l Sono un residuo di precedenti versioni di JAVA fornisce ancora alcune importanti componenti al funzionamento e creazione di elementi di interfaccia�
l Swing�
l Costruite sopra AWT�l Consentono di realizzare applicazioni con un “look and feel” più aggiornato e
elegante�l Più semplici da usare rispetto alle librerie AWT�l Il nome di tutti le classi Swing inizia con J (Es. JButton, Jframe, ecc)�l Per motivi di compatibilità è bene non includere componenti Swing ed AWT in
una stessa interfaccia�
���
11
Model-View-Controller�
l Swing si basa su un “paradigma” di progettazione che si incontra anche in altri campi: �l Un componente ha un suo “modello logico”�l Un componente ha un suo “aspetto visuale”�l Un componente ha “comportamenti” che consentono la sua interazione
con il resto dell’applicazione�
l Esempio: JButton �l Model: Premuto/Rilasciato (variabile booleana)�l View: dipende dal look&feel�l Controller: azioni associate agli eventi del pulsante�
��
12
Un’interfaccia Swing �
l Tre elementi fondamentali�l Contenitori�
l Finestre, Panelli�
l Elementi Interattivi e visuali�l Pulsanti, Menù, Caselle di testo �
l Eventi�l Pulsante premuto, Focus, resize�
13
Components e Container�
l Tutti gli elementi che hanno una rappresentazioni grafica sono dei Component�l Sono sotto classi di java.awt.Component �l Esempi: JLabel, JTextArea, JButton �
l Sia i contenitori che gli elementi interattivi sono Component�
l I contenitori sono implementati dalla classe java.awt.Container�l Sotto classe di java.awt.Component �l Esempi: JFrame, JPanel�
14
Container�
l I Container possono contenere un insieme di Component �
l Dato che tutti i Container sono dei Component posso avere un meccanismo a scatole cinesi�l Un container può contenere altri Container�l Esempio: una finestra contiene diversi pannelli, e i pannelli
contengono vari pulsanti�l Non tutti i Component sono Container! �
l Container.add(Component c)�l Container.add(Component c, parametri …)�
l I parametri specificano come il componente verrà posizionato nel contenitore�
15
Frame �
l Un frame �l Definisce l’intelaiatura dell’interfaccia�
l Fornisce un rettangolo, “decorato” alla maniera delle finestre cui siamo abituati�
l E’ un oggetto COMPLESSO! �
l Riceve Eventi come close, resize, �riduzione ad icona, ecc�
�
16
JFrame �
l Come in tutta la programmazione ad oggetti occorre conoscere la “gerarchia” entro la quale si colloca JFrame�
l Per conoscere la “derivazione” di ogni oggetto delle librerie GUI di Swing si deve fare ricorso alla documentazione in linea di Java�l 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�
l Component �l “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”�
l Component è quindi una classe molto generale e definisce un sacco di metodi�
l Container�l Un Component con la proprietà di essere abilitato a contenere altri
Component �l Prevede metodi di tipo “add” per aggiungere componenti�
l Prevede anche metodi per rappresentare il contenitore e i suoi contenuti e per aggiornarne l’immagine�
�
18
Scorrendo la gerarchia�
l Window �l È un particolare contenitore che può apparire sullo schermo come entità
propria, ma non ha bordi, barre e controlli�l Possiede metodi per mostrare la finestra, nascondere la finestra, posizionare la
finestra e aggiustare l’ordine di comparizione relativamente ad altre finestre�l Frame�
l Si tratta di Window con bordi e barra del titolo, oltre alle caratteristiche solite di un’interfaccia (minimizzazione, iconizzazione, chiusura, resizing)�
l JFrame�l È un Frame AWT a cui SWING aggiunge una serie di metodi per ridefinire i
dettagli grafici. Ad esempio �l l metodo setSize(int l, int h) permette di determinare le dimensioni del Frame�l 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?�
l Aggiungere un titolo usando il costruttore ereditato �
l Possiamo aggiungere componenti nel suo pannello principale: �l frame.getContentPane().add(label)�l frame.add(label)�
l Settare le dimensioni delle finestra�
l Associare un azione all’evento di chiusura della finestra�
l 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�
l Dobbiamo sapere: �l Da dove prendere i componenti?�
l Una lista/descrizione delle librerie disponibili�l Come costruirli e personalizzarli?�
l Costruttori e modificatori�l Come usarli?�
l Quali eventi sono in grado di raccogliere e quali i listener necessari�l Come disporli sui frame che costituiscono la nostra applicazione?�
l Layout manager��
22
JApplet � JDialog � JFrame �
JPanel� JScrollPane � JSplitPane � JTabbedPane �
Container�
l Top-level container�������l 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�
l 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�
l Java gestisce la disposizione dei componenti dentro i Container mediante oggetti che si chiamano LayoutManager�l Incapsulano gli algoritmi per il posizionamento delle componenti di una
GUI �l Il LayoutManager mantiene l’algoritmo separato in una classe a parte�
l È un’interfaccia che descrive come un componente deve comunicare con il suo LayoutManager�
l Esiste un’ampia collezione di LayoutManager, ma se si vuole si può creare il proprio �l Noi vediamo solo i LayoutManager più comuni: FlowLayout,
BorderLayout, GridLayout, CardLayout e GridBagLayout �l L’associazione avviene tramite il metodo setLayout() di cui è
provvista la classe Container (e quindi tutte le sue sottoclassi)�l p.setLayout(new BorderLayout()); �
28
FlowLayout�
l E’ il più semplice. La sua strategia è: �l Rispettare la dimensione di tutti i
componenti�l Disporre i componenti in orizzontale
finché non viene riempita tutta una riga, altrimenti iniziare su una nuova riga�
l Se non c’è spazio i componenti non vengono visualizzati�
l E’ possibile allineare i componenti a sinistra, destra o al centro �
l 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�
l Definisce 5 aree logiche: NORTH, SOUTH, CENTER, EAST e WEST�l Richiede la dimensione preferita del componente (altezza e larghezza)�l Se il componente è NORTH o SOUTH setta l’altezza al valore preferito e
la larghezza in modo da occupare tutto lo spazio orizzontale�l Se il componente è EAST o WEST setta la larghezza al valore preferito
e l’altezza in modo da occupare tutto lo spazio verticale restante�l Se il componente è CENTER setta l’altezza e la larghezza in modo da
occupare tutto lo spazio centrale restante�l Quindi�
l Le posizioni NORTH e SOUTH servono quando vogliare fissare l’altezza di un componente al valore preferito �
l Le posizioni EAST e WEST servono quando vogliamo fissare la larghezza di un componente al valore preferito �
l 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�
l 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�
l Nel JPanel il layout di default è: FlowLayout �
l Nel JFrame il layout di default è: BorderLayout �
34
Eventi�
l L’interazione tra gli elementi dell’interfaccia e la logica applicativa è gestita tramite eventi�
l Gli EventListener sono interfacce definite per catturare e processare tipi di eventi particolari�
l Un listener deve�l Essere associato al componente�l Essere informato quando il componente genera un evento del tipo
richiesto �l Rispondere facendo qualcosa di appropriato �
��
35
EventHandler�
l Devono avere tre pezzi di codice�
l Dichiarazione�l Estendono o implementano listener esistenti�l public class MyClass implements ActionListener { �
l Associazione tra handler (ovvero listener) e istanza�l someComponent.addActionListener(instanceOfMyClass); �
l Definizione del codice che implementa i metodi dell’interfaccia listener�l 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�
FocusListener�FocusEvent �focus �
WindowListener�WindowEvent �cambiamenti nella finestra�
ActionListener�ActionEvent �bottoni, menu,...�
AdjustmentListener�AdjustmentEvent �scrollbar�
TextListener�TextEvent �input di testo �
ItemListener�ItemEvent �Selezione elem�
KeyListener�KeyEvent �Keyboard �
MouseListener, MouseMotionListener�
MouseEvent �Mouse�
handler�Evento �Categoria�
38
Swing e Thread�
l Nelle Swing, la gestione degli eventi e il ridisegno delle finestre e dei componenti grafici è affidata ad un unico thread�l Dispatching Thread�
l Perché un unico thread? Perché le Swing non sono thread safe! L’accesso ad un oggetto da parte di più thread può causare problemi! �
l Dispatching Thread: �l Viene eseguito in background�l Processa gli elementi presenti nella coda degli eventi grafici�l 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�
l Swing Tutorial: �http://download.oracle.com/javase/tutorial/uiswing/index.html�
l Java Api: �http://java.sun.com/javase/6/docs/api/ �
���