AWT e Swing Docente: Gabriele Lombardi [email protected] © 2010 - CEFRIEL The present original document was produced by CEFRIEL and the Teacher for the benefit and internal use of this course, and nobody else may claim any right or paternity on it. No right to use the document for any purpose other than the Intended purpose and no right to distribute, disclose, release, furnish or disseminate it or a part of it in any way or form to anyone without the prior express written consent of CEFRIEL and the Teacher. © copyright Cefriel and the Teacher-Milan-Italy-23/06/2008. All rights reserved in accordance with rule of law and international agreements. © 2010 - CEFRIEL Sommario SLIDE CONTENUTO Toolkits Cosa sono e che tipologie ne esistono AWT Peers, componenti, gestione eventi AWT: Packaging Contenitori e layout managers AWT: Varie Colori, font, geometria, immagini, stampa, … Swing Problemi di AWT? Soluzione? Swing: MVC Analisi di un componente di esempio Swing: Varie Rassegna dei componenti © 2010 - CEFRIEL Toolkits Scopo: – consentire al programmatore di definire: • interfacce uomo-macchina (grafiche); • in maniera semplice (dichiarativa); • pienamente funzionanti: – gestione “interna” degli eventi (dell’utente); – gestione “esterna” degli eventi (dell’utente); Tipologie: – costruttive: • la struttura dati contenente gli “oggetti grafici” viene costruita dal programmatore: – GTK, QT, MFC, AWT, Swing, … – dichiarative: • la struttura dati contenente gli “oggetti grafici” viene definita tramite un apposito linguaggio: – Glade, XUL, XAML, … © 2010 - CEFRIEL AWT Primo toolkit per interfacce grafiche in Java: – basato sull’idea di riutilizzo dei toolkit esistenti; – definito attorno al concetto di peers: • ogni componente è un wrapper per un componente del sistema grafico ospitante; – offre un’infrastruttura di accesso a componenti: • esistenti nel sistema operativo ospitante; • quindi solo un subset comune hai SO considerati (massimo subset comune). Vantaggi: – molto efficiente. Svantaggi: – autolimitato dal rodotto subset di componenti esterne. © 2010 - CEFRIEL AWT: Packaging Problema: – definire il layout delle componenti uno nell’altro; – astrazione dei contenitori: • panelli, finestre, … componenti in generale! Soluzione: – definire i “gestori di layout” come astrazione di … • “coloro che impacchettano i componenti”; – realizzare differenti implementazioni per ottenere svariate modalità di “impacchettamento”: • box, flow, grid, gridbag, … – parametri di preferenza per il packaging: • • • • dimensioni massime, minime, preferite; tipo di layout; ordine e posizione di inserimento; … © 2010 - CEFRIEL AWT: Gestione degli eventi Ogni evento: – – – – è un oggetto istanziato quando si verifica; deriva direttamente o indirettamente da EventObject; trasporta le informazioni che lo caratterizzano; viene passato ai gestori di quel tipo di evento. Ogni gestore: – implementa l’interfaccia (marchio) EventListener; – di solito implementa direttamente un’interfaccia che estende la precedente, aggiungendo gli handler; – il nome degli handler è del tipo “*Listener”; – esistono spesso degli adapter, implementano tutte le risposte vuote (di cui fare override) comodità! vedere Code\03_AWT&Swing\AWT con: esempio di base di creazione di una finestra packaging di componenti cattura di un evento © 2010 - CEFRIEL java.awt.** java.awt.color: – gestione di due aspetti relativi al colore: • spazio colore: – RGB, Ycbcr, Luv, Lab, XYZ, HSV, … • profilo: – numero, codifica e posizione delle componenti: » RGB, RGBA, ARGB, ABGR, 8 bit, 12 bit, … java.awt.font: – gestione delle famiglie/tipologie/sottotipologie di font; – gestione del loro aspetto grafico: • rendering, dimensioni, glifi, … java.awt.print: – strumenti di impaginazione della stampa. © 2010 - CEFRIEL java.awt.** java.awt.geom: – strumenti di geometria 2D: • forme geometriche: – punti, linee, curve, archi, rettangoli, … • trasformazioni: – similarità, affinità, … java.awt.image: * – memorizzazione: • strategie di buffering; • formato dei dati (colormodel); – trasformazione: affine, … – filtering: • lineare (convoluzione con kernel); • generale (tramite ImageFilter); – inoltre: SampleModel, PixelGrabber, ImageProducer, ImageConsumer, ImageObserver, LookupTable, … © 2010 - CEFRIEL Swing: intro Problemi con AWT? – componenti limitate (subset comune); – impossibile realizzare componenti custom; – chiamate indirette al SO tramite wrapper. Soluzione di Swing: – costruire le proprie componenti da zero: • all’interno di un java.awt.Component; • le componenti si disegnano da sé; • Swing gestisce eventi di livello più basso; – vantaggi di questa piccola evoluzione: • • • • set ampio di componenti preconfezionate; architettura indipendente dai peer MVC; possibile creare componenti custom; efficiente essendo basato su Java2D … – … che si appoggia su OpenGL o su DirectX. © 2010 - CEFRIEL Swing: intro Dove cosa: – componenti in javax.swing.** … • … altre nei sotto-package; – tutte le componenti si chiamano javax.swing.J*; – componenti figlie di JComponent: • possiamo estendere questa componente noi stessi per creare componenti custom; – nuove implementazioni di LayoutManager … – … input, PLAF, eventi, e molto altro! Ricordarsi però che: – Swing si appoggia ad AWT: • spesso è richiesto l’utilizzo di package in esso contenuti (come java.awt.event.*); – l’utilizzo CONSAPEVOLE di IDE con designer è consigliabile. © 2010 - CEFRIEL Swing: esempio Esercizio 1: si costruisca un’applicazione grafica che: • mostri una calcolatrice semplice; • implementi le 4 operazioni algebriche +, -, *, /; • implementi la funzionalità di memorizzazione: – tasti MS e MR per salvare in memoria e per recuperare il valore; – tasti M+ e M- per aggiungere e togliere al contenuto della memoria. Esercizio 2: si costruisca, utilizzando NetBeans: – un’applicazione grafica di visualizzazione risultati query: • funzionalità: mostrare su richiesta il contenuto delle tabelle di un database: – show tabellaUtenti – Pippo DePippis Papero DePaperis … … • createne l’interfaccia, e inizialmente utilizzate funzionalità di quering fittizie, con java.sql potremo renderle reali query verso un database. © 2010 - CEFRIEL Swing: MVC MVC (Model View Controller): – pattern di separazione delle responsabilità sui dati; – spesso usato per le interfacce grafiche; – identifica i seguenti ruoli di manipolazione di una struttura dati: • Model la struttura dati; • View la rappresentazione (grafica) dei dati; • Controller gli algoritmi di modifica dei dati. In Swing: – le componenti hanno lo scopo di permettere la visualizzazione e la generazione di eventi di manipolazione di dati (da parte dell’utente); – i modelli ne rappresentano la struttura (ad es. ListModel); – le viste sono le componenti grafiche; – i controller sono ascoltatori di eventi (Listener). Vediamo: – un esempio di utilizzo delle liste: • lista di file come modello in una componente JList; • si veda 03_AWT&Swing\Swing\SwingExamples01: – sono stati inseriti svariati widget come esempio; – si osservi il funzionamento della lista di file (con la classe FilesListModel realizzata come classe innestata di GeneratedExample). © 2010 - CEFRIEL Swing: esempio liste private static class FilesListModel implements ListModel { private String[] names; public FilesListModel(File baseDir) { names = baseDir.list(null); } public int getSize() { return names.length; } public Object getElementAt(int index) { return names[index]; } public void addListDataListener(ListDataListener l) {} public void removeListDataListener(ListDataListener l) {} } Definiamo un modello di lista basato sul contenuto di una directory private void btn_chooseDirActionPerformed( java.awt.event.ActionEvent evt) { // Aggiornamento della directory: JFileChooser chooser = new JFileChooser( fld_dirname.getText()); chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY); if (chooser.showDialog(this, "Seleziona la directory") == JFileChooser.APPROVE_OPTION) { // Cambio directory: fld_dirname.setText( chooser.getSelectedFile().toString()); lst_files.setModel( new FilesListModel(chooser.getSelectedFile())); } } © 2010 - CEFRIEL Rassegna componenti Di seguito è riportata una lista di componenti: – non esaustiva, ne esistono molti standard … • … e molti di più non standard ma open; – di cui non si approfondisce l’utilizzo; – per i quali si consiglia di provare a costruire un programma di esempio (uno per componente). Elenco di alcune delle componenti: – JLabel, JButton, JToggleButton, JCheckBox, JRadioButton, JTextField, JPasswordFiled, JFormattedTextField, JTextArea, JList, JComboBox, JTree, JTable, JScrollBar, JProgressBar, JFrame, JDialog, JMenu, JMenuBar, JMenuItem, JCheckBoxMenuItem, JRadioButtonMenuItem, JSeparator, JPopupMenu, JFileChooser, JColorChooser, JOptionPane, JPanel, JScrollPane, JTextPane, JEditorPane, JSpinner, JSlider, JSplitPane, JTabbedPane, JDesktopPane, JLayeredPane, JInternalFrame, JToolBar, … – inoltre è possibile realizzare nuove componenti custom. © 2010 - CEFRIEL Componenti di base JLabel: visualizzare un testo informativo: JButton: pulsante per invocare un’azione: JToggleButton: per selezionare opzioni: JCheckBox: come il precedente: JRadioButton: selezione singola tra scelte multiple: – JLabel lblExample = new JLabel(“Testo informativo”); – lblExample.setText(“Altro testo”); – JButton btnExample = new JButton(“Clicca qui); – btnExample.addActionListener(…); – JToggleButton tglExample = new JToggleButton(“ChangeMe”,true); – if (tglExample.isSelected()) {…} – JCheckBox chkExample = new JCheckBox(“Option”); – If (chkExample.isSelected()) {…} – – – – ButtonGroup grp = new ButtonGroup(); grp.add(new RadioButton(“opt1”)); grp.add(new RadioButton(“opt2”)); System.out.println(“Azione: ” + grp.getSelection().getActionCommand()); JTextField, JPasswordFiled, JFormattedTextField, JTextArea: – campi di testo semplice (nascosto in quanto password, formattato); – JTextField fldExample = new JTextField(“Change this text”); – System.out.println(“Testo: ” + fldExample.getText()); JFrame, JDialog, JPanel: contenitori di altri componenti: – JPanel pnl = new JPanel(); JFrame frm = new JFrame(“Titolo”); – JLabel lbl = new JLabel(“Qualcosa”); frm.add(pnl); pnl.add(lbl); © 2010 - CEFRIEL Componenti complesse JList: mostra una lista di elementi: – Una possibilità semplice è data dalla creazione della lista data una collezione (o array) di elementi: • String[] data = {“Primo", “Secondo"}; • JList lstExample = new JList(data); • System.out.println(“Selezionato: ” + lstExample.getSelectedValue()); – Come altro esempio si veda la classe GeneratedExample.FilesListModel in 03_AWT&Swing\Swing\SwingExamples01 JComboBox: lista con selezione singola: – Si tratta di un JTextFiled composto con una JList in cui scegliere l’elemento da mostrare nel campo di testo. JTable: tabella (lista di tuple): – Componente capace di mostrare una tabella con righe e colonne; – Si provi a mostrare un JTable con un TableModel creato per generare le tabelline dei numeri interi forniti come parametro al costruttore. • Si veda 03_AWT&Swing\Swing\SwingExamples01, la classe TabellinaTableModel e sotto la scheda “tab2”. JTree: gerarchia di elementi: – Componente di visualizzazione di una gerarchia (albero) di elementi, come ad esempio le directory ed i file in un file-system (si pensi a gestione risorse). – Se adeguatamente re-implementato il modello TreeModel, si può definire un albero capace di caricare dati solo quando servono durante la navigazione. – Si osservi, come esempio di caricamento al volo, le classi JDMSBrowser e DMSTreeNode in Code\02_BaseAPIs\Altre\DMS\DMS. © 2010 - CEFRIEL Altre componenti JMenuBar, JMenu, JMenuItem, JSeparator, JCheckBoxMenuItem, JRadioButtonMenuItem: – permettono di creare definire una struttura (con radice in JMenuBar) che definisce una barra dei menu. JPopupMenu: menu contestuale (con item precedenti). JToolBar: barra degli strumenti. JOptionPane, JPanel, JScrollPane, JTextPane, JEditorPane, JSplitPane, JTabbedPane, JDesktopPane, JLayeredPane, JInternalFrame: – contengono e organizzano altri JComponent con differenti scopi. JFrame, JDialog, JFileChooser, JColorChooser: – finestre, finestre di dialogo, finestre di dialogo preconfezionate: – JFileChooser fc = new JFileChooser(); – if (fc. showOpenDialog(“?”)==JFileChooser.APPROVE_OPTION) { • …chooser.getSelectedFile()…; © 2010 - CEFRIEL AWT/Swing thread Chi disegna? Chi invoca gli handler? – un thread apposito che esegue il classico “main loop”; – effettua (tra le altre) le seguenti operazioni: – estrae gli eventi dalla coda (java.awt.EventQueue); – invoca i listener degli eventi nell’ordine di registrazione; – invoca le funzionalità di ricalcolo del layout sulle componenti invalidate (tramite metodo invalidate); – produce un Graphics e lo utilizza per richiedere il disegno delle componenti di alto livello (che gerarchicamente invocano il disegno di quelle che contengono, composite pattern). Invoco una operazione e non avviene! – le modifiche dell’interfaccia grafica devono avvenire nel thread di AWT, quindi in un listener o tramite: • EventQueue.invokeLater( new Runnable() { public void run() { /* operazione */ } }); © 2010 - CEFRIEL