Abstract Windowing Toolkit Il package AWT permette di gestire l’interfaccia grafica con l’utente. Fornisce le seguenti funzionalità: ¯ un insieme completo di componenti per la creazione di interfacce utente (UI), che include finestre, menu, bottoni, checkbox, scrollbar e liste ¯ supporto per “containers”, che contengono altri contenitori o elementi UI ¯ gestione degli eventi di sistema ed eventi generati dagli utenti su parti dell’UI ¯ meccanismi per disporre i componenti in modo da consentire la progettazione di UI indipendente dalla piattaforma Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 1 JAVA Gestione delle finestre Il sistema a finestre dell’AWT si basa sull’annidamento di componenti elementari, a partire dalle finestre esterne fino a raggiungere i componenti (di norma più semplici) interne. µ Si definisce una gerarchia di componenti che determina la disposizione degli elementi sullo schermo e l’ordine in cui sono visualizzati. Le componenti più importanti sono: ¯ Container: sono componenti generiche che contengono al loro interno altre componenti. Le applet sono una sottoclasse dei panel (contenitori rappresentabili sullo schermo) che sono a loro volta una sottoclasse dei container. ¯ Canvas: sono aree dedicate alla rappresentazione di immagini. ¯ Componenti di interfaccia con l’utente: bottone, lista, menu popup, checkbox, text field,label. ¯ Elementi per la costruzione delle finestre: frame, menubar, dialog window. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 2 JAVA La gerarchia delle classi all’interno dell’AWT Component Canvas Container Panel Applet TextCompon Window Frame Button TextField Dialog Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 3 JAVA Gestione delle componenti elementari di interfaccia verso l’utente La procedura per l’inclusione di una componente in un contenitore è indipendente dalla componente considerata e consiste in 1. creazione della componente elementare 2. inserimento nel contenitore che la contiene public void init() { Button b = new Button("OK"): add(b): } ¯ Il posizionamento della componente nel contenitore dipende dalla definizione della struttura (layout) del contenitore. ¯ Il layout di default è FlowLayout con allineamento centrato. Gli oggetti sono posizionati uno dopo l’altro, da sinistra a destra, riga per riga. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 4 JAVA Etichette Un’etichetta è una stringa di testo senza azioni associate. Per creare un’etichetta, si usano i costruttori: ¯ Label(); crea etichetta vuota, allineata a sinistra ¯ Label(String); crea etichetta con testo dato, allineata a sinistra ¯ Label(String, int); crea etichetta con testo dato, allineata secondo quanto specificato nel secondo parametro (Label.LEFT, Label.RIGHT, Label.CENTER). Il font è determinato dal font associato al contenitore mediante il metodo setFont(). Metodi attivabili su una etichetta: getText(), setText(String), getAlignement(), setAlignement(int). Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 5 JAVA Bottoni Un bottone è un componente che innesca una azione a seguito di una pressione da parte dell’utente, ad esempio mediante il mouse. Un bottone è creato mediante i costruttori: ¯ Button(); crea un bottone senza testo (senza etichetta) ¯ Button(String); crea un bottone con un’etichetta contenente il testo dato Per leggere o modificare l’etichetta di un bottone si utilizzano i metodi getLabel(), setLabel(String). Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 6 JAVA Checkbox e radiobutton Sono componenti caratterizzate da due stati. Permettono di selezionare o fornire opzioni mediante due modalità: ¯ esclusiva µ radiobutton (o checkbox group) ¯ non esclusiva µ checkbox Per creare una checkbox si utilizzano i metodi: ¯ Checkbox(); crea checkbox vuota ¯ Checkbox(String); crea checkbox con etichetta data ¯ Checkbox(String, boolean); crea checkbox con etichetta data, selezionata oppure non selezionata a seconda del valore del parametro booleano (rispettivamente true o false) Metodi attivabili su una checkbox: ¯ getLabel(), setLabel(String): permettono di leggere o modificare l’etichetta ¯ getState(), setState(boolean): permettono di leggere o modificare lo stato Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 7 JAVA Radiobutton Per creare un radiobutton 1. è necessario creare un gruppo di radiobutton con il metodo CheckboxGroup(). Tale metodo ritorna un oggetto di tipo CheckboxGroup. 2. Si crea la checkbox singola, passando come parametro al metodo Checkbox(String, boolean, CheckboxGroup) l’oggetto CheckboxGroup. I metodi attivabili su un radiobutton sono: ¯ getLabel(), setLabel(String) ¯ getState(), setState(boolean) ¯ getCheckboxGroup(), setCheckboxGroup(CheckboxGroup): permettono di leggere o modificare il gruppo di una checkbox ¯ getCurrent(), setCurrent(Checkbox): permettono di leggere o impostare la selezione corrente Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 8 JAVA Menu I menu detti pop-up o pull-down consentono la scelta di un elemento da una lista. Per creare un menu 1. si crea una istanza della classe Choice 2. si utilizza il metodo add() per aggiungere elementi alla lista nell’ordine in cui devono apparire Esempio: Choice c = new Choice(): c.add("Mele"): c.add("Pere"): c.add("Albicocche"): c.add("Mirtilli"): add(c); µ I menu permettono di selezionare un solo elemento. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 9 JAVA Menu I metodi attivabili su un menu sono: ¯ add(String): permette di aggiungere nuovi elementi ¯ getItem(int): restituisce la stringa associata all’elemento la cui posizione è passata come parametro (0 corrisponde al primo elemento) ¯ getItemCount(): restituisce il numero di elementi del menu ¯ getSelectedIndex(), getSelectedItem(): restituisce la posizione o la stringa associata all’elemento attualmente selezionato ¯ select(int), select(String): seleziona l’elemento in posizione data o associato alla stringa data Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 10 JAVA Text Field I campi testo permettono l’introduzione di stringhe di testo da parte dell’utente. Per creare un text field si usano i costruttori: ¯ TextField(), TextField (int); creano un textfield con ampiezza nulla oppure ampiezza data ¯ TextField (String), TextField (String, int); creano un textfield contenente la stringa data I text field hanno dimensione limitata e sono adatti per introdurre brevi stringhe di una sola linea. Sono normalmente accompagnati da etichette esplicative. add(new Label("Enter your Name")); add(new TextField("your name here",45)); add(new Label("Enter your phone number")); add(new TextField(12)); add(new Label("Enter your password")); TextField t = new TextField(20); t.setEchoChar(’*’); // Java impedisco echo dei caratteri add(t); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 11 JAVA Text Field I metodi attivabili su un textfield sono: ¯ getText(), setText(String); legge o modifica il contenuto del text field ¯ getColumns(); restituisce l’ampiezza del text field ¯ select(int, int), selectAll(); seleziona il testo tra le due posizioni indicate (inizio dalla posizione 0) oppure tutto il testo specificato ¯ isEditable(); ritorna true se il testo è modificabile, false altrimenti ¯ setEditable(boolean); abilita o disabilita la possibilità di modificare il testo (default è true) ¯ setEchoChar(char); imposta il carattere di mascheratura del testo ¯ getEchoChar(); restituisce il carattere utilizzato per mascherare il testo ¯ echoCharIsSet(); permette di verificare se è stato impostato un carattere di mascheratura del testo Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 12 JAVA Panels Il posizionamento degli oggetti basato su coordinate assolute in pixel può dare risultati molto diversi su schermi diversi. µ il posizionamento degli oggetti è basato su – layout del panel che contiene gli oggetti – ordine con cui tali oggetti sono creati nel panel I cinque layout di base sono: FlowLayout, GridLayout, BorderLayout, CardLayout, GridBagLayout. Durante l’inizializzazione del panel, si seleziona il layout voluto chiamando il metodo setLayout(): public void init() { this.setLayout(new FlowLayout()); } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 13 JAVA Panels: tipi di layout Il FlowLayout è il layout più elementare: gli oggetti sono posizionati per righe uno dopo l’altro, da sinistra a destra e dall’alto in basso. ¯ l’allineamento di ogni riga è centrato µ è possibile specificare l’allineamento a destra o a sinistra con SetLayout(new FlowLayout(FlowLayout.LEFT)). ¯ la distanza tra gli elementi è 3 pixel µ è possibile specificare una distanza diversa con SetLayout(new FlowLayout(FlowLayout.LEFT), 10, 10). Il GridLayout permette di dividere l’area del panel in righe e colonne. Ogni cella del layout contiene un componente. setLayout(new GridLayout(3,3)); Oltre al numero di righe e colonne, è possibile specificare tra i parametri del metodo GridLayout() lo spazio in orizzontale e verticale tra righe e colonne. setLayout(new GridLayout(3,3,10,15)); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 14 JAVA Panels: tipi di layout Il BorderLayout divide in cinque zone l’area del panel. ¯ Gli oggetti sono posizionati a nord, sud, est e ovest. ¯ Lo spazio occupato dall’area centrale è quello lasciato libero dalle altre quattro aree, dimensionate opportunamente per accogliere i componenti. setLayout(new BorderLayout(10, 10)); // creo spazio tra le aree add("North", new TextField("Title", 50)); Il CardLayout crea tante schede (aree) sovrapposte, stile folder Macintosh. ¯ ogni scheda è un contenitore (pannello) con un proprio layout setLayout(new CardLayout()); Panel one = new Panel(); add ("first", one); Panel two = new Panel(); add ("second", second); Panel three = new Panel(); add ("third", three); // navigazione show(this,"second"); show(this,"third"); previous(this); first(this); // mostra la scheda con // etichetta "second" // mostra la scheda precedente //mostra la prima scheda Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 15 JAVA GridBagLayout ¯ Le componenti sono disposti in una griglia ¯ È possibile controllare – spazio tra le singole celle della griglia – proporzioni tra le righe e le colonne – disposizione delle componenti nelle celle ¯ Una componente può occupare più celle (ma non viceversa) ¯ Si utilizzano due classi: – GridBagLayout fornisce il gestore di layout – GridBagConstraints definisce le proprietà di ogni componente della griglia (posizione, dimensioni, allineamento, . . . ) Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 16 JAVA Definizione di un GridBagLayout 1. Progettazione della griglia (eventualmente con uno schizzo su carta) ¯ indicare le coordinate di ciascuna cella esplicitamente 2. Creazione di un oggetto GridBagLayout, che deve essere definito come layout corrente GridBagLayout gb = new GridBagLayout(); setLayout(gb); 3. Creazione di un oggetto GridBagConstraints per definire le proprietà delle componenti GridBagConstraints gbc = new GridBagConstraints(); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 17 JAVA Definizione di un GridBagLayout 4. Per tutte le componenti da inserire nella griglia: – definire le proprietà della componente – comunicare le proprietà al gestore di layout – aggiungere la componente al pannello Button b = new Button("OK"); // definizione delle proprieta‘ gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 1; gbc.gridheight = 1; gbc.weightx = 30; gbc.weighty = 30; gbc.fill = GridBagConstraints.NONE; gbc.anchor = GridBagConstraints.CENTER; // comunicazione al layout gb.setConstraints(b,gbc); // aggiunta della componente add(b); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 18 JAVA Proprietà di una componente ¯ gridx, gridy: coordinate della cella (se la componente occupa più celle, si specifica la cella corrispondente all’angolo in alto a sinistra) ¯ gridwidth, gridheight: numero di celle occupate dal componente (colonne per gridwidth, righe per gridheight) ¯ weightx, weighty: frazione (proporzione) dello spazio totale (in x e y) occupate dalla cella – vale zero se le proporzioni sono impostate altrove; indica di occupare tutto spazio disponibile per la cella ¯ fill: determina la direzione in cui si estende la componente. NONE (default): visualizza la componente nella dimensione minima BOTH: la componente si allarga fino a riempire la cella in entrambe le direzioni HORIZONTAL: la componente si allarga in orizzontale VERTICAL: la componente si allarga in verticale ¯ anchor: posizione della componente nella cella. Valori: CENTER (default), NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST. ¯ ipadx, ipady: spazio intorno alla componente (in x e y) Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 19 JAVA La applet UserName import java.awt.*; public class UserName extends java.applet.Applet { constraints.fill = GridBagConstraints.HORIZONTAL; TextField tfname = new TextField(); gb.setConstraints(tfname,constraints); add(tfname); void buildConstraints(GridBagConstraints gbc, int gx, int gy, int gw, int gh, int wx, int wy) { gbc.gridx = gx; gbc.gridy = gy; gbc.gridwidth = gw; gbc.gridheight = gh; gbc.weightx = wx; gbc.weighty = wy; } // Password label buildConstraints(constraints, 0, 1, 1, 1, 0, 40); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label label2 = new Label("Password:",Label.LEFT); gb.setConstraints(label2,constraints); add(label2); // Password text field buildConstraints(constraints, 1, 1, 1, 1, 0, 0); constraints.fill = GridBagConstraints.HORIZONTAL; TextField tfpass = new TextField(); tfpass.setEchoChar(’*’); gb.setConstraints(tfpass,constraints); add(tfpass); public void init() { GridBagLayout gb = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setLayout(gb); // Username label buildConstraints(constraints, 0, 0, 1, 1, 10, 40); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.EAST; Label label1 = new Label("Username:",Label.LEFT); gb.setConstraints(label1,constraints); add(label1); // Username text field buildConstraints(constraints, 1, 0, 1, 1, 90, 0); // OK button buildConstraints(constraints, 0, 2, 2, 1, 0, 20); constraints.fill = GridBagConstraints.NONE; constraints.anchor = GridBagConstraints.CENTER; Button okb = new Button("OK"); gb.setConstraints(okb,constraints); add(okb); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 20 JAVA Operazioni senza mouse È possibile selezionare per l’input le componenti dell’interfaccia utente senza utilizzare il mouse. ¯ La componente selezionata è contrassegnata visivamente ¯ Quando una componente è attivata, è possibile utilizzare i tasti che essa riconosce per eseguire operazioni (i tasti accettati dipendono dalla piattaforma) ¯ Per spostare la selezione si utilizzano i tasti tab (in avanti) e shift tab (indietro) – l’ordine di selezione dipende dall’ordine di inserimento delle componenti nel contenitore (metodo add()) ¯ Una componente può richiedere esplicitamente la selezione con il metodo requestFocus(), definito nella classe Component Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 21 JAVA Eventi dell’interfaccia utente Le componenti dell’interfaccia utente generano eventi con un livello di astrazione superiore agli eventi del mouse e della tastiera: ¯ Azioni: indicano che la componente è stata attivata (esempio: pressione di un bottone) ¯ Eventi di selezione e deselezione in un elenco: sono generati quando si seleziona una checkbox o una voce di menù ¯ Eventi di selezione o deselezione per l’input: generati da qualsiasi componente (tranne le etichette) quando la componente è selezionata con il mouse o con il tasto tab Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 22 JAVA Gestione eventi dell’interfaccia utente Ogni componente genera un tipo particolare di evento, detto azione: ¯ i bottoni, le checkbox, i radiobutton creano azioni quando sono selezionati; ¯ i menu creano un’azione (con argomento l’elemento selezionato) quando si seleziona un elemento; ¯ i text field creano un’azione quando si preme sulla tastiera il tasto return. Si possono ottenere ulteriori informazioni su un evento esaminando l’oggetto descrittore dell’evento. ¯ è utile il metodo getSource(), che restituisce la componente che ha generato l’evento public void actionPerformed(ActionEvent e) { Button theSource = e.getSource(); if (theSource.getLabel().equals("OK")) { // gestione OK } else if (theSource.getLabel().equals("Cancel")) { // gestione Cancel } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 23 JAVA Gestione eventi dell’interfaccia utente ¯ Gli eventi dell’interfaccia utente sono divisi in classi diverse ¯ Solo le interfacce ContainerListener e FocusListener dispongono di adattatori (ContainerAdapter e FocusAdapter) Interfaccia ActionListener ItemListener Eventi Azione Selezione da elenco (e deselezione) FocusListener Selezione per input Deselezione per input TextListener Testo modificato ContainerListener Componente aggiunta Componente rimossa Metodi public void actionPerformed(ActionEvent e) public void itemStateChanged(ItemEvent e) public void focusGained(FocusEvent e) public void focusLost(FocusEvent e) public void textValueChanged(TextEvent e) public void componentAdded(ContainerEvent e) public void componentRemoved(ContainerEvent e) ¯ Oltre alla azioni, al’interfaccia utente sono associati eventi particolari – Testo modificato: generato quando è modificato il testo di un text field – Componente aggiunta: generato quando si aggiunge una componente a un contenitore (anche applet) – Componente rimossa: generato quando si rimuove una componente da un contenitore Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 24 JAVA Registrazione degli ascoltatori ¯ Sono disponibili i metodi addActionListener(), addItemListener(), addFocusListener(), addTextListener(), addContainerListener(). ¯ È necessario registrare l’ascoltatore appropriato per ogni componente che deve gestire un evento. public void init() { Button okb = new Button("OK"); OKButtonAction ok = new OKButtonAction(); okb.addActionListener(ok); Button cb = new Button("Cancel"); CButtonAction c = new CButtonAction(); cb.addActionListener(c); add(okb); add(cb); } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 25 JAVA Un esempio di gestione di azioni import java.awt.*; whiteButton = new Button("White"); bh = new ButtonHandler(this,Color.white); whiteButton.addActionListener(bh); add(whiteButton); public class ButtonActionsTest extends java.applet.Applet { Button redButton,blueButton, greenButton,whiteButton; } } public void init() { ButtonHandler bh; //-------------------------------- setBackground(Color.white); setLayout(new FlowLayout(FlowLayout.CENTER, 10,10)); redButton = new Button("Red"); bh = new ButtonHandler(this,Color.red); redButton.addActionListener(bh); add(redButton); blueButton = new Button("Blue"); bh = new ButtonHandler(this,Color.blue); blueButton.addActionListener(bh); add(blueButton); greenButton = new Button("Green"); bh = new ButtonHandler(this,Color.green); greenButton.addActionListener(bh); add(greenButton); import java.awt.*; import java.awt.event.*; public class ButtonHandler implements ActionListener { Color theColor; ButtonActionsTest theApplet; ButtonHandler(ButtonActionsTest a, Color c) { theApplet = a; theColor = c; } public void actionPerformed(ActionEvent e) { theApplet.setBackground(theColor); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 26 JAVA Annidamento di panels Per utilizzare caratteristiche grafiche diverse (layout diversi, oppure font diversi, . . . ) in aree diverse della stessa applet, si creano panel diversi all’interno della applet. Per creare più panel in una applet (a sua volta una sottoclasse della classe panel), è sufficiente aggiungere nuovi panel al panel contenitore, nello stesso modo in cui si aggiungono altri oggetti. setLayout(new GridLayout(1,2,10,10); Panel panel1 = new Panel(); Panel panel2 = new Panel(); add(panel1); add(panel2); panel1.setLayout(newFlowLayout()); panel1.add(new Button("Up"); panel1.add(new Button("Down"); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 27 JAVA Text Area Il componente TextArea permette una gestione più completa dei campi testo rispetto al componente TextField. Permette di specificare il testo su più linee, gestendo se necessario lo scrolling del testo in modo automatico. I metodi costruttori sono: ¯ TextArea(); area di dimensione nulla ¯ TextArea(int, int); area con dimensioni specificate (numero di righe e colonne in caratteri) ¯ TextArea(String); area di dimensione nulla inizializzata con il testo specificato ¯ TextArea(String, int, int); area con dimensioni e testo di inizializzazione specificati ¯ TextArea(String,int,int,int); area con dimensioni e testo di inizializzazione specificati. L’ultimo parametro descrive lo stato delle scrollbar: TextArea.SCROLLBARS BOTH (default): visualizza scrollbar orizzontale e verticale TextArea.SCROLLBARS HORIZONTAL ONLY: visualizza solo scrollbar orizzontale TextArea.SCROLLBARS VERTICAL ONLY: visualizza solo scrollbar verticale TextArea.SCROLLBARS NONE non visualizza scrollbar Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 28 JAVA Text Area Oltre ai numerosi metodi applicabili ai Text Field, sono disponibili: ¯ getColumns(), getRows(): ritornano il numero di colonne (in caratteri) e di righe della text area ¯ insert(String, int): inserisce il testo specificato nella posizione data ¯ replace(String, int, int): sostituisce il testo tra le posizioni specificate con la nuova stringa Le Text Area generano gli stessi eventi dei Text Field: ¯ eventi di selezione e deselezione ¯ eventi di modifica del testo Per gestire gli eventi di selezione e deselezione occorre implementare dei metodi focusGained() e focusLost(), realizzando interfaccia FocusListener, oppure estendere la classe FocusAdapter(). Per gestire gli eventi di modifica del testo si implementa l’interfaccia TextListener, che contiene il metodo textValueChanged(). Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 29 JAVA Liste a scorrimento Sono costituite da un elenco di elementi, selezionabili o uno alla volta (exclusive) oppure con scelta multipla (nonexclusive). µ se il numero di elementi è maggiore del numero di elementi visualizzabili, una barra di scorrimento è aggiunta in modo automatico I metodi costruttori sono: ¯ List(): crea una lista che consente la selezione di un solo elemento per volta ¯ List(int): crea una lista con il numero specificato di elementi visibili ¯ List(int,boolean): crea una lista con il numero specificato di elementi e l’abilitazione (se il secondo parametro è true) della selezione multipla. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 30 JAVA Liste a scorrimento Dopo aver creato un oggetto List, si possono aggiungere gli elementi con il metodo add(). List lst = new List(5, true); // 5 linee visibili // abilito selezione multipla lst.add("Luca"); lst.add("Andrea"); lst.add("Elena"); I metodi applicabili sono: ¯ getItemCount(), getItem(int), getSelectedIndex(), getSelectedItem(), select(int), select(String) con lo stesso significato dei menu. ¯ getSelectedIndexes(), getSelectedItems() restituiscono un array di posizioni o di stringhe contenente tutti gli elementi selezionati. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 31 JAVA Liste a scorrimento Le liste a scorrimento generano i seguenti eventi: ¯ doppio click su un elemento (evento di azione) ¯ selezione e deselezione di un elemento Per gestire il doppio click si implementa il metodo actionPerformed() nell’interfaccia ActionListener Per gestire la selezione/deselezione si implementa il metodo itemStateChanged(), nell’interfaccia ItemListener. La classe ItemEvent contiene i metodi getItem(), che restituisce l’elemento che ha generato l’evento, e getStateChange() che descrive se è stato selezionato o deselezionato Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 32 JAVA Scrollbar È possibile creare barre di scorrimento autonome, non gestite automaticamente come nelle liste a scorrimento o nelle text area. I metodi costruttori sono ¯ Scrollbar(); crea una barra a scorrimento verticale, con campo di valori minimo e massimo rispettivamente 0e0 ¯ Scrollbar(int), crea barra di scorrimento con orientamento specificato (Scrollbar.HORIZONTAL oppure Scrollbar.VERTICAL) ¯ Scrollbar(int, int, int, int, int); crea barra di scorrimento con orientamento, posizione iniziale, ampiezza del cursore, valore minimo e massimo della barra di scorrimento specificati. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 33 JAVA Scrollbar I metodi applicabili sono: ¯ getMaximum(), getMinimum(), getOrientation(): restituiscono rispettivamente il valore minimo o massimo e l’orientamento della barra ¯ getValue(), setValue(): restituisce o imposta il valore corrente della barra ¯ getUnitIncrement() e setUnitIncrement(int): restituisce o imposta l’incremento utilizzato per lo scorrimento quando sono selezionate le estremità della barra (default 1) ¯ getBlockIncrement() e setBlockIncrement(int): restituisce o imposta l’incremento utilizzato per lo scorrimento quando è selezionata la parte centrale della barra (default 10) Le barre di scorrimento generano numerosi eventi per descrivere lo spostamento della barra. Per gestire gli eventi si implementa il metodo adjustmentValueChanged(), nell’interfaccia AdjustmentListener. La classe AdjustmentEvent contiene il metodo getAdjustmentType(), che descrive il tipo di modifica. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 34 JAVA Scrollbar: esempio import java.awt.*; import java.awt.event.*; public class ScrollbarTest extends java.applet.Applet implements AdjustmentListener { Label l; public void init() { setLayout(new GridLayout(1,2)); l = new Label("1",Label.CENTER); add(l); Scrollbar sb = new Scrollbar(Scrollbar.HORIZONTAL,0,0,1,100); sb.addAdjustmentListener(this); add(sb); } public void adjustmentValueChanged(AdjustmentEvent e) { int v = ((Scrollbar)e.getSource()).getValue(); l.setText(String.valueOf(v)); repaint(): // Non strettamente necessario } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 35 JAVA ScrollPane Gli Scroll Pane (pannelli a scorrimento) sono contenitori all’interno dei quali si può definire una sola componente: ¯ se la componente è più grande del panel che la contiene, il panel dispone di scrollbar, che permettono di spostare una “finestra mobile” sulla componente, in modo da poterne visualizzare tutte le parti ¯ lo scorrimento è gestito dall’AWT I metodi costruttori sono: ¯ ScrollPane(); crea un panel in cui le scrollbar sono aggiunte automaticamente se la componente interna è più grande del panel ¯ ScrollPane(int); crea un panel in cui lo stato delle scrollbar è determinato dall’argomento, che assume i valori ScrollPane.SCROLLBARS ALWAYS: le scrollbar sono sempre presenti ScrollPane.SCROLLBARS AS NEEDED: le scrollbar sono visualizzate quando è necessario per vedere in modo completo la componente figlia ScrollPane.SCROLLBARS NEVER: le scrollbar non sono mai presenti Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 36 JAVA ScrollPane Per creare uno Scroll Pane: ScrollPane scroller = new ScrollPane(); Panel panel1 = new Panel(); scroller.add(panel1); add(scroller); I metodi applicabili sono: ¯ getScrollPosition(): restituisce un oggetto Point che rappresenta, all’interno della componente figlia, la posizione dell’angolo in alto a sinistra dello Scroll Pane ¯ setScrollPosition(int,int), setScrollPosition(Point): scorre il panel fino alla posizione specificata ¯ getHAdjustable(), getVAdjustable(): restituisce un oggetto Adjustable che rappresenta lo stato della scrollbar orizzontale o verticale; per modificare le caratteristiche delle scrollbar si utilizzano i metodi delle scrollbar definiti nell’interfaccia Adjustable ¯ getViewportSize(): restituisce un oggetto Dimension che rappresenta la dimensione della finestra di visualizzazione dello Scroll Pane Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 37 JAVA Cursori Il cursore è l’immagine che raffigura il puntatore del mouse (freccia, mano, clessidra, . . . ). È possibile aggiungere un cursore a qualsiasi componente e modificarlo in qualsiasi momento. Il metodo creatore è: ¯ Cursor(int): crea un cursore, il cui tipo è determinato dal parametro, che può assumere i seguenti valori: – Cursor.DEFAULT CURSOR: cursore di default (di solito la freccia) – Cursor.CROSSHAIR CURSOR: cursore a forma di segno più – Cursor.HAND CURSOR: cursore a forma di mano – Cursor.TEXT CURSOR cursore a I per l’inserimento del testo – Cursor.WAIT CURSOR: indica che è in corso un’operazione lunga (clessidra o orologio) – Cursor.MOVE CURSOR: indica che è in corso uno spostamento di un oggetto – Cursor.N RESIZE CURSOR, Cursor.NE RESIZE CURSOR, Cursor.E RESIZE CURSOR, Cursor.SE RESIZE CURSOR, Cursor.S RESIZE CURSOR, Cursor.SW RESIZE CURSOR, Cursor.W RESIZE CURSOR, Cursor.NW RESIZE CURSOR: indicano che è in corso il ridimensionamento di una finestra Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 38 JAVA Cursori Metodi disponibili: ¯ setCursor(Cursor): imposta il cursore ¯ getCursor(): restituisce il cursore corrente ¯ getPredefinedCursor(): restituisce il tipo di cursore predefinito Per creare un cursore: Cursor cur = new Cursor(Cursor.HAND_CURSOR); setCursor(cur); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 39 JAVA Componenti La classe Component è l’origine della gerarchia dell’AWT. Dispone di metodi che consentono di modificare l’aspetto di qualsiasi componente (panel, applet, finestre, ecc.): ¯ getBackground(), getForeground(): restituisce un oggetto Color che rappresenta il colore dello sfondo o del primo piano della componente ¯ setBackground(Color), setForeground(Color): imposta il colore dello sfondo o del primo piano della componente ¯ getFont(); setFont(Font): restituisce il font corrente (in un oggetto Font); imposta il font della componente ¯ getSize(): restituisce un oggetto Dimension che rappresenta la dimensione della componente (largezza e altezza sono ottenuti dalle variabili di istanza width e height) ¯ getMinimumSize(): restituisce in un oggetto Dimension la dimensione minima della componente (utilizzato dai gestori di layout). Deve essere ridefinito per componenti personalizzate. ¯ getPreferredSize(): restituisce in un oggetto Dimension la dimensione “ideale” della componente ¯ setSize(Dimension): porta la dimensione della componente a quella passata come parametro Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 40 JAVA Componenti ¯ contains(int,int): restituisce true se le coordinate x,y specificate sono all’interno della componente ¯ setVisible(boolean): con parametro false nasconde la componente, mentre con parametro true la rende visibile ¯ isVisible(): restituisce true se la componente è visibile, false se è nascosta ¯ setEnabled(boolean): con parametro false disabilita (interrompe la generazione di eventi) la componente, mentre con parametro true la (ri)abilita. ¯ isEnabled(): restituisce true se la componente è abilitata, false se è disabilitata Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 41 JAVA Un esempio completo: ColorTest (1/2) import java.awt.*; public class ColorTest extends java.applet.Applet { ColorControls RGBcontrols, HSBcontrols; Canvas swatch; public void init() { setLayout(new GridLayout(1,3,10,10)); swatch = new Canvas(); // L’area in cui presentare il colore swatch.setBackground(Color.black); // Il pannello di controllo RGBcontrols = new ColorControls(this, "Red", "Green", "Blue"); HSBcontrols = new ColorControls(this, "Hue", "Saturation", "Brightness"); add(swatch); add(RGBcontrols); add(HSBcontrols); } public Insets getInsets() { return new Insets(10,10,10,10); } void update(ColorControls in) { Color c; int v1 = Integer.parseInt(in.f1.getText()); int v2 = Integer.parseInt(in.f2.getText()); int v3 = Integer.parseInt(in.f3.getText()); if (in == RGBcontrols) { // converto a RGB c = new Color(v1,v2, v3); float[] HSB = Color.RGBtoHSB(c.getRed(),c.getGreen(), c.getBlue(), (new float[3])); HSB[0] *= 360; HSB[1] *= 100; HSB[2] *= 100; HSBcontrols.f1.setText(String.valueOf((int)HSB[0])); HSBcontrols.f2.setText(String.valueOf((int)HSB[1])); HSBcontrols.f3.setText(String.valueOf((int)HSB[2])); } else { // converto a HSB c=Color.getHSBColor((float)v1/360, (float)v2/100, (float)v3/100); RGBcontrols.f1.setText(String.valueOf(c.getRed())); RGBcontrols.f2.setText(String.valueOf(c.getGreen())); RGBcontrols.f3.setText(String.valueOf(c.getBlue())); } swatch.setBackground(c); swatch.repaint(); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 42 JAVA Un esempio completo: ColorTest (2/2) import java.awt.*; import java.awt.events.*; add(new Label(l3, Label.RIGHT)); f3.addFocusListener(this); f3.addActionListener(this); add(f3); class ColorControls extends Panel implements FocusListener,ActionListener { TextField f1, f2, f3; ColorTest outerparent; // permette // la notifica di aggiornamento // schermo alla applet } public Insets getInsets() { return new Insets(10,10,0,0); } ColorControls(ColorTest target, String l1, String l2, String l3) { public void focusGained(FocusEvent e) {} public void focusLost(FocusEvent e) { outerparent.update(this); } outerparent = target; setLayout(new GridLayout(3,2,10,10)); f1 = new TextField("0"); f2 = new TextField("0"); f3 = new TextField("0"); public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof TextField) outerparent.update(this); } add(new Label(l1, Label.RIGHT)); f1.addFocusListener(this); f1.addActionListener(this); add(f1); add(new Label(l2, Label.RIGHT)); f2.addFocusListener(this); f2.addActionListener(this); add(f2); } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 43 JAVA La applet ColorTest Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 44 JAVA Creazione di finestre ¯ È possibile creare finestre indipendenti dalla finestra del browser che contiene la applet oppure per applicazioni autonome. ¯ La classe Window fornisce il comportamento di base; contiene due sottoclassi – Frame per la gestione di finestre complete, con titolo, menu a barra, bordi di ridimensionamento, caselle di chiusura – Dialog per la gestione delle dialog box, finestre più semplici di tipo temporaneo utilizzate per visualizzare messaggi e richiedere informazioni specifiche ¯ Per creare nuove finestre si definiscono sottoclassi di Frame e Dialog Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 45 JAVA Frame Per creare un frame si utilizzano i metodi costruttori: ¯ Frame(): crea un frame senza titolo ¯ Frame(String): crea un frame con il titolo specificato I frame sono contenitori: ¯ è possibile aggiungere componenti (come per i panel) mediante il metodo add() ¯ il layout di default è il BorderLayout win = new Frame("La mia finestra"); win.setLayout(new BorderLayout(10,20); win.add ("North", new Button("Start")); win.add ("Center", new Button("Move")); win.setSize(100, 200); win.show(); // modifico dimensione frame // (largo 100 pixel, alto 200) // mostra la finestra (inizialmente invisibile!) La finestra può avere una dimensione diversa a seconda della piattaforma utilizzata µ al posto di setSize() si può utilizzare il metodo pack(), che crea una finestra con la dimensione minima possibile Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 46 JAVA Finestre di dialogo ¯ Le finestre di dialogo sono finestre temporanee. ¯ Le finestre di dialogo modali impediscono di fornire input a qualsiasi altra finestra dell’applicazione (o applet) fino a quando non vengono chiuse. ¯ Sono disponibili due classi per definire finestre di dialogo: Dialog che fornisce finestre di dialogo generiche e FileDialog che genera finestre specifiche per l’apertura e chiusura di file µ le finestre di dialogo possono essere usate solo se associate ad altre finestre (non a applet!) µ le finestre di dialogo sono, a tutti gli effetti, panel, a cui si possono quindi aggiungere altri componenti Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 47 JAVA Finestre di dialogo I metodi costruttori sono: ¯ Dialog(Frame): crea una finestra di dialogo inizialmente invisibile associata al frame passato come argomento ¯ Dialog(Frame,boolean): crea una finestra di dialogo inizialmente invisibile associata al frame passato come argomento; la finestra è modale se il secondo argomento è true ¯ Dialog(Frame,String): crea una finestra di dialogo non modale inizialmente invisibile con il titolo specificato ¯ Dialog(Frame,String,boolean): crea una finestra di dialogo inizialmente invisibile con il titolo specificato; la finestra è modale se il secondo argomento è true dl = new Dialog(this, "Enter Text", true); dl.setLayout(new GridLayout(2, 1, 30, 30)); tf = new TextField("Scritta di prova", 20); dl.add(tf); dl.add(new Button("OK")); dl.setSize(150,75); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 48 JAVA Finestre di dialogo (1/3) import java.awt.*; public class PopupWindow extends java.applet.Applet { MyFrame window; Button open, close; public void init() { AppletAction handleButton = new AppletAction(this); open = new Button("Open Window"); open.addActionListener(handleButton); add(open); close = new Button("Close Window"); close.addActionListener(handleButton); add(close); import java.awt.*; import java.awt.event.*; public class AppletAction implements ActionListener { PopupWindow theApp; AppletAction(PopupWindow app) { theApp = app; } public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof Button) { if (e.getSource() == theApp.open) { if (!theApp.window.isShowing()) theApp.window.show(); } else if (e.getSource() == theApp.close) { if (theApp.window.isShowing()) theApp.window.hide(); } } } window = new MyFrame("A Popup Window"); window.setSize(150,150); window.show(); } } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 49 JAVA Finestre di dialogo (2/3) import java.awt.*; import java.awt.event.*; import java.awt.*; import java.awt.event.*; class MyFrame extends Frame { TextDialog td; Label l; String msg = "This is a window"; public class MyFrameAction implements ActionListener { MyFrame theWin; MyFrameAction(MyFrame win) { theWin = win; } public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof Button) theWin.td.show(); } MyFrame(String title) { super(title); setLayout(new BorderLayout()); l = new Label(msg, Label.CENTER); l.setFont(new Font("Helvetica",Font.PLAIN,12); add("Center",l); } // make dialog for this window td = new TextDialog(this, "Enter Text",true); td.setSize(150,100); // button for showing Dialog Button b = new Button("Enter Text"); b.addActionListener(new MyFrameAction(this)); add("South",b); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 50 JAVA Finestre di dialogo (3/3) import java.awt.*; import java.awt.event.*; public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof Button) { String l = ((Button)e.getSource()).getLabel(); if (l.equals("OK") { hide(); theWin.l.setText(tf.getText()); } } } class TextDialog extends Dialog implements ActionListener { TextField tf; MyFrame theWin; TextDialog(MyFrame parent, String title, boolean modal) { super((Frame)parent,title,modal); theWin = parent; setLayout(new BorderLayout(10,10)); setBackground(Color.white); tf = new TextField(theWin.msg,20); add("Center",tf); Button b = new Button("OK"); b.addActionListener(this); add("South",b); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 51 JAVA Finestre di dialogo e applet Le finestre di dialogo devono essere associate a un Frame µ non possono essere associate direttamente a una applet Si può utilizzare il frame della finestra che contiene la applet (spesso è la finestra del browser). 1. Richiamando ripetutamente il metodo getParent() della classe Component, si risale fino alla finestra che contiene la applet Object anchorpoint = getParent(); while (! anchorpoint instanceof Frame)) anchorpoint = ((Component)anchorpoint).getParent(); 2. Si associa la finestra di dialogo alla finestra ottenuta: TextDialog dl = new TextDialog((Frame)anchorpoint,"Inserire testo", true); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 52 JAVA Finestre di dialogo: classe FileDialog La classe FileDialog fornisce finestre di dialogo per la gestione classica di apertura o salvataggio di file. I metodi costruttori sono: ¯ FileDialog(Frame,String); crea una finestra di dialogo di apertura di file, associata al frame specificato, con il titolo indicato. ¯ FileDialog(Frame,String,int); crea una finestra di dialogo la cui funzione è indicata dal parametro intero (FileDialog.LOAD o FileDialog.SAVE) Dopo che l’utente ha selezionato un file e chiuso la finestra, l’informazione sul file selezionato può essere ottenuta mediante i metodi ¯ getDirectory() ¯ getFile() Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 53 JAVA Eventi generati dalle finestre Le finestre generano eventi quando cambiano stato a causa di una variazione di dimensioni, di una riduzione a icona, di un passaggio in primo piano, di uno spostamento o di una chiusura, ecc. Evento Finestra aperta Finestra attivata Finestra disattivata Finestra ridotta a icona Finestra ripristinata Finestra in fase di chiusura Finestra chiusa Finestra spostata Interfaccia WindowListener WindowListener WindowListener WindowListener WindowListener WindowListener WindowListener ComponentListener Metodo public void windowOpened(WindowEvent e) public void windowActivated(WindowEvent e) public void windowDeactivated(WindowEvent e) public void windowIconified(WindowEvent e) public void windowDeiconified(WindowEvent e) public void windowClosing(WindowEvent e) public void windowClosed(WindowEvent e) public void componentMoved(ComponentEvent e) Per registrare un ascoltatore si utilizza il metodo addWindowListener(), che è disponibile solo per le classi Frame e Dialog. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 54 JAVA Menubar Sono disponibili i seguenti tipi di menu: ¯ menu fissi, contenuti in una barra dei menu disposta nella parte superiore della finestra ¯ menu a comparsa, che possono apparire in qualsiasi punto di applet o applicazioni L’AWT fornisce le seguenti classi per la gestione dei menu: MenuComponent MenuBar MenuItem Menu CheckboxMenu Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 55 JAVA Menubar Ogni finestra ha una sua barra di comandi contenente i menu. ¯ Per creare la barra di comandi MenuBar mb = new MenuBar(); win.setMenuBar(mb); // metodo definito nella classe Frame ¯ Per aggiungere menu alla barra di comandi Menu m = new Menu("File"); mb.add(m); ¯ Per specificare il menu di help Menu hm = new Menu("Help"); mb.add(hm); mb.setHelpMenu(hm); // Menu di Help a destra in fondo ¯ Per abilitare o disabilitare un menu m.enable(); m.disable(); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 56 JAVA Voci di menu È possibile definire come voci del menu ¯ voci normali, come istanze della classe MenuItem Menu m = new Menu("Tools"); m.add(new MenuItem("Info")); m.add(new MenuItem("Colors")); ¯ voci di menu a due stati (toggle), come istanze della classe CheckboxMenuItem CheckboxMenuItem coords = new CheckboxMenuItem("Mostra coordinate"); m.add(coords); ¯ sottomenu Menu sb = new Menu("Sizes"); m.add(sb); sb.add(new MenuItem("Small")); sb.add(new MenuItem("Medium")); sb.add(new MenuItem("Large")); ¯ separatori MenuItem separator = new MenuItem("-"); m.add(separator); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 57 JAVA Tasti di scelta rapida per menu A voci di menu normali e toggle si possono associare tasti di scelta rapida, che permettono di selezionare l’elemento con la tastiera anziché con il mouse. Per aggiungere un tasto di scelta rapida a una voce di menu, si crea un’istanza della classe MenuShortcut ¯ MenuShortcut(int): crea un nuovo tasto di scelta rapida associato al dato carattere (o tasto virtuale) ¯ MenuShortcut(int,boolean): crea un nuovo tasto di scelta rapida associato al dato carattere (o tasto virtuale), in cui se l’argomento boolean è true occorre premere il tasto shift insieme al tasto dato Menu e = new Menu("Edit"); e.add(new MenuItem("Cut", new MenuShortcut(’x’))); e.add(new MenuItem("Copy", new MenuShortcut(’c’))); e.add(new MenuItem("Paste", new MenuShortcut(’v’))); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 58 JAVA Azioni generate dai menu La selezione di una voce di menu genera un evento di azione µ per i gli elementi MenuItem si ridefinisce il metodo actionPerformed() dell’interfaccia ActionListener public void actionPerformed(ActionEvent e){ if (e.getSource() instanceof MenuItem) { String label = ((MenuItem)e.getSource()).getLabel(); if (label.equals("Mostra coordinate")) toggleCoords(); else if (label.equals("Fill")) fillcurrentArea(); } } µ per gli elementi CheckboxMenuItem il cambio di stato viene gestita dal metodo itemStateChanged() dell’interfaccia ItemListener. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 59 JAVA Menu a comparsa Il menu a comparsa è visualizzato in risposta ad eventi del mouse µ è possibile creare menu sensibili al contesto (alla componente sui cui è stato generato l’evento del mouse) Per creare un menu a comparsa ¯ si crea un’istanza della classe PopupMenu: PopupMenu pm = new PopupMenu("Edit"); ¯ si aggiungono le voci come nel caso di menu normali pm.add(new MenuItem("Cut")); pm.add(new MenuItem("Copy")); pm.add(new MenuItem("Paste")); ¯ si aggiunge il menu alla componente add(pm); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 60 JAVA Menu a comparsa Per mostrare un menu a comparsa ¯ si utilizza il metodo processMouseEvent() della classe Component che permette di gestire eventi di tipo generico del mouse ¯ si utilizza il metodo isPopupTrigger() della classe MouseEvent per riconoscere la richiesta di menu a comparsa ¯ si utilizza il metodo show() della classe PopupMenu per mostrare il menu public void processMouseEvent(MouseEvent e) { if (e.isPopupTrigger()) pm.show(e.getComponent(),e.getX(),e.getY()); super.processMouseEvent(e); } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 61 JAVA Esempio: finestra con menu (1/3) import java.awt.*; // define menu MenuBar mb = new MenuBar(); Menu m = new Menu("Colors"); MenuItem i = new MenuItem("Red"); i.addActionListener(ha); m.add(i); i = new MenuItem("Green"); i.addActionListener(ha); m.add(i); i = new MenuItem("Blue"); i.addActionListener(ha); m.add(i); m.add(new MenuItem("-")); CheckboxMenuItem c = new CheckboxMenuItem("Bold"); c.addItemListener(ha); m.add(c); mb.add(m); setMenuBar(mb); class MyFrame extends Frame { TextDialog td; Label l; String msg = "This is a window"; MyFrame(String title) { super(title); setLayout(new BorderLayout()); l = new Label(msg, Label.CENTER); l.setFont(new Font("Helvetica",Font.PLAIN,12)); add("Center",l); // make dialog for this window td = new TextDialog(this, "Enter Text",true); td.setSize(150,100); // button for showing Dialog Button b = new Button("Enter Text"); MyFrameAction ha = new MyFrameAction(this); b.addActionListener(ha); add("South",b); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 62 JAVA Esempio: finestra con menu (2/3) import java.awt.*; import java.awt.event.*; public class MyFrameAction implements ActionListener { MyFrame theWin; MyFrameAction(MyFrame win) { theWin = win; } public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof Button) theWin.td.show(); else if (e.getSource() instanceof MenuItem) { String label = ((MenuItem)e.getSource()).getLabel(); if (label.equals("Red")) theWin.l.setBackground(Color.red); else if (label.equals("Green")) theWin.l.setBackground(Color.green); else if (label.equals("Blue")) theWin.l.setBackground(Color.blue); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 63 JAVA Esempio: finestra con menu (3/3) public void itemStateChanged(ItemEvent e) { if (e.getSource() instanceof CheckboxMenuItem) { CheckboxMenuItem cb = (CheckboxMenuItem)e.getSource(); String label = cb.getLabel(); if (label.equals("Bold")) { if (cb.getState()) theWin.l.setFont(new Font("Helvetica", Font.BOLD, 12)); else theWin.l.setFont(new Font("Helvetica", Font.PLAIN, 12)); } } } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 64 JAVA Uso delle finestre nelle applicazioni ¯ La classe principale di un’applicazione deve essere una sottoclasse di Frame (se uso animazioni realizzo anche interfaccia Runnable) Class MyAppAWT extends Frame implements Runnable ¯ All’interno del metodo main() dell’applicazione si crea un’istanza della classe µ una finestra normale ¯ Nel metodo costruttore di MyAppAWT si impostano le caratteristiche della finestra import java.awt.* class MyAppAWT extends Frame { MyAppAWT(String title) { super(title); add(new Button("OK")); add(new Button("Cancel")); } public static void main(String args[]) { MyAppAWT a = new MyAppAWT("This is an application"); a.setSize(300,300); a.show(); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 65 JAVA Uso delle finestre nelle applicazioni ¯ Si deve gestire l’evento di chiusura della finestra: si nasconde o si distrugge la finestra e si richiama il metodo System.exit(0) per indicare al sistema che si è usciti dall’applicazione public void windowClosing(WindowEvent e) { win.hide(); win.destroy(); System.exit(0); } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 66 JAVA Swing A partire dalle versioni più recenti di Java, Sun ha incluso tra le sue librerie e distribuito un nuovo toolkit grafico, chiamato Swing. Il toolkit AWT si ha dimostrato di soffrire alcuni problemi che ne limitano la portabilità: ¯ c’è una forte dipendenza dalle capacità dei toolkit grafici del sistema operativo su cui viene eseguita la Virtual Machine Java ¯ la libreria deve quindi essere ridotta ad un denominatore comune, non potendo sfruttare tutte le possibilità dei vari sistemi ¯ differenti piattaforme soffrivano di bug diversi, per cui la soluzione di un problema su una piattaforma pu ò non corrispondere ad una corretta rappresentazione su un’altra Una soluzione è stata l’adozione da parte di Sun del toolkit Swing, precedentemente sviluppato da Netscape. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 67 JAVA Swing: caratteristiche A differenza di AWT, Swing non sfrutta direttamente il toolkit grafico del sistema che ospita la Virtual Machine: gli elementi di Swing sono “disegnati” direttamente sulla finestra. Questo produce alcuni vantaggi: ¯ Swing può offire un insieme di elementi grafici molto più ricco ¯ Swing dipende meno dalla piattaforma sottostante e quindi soffre meno di bug legati alla piattaforma ¯ Swing produce un aspetto grafico uniforme su tutte le piattaforme Ci sono naturalmente degli svantaggi nell’utilizzo di Swing: ¯ essendo le componenti “disegnate”, Swing può apparire puù lento nell’esecuzione rispetto a AWT ¯ l’utente può rimanere disorientato dall’aspetto grafico prodotto da Swing, che non corrisponde a quello a cui è abituato sul suo sistema operativo. Questo problema è superato dal fatto che Swing permette di scegliere e cambiare il “look and feel” dei componenti ¯ poiché Swing è incluso solo nelle versioni più recenti del JDK, non è possibile utilizzarlo in Applet che debbano essere eseguiti su browser che facciano uso della loro JVM invece di quella offerta dal JDK. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 68 JAVA Da AWT a Swing Gli elementi grafici offerti da Swing sono contenuti nel package javax.swing Tranne poche eccezioni, le componenti Swing hanno nomi analoghi alle componenti AWT e si riconoscono dall’uso dell’iniziale J per il nome della componente (JButton, JFrame, JDialog, JMenu, ecc.) È spesso possibile convertire un’applicazione AWT in un applicazione Swing semplicemente rinominando i vari elementi. Tale conversione non è però sempre immediata. La gestione degli eventi non cambia e rimane basata sulla registrazione degli ascoltatori Occorre ricordarsi di non usare componenti AWT e componenti Swing nella medesima applicazione perché questi ultimi potrebbero non essere disegnati correttamente. Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 69 JAVA Un esempio completo: JColorTest (1/2) import java.awt.*; import javax.swing.*; public class JColorTest extends JApplet { JColorControls RGBcontrols, HSBcontrols; JPanel swatch; public void init() { Container p = getContentPane(); p.setLayout(new GridLayout(1,3,10,10)); swatch = new JPanel(); // L’area in cui presentare il colore swatch.setBackground(Color.black); // Il pannello di controllo RGBcontrols = new JColorControls(this, "Red", "Green", "Blue"); HSBcontrols = new JColorControls(this, "Hue", "Saturation", "Brightness"); p.add(swatch); p.add(RGBcontrols); p.add(HSBcontrols); } public Insets getInsets() { return new Insets(10,10,10,10); } void update(JColorControls in) { Color c; int v1 = Integer.parseInt(in.f1.getText()); int v2 = Integer.parseInt(in.f2.getText()); int v3 = Integer.parseInt(in.f3.getText()); if (in == RGBcontrols) { // converto a RGB c = new Color(v1,v2, v3); float[] HSB = Color.RGBtoHSB(c.getRed(),c.getGreen(), c.getBlue(), (new float[3])); HSB[0] *= 360; HSB[1] *= 100; HSB[2] *= 100; HSBcontrols.f1.setText(String.valueOf((int)HSB[0])); HSBcontrols.f2.setText(String.valueOf((int)HSB[1])); HSBcontrols.f3.setText(String.valueOf((int)HSB[2])); } else { // converto a HSB c=Color.getHSBColor((float)v1/360, (float)v2/100, (float)v3/100); RGBcontrols.f1.setText(String.valueOf(c.getRed())); RGBcontrols.f2.setText(String.valueOf(c.getGreen())); RGBcontrols.f3.setText(String.valueOf(c.getBlue())); } swatch.setBackground(c); swatch.repaint(); } } Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 70 JAVA Un esempio completo: JColorTest (2/2) import java.awt.*; import java.awt.event.*; import javax.swing.*; add(new JLabel(l3, JLabel.RIGHT)); f3.addFocusListener(this); f3.addActionListener(this); add(f3); class JColorControls extends JPanel implements FocusListener,ActionListener { JTextField f1, f2, f3; JColorTest outerparent; // permette // la notifica di aggiornamento // schermo alla applet } public Insets getInsets() { return new Insets(10,10,0,0); } public void focusGained(FocusEvent e) {} JColorControls(JColorTest target, String l1, String l2, String l3) { public void focusLost(FocusEvent e) { outerparent.update(this); } outerparent = target; setLayout(new GridLayout(3,2,10,10)); public void actionPerformed(ActionEvent e) { if (e.getSource() instanceof JTextField) outerparent.update(this); } f1 = new JTextField("0"); f2 = new JTextField("0"); f3 = new JTextField("0"); } add(new JLabel(l1, JLabel.RIGHT)); f1.addFocusListener(this); f1.addActionListener(this); add(f1); add(new JLabel(l2, JLabel.RIGHT)); f2.addFocusListener(this); f2.addActionListener(this); add(f2); Elena Baralis, Andrea Bianco, Maurizio Munaf ò Politecnico di Torino JAVA AWT: ABSTRACT WINDOWING TOOLKIT – 71 JAVA JAVA