MokaByte
Numero 09 - Giugno 1997
|
|||
|
un Java Bean |
||
Daniela Ruggeri |
|
||
Si vuole dare una panoramica su cosa sia un JavaBean e quale possa essere la sua utilità. L'articolo si compone dei seguenti argomenti:
Il codice che interessa è quello relativo al bottone MioBottone:
class MioBottone extends Button{ Image imm; Image imm1; int Immagine = 1; String s; int x,y; public boolean mouseDown(Event evt, int x, int y){ Immagine = 2; repaint(); return true; } public boolean mouseUp(Event evt, int x, int y){ Immagine = 1; repaint(); return true; } public void update(Graphics g){ paint(g); } public void paint(Graphics g){ if (Immagine == 1){ g.drawImage(imm,x,y,this); enable(); } else{ g.drawImage(imm1,x,y,this); } } MioBottone(String s,int x,int y,Image imm, Image imm1){ super(s); this.s = s; this.imm = imm; this.imm1 = imm1; this.x = x; this.y = y; disable(); } }Per la costruzione del JavaBean useremo le seguenti API:
La prima cosa da fare è rendere l'oggetto serializzabile, cosa che si ottiene implementando l'interfaccia bean.io.serializable, e pubblico. Naturalmente occorerà importare anche il package relativo. Si farà anche in modo che il JavaBean faccia parte di un package. Avremo quindi:
package dany.Bottoni; import bean.io.serializable; public MioBottone extends Button implements serializablePer semplicità utilizziamo un costruttore senza parametri "public MioBottone()" e impostiamo i parametri all'interno del codice.
import java.net.URL;
import java.awt.image.*;
Il costruttore diventa quindi:
public MioBottone() { super(" Cliccare qui'"); enableEvents(AWTEvent.MOUSE_EVENT_MASK); setFont(new Font("TimesRoman",Font.BOLD, 36)); this.s = s; this.x = 5; this.y = 5; setEnabled(false); Image imm = null; Image imm1 = null; try { URL url = getClass().getResource("imma.gif"); Toolkit tk = Toolkit.getDefaultToolkit(); imm = tk.createImage((ImageProducer) url.getContent()); java.net.URL url1 = getClass().getResource("imma1.gif"); imm1 = tk.createImage((ImageProducer) url1.getContent()); } catch (Exception ex){ System.err.println("Errore di caricamento immagini"); } this.imm = imm; this.imm1 = imm1; }Poiché la gestione degli eventi è cambiata rispetto al JDK 1.0.2. (vedere articolo di Massimo Carli relativo al JDK 1.1. su ), useremo al posto dei metodi MouseDown e MouseUp il metodo processEvent(AWTEvent evt) . Il codice relativo è il seguente:
A questo punto dobbiamo inserire anche le seguenti proprietà :protected void processEvent(AWTEvent evt) { switch (evt.getID()) { case Event.MOUSE_DOWN: Immagine = 2; repaint(); super.processEvent(evt); return; case Event.MOUSE_UP: Immagine = 1; repaint(); super.processEvent(evt); return; } super.processEvent(evt); }
epublic String getValore(){ return valore; }
Dove changes è un'istanza della classe PropertyChangeSupport che è la classe usata per la gestione del cambiamento proprietà, e firePropertyChange è il metodo usato per cambiare il valore della classe. Rimangono da definire solo i metodi relativi a Posx e Posy, visto che per le prime quattro classi sono già previsti i metodi di set/get.public void setValore(String nuovovalore) { int vecchiax = x; x = nuovax; .... .... .... changes.firePropertyChange("valore", vecchiovalore, nuovovalore); }
Come ultima cosa diremo che, dovendo gestire i cambiamenti delle proprietà, abbiamo bisogno di due metodi: lo specificato metodo propertyChange dell'interfaccia PropertyChangeListener sarà chiamato ogni volta che il valore di una proprietà caricata (bound) è cambiato. Quindi abbiamo bisogno di un metodo per segnalare il cambiamento aggiungendolo nella lista apposita degli ascoltatori cambiamenti di proprietà, e di un metodo per rimuoverlo da tale lista.// Ottiene il valore della proprietà Posx public int getPosx(){ return x; } // Ottiene il valore della proprietà Posy public int getPosy(){ return y; } // Imposta il valore della proprietà Posx public void setPosx(int nuovax){ int vecchiax = x; x = nuovax; changes.firePropertyChange("Posx", new Integer(vecchiax), new Integer(nuovax)); } // Imposta il valore della proprietà Posy public void setPosy(int nuovay){ int vecchiay= y; y = nuovay; changes.firePropertyChange("Posy", new Integer(vecchiay), new Integer(nuovay)); }
public void addPropertyChangeListener(PropertyChangeListener l) { changes.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { changes.removePropertyChangeListener(l); }
Il codice
sorgente totale risulta quindi:
package dany.Bottoni; import java.awt.*; import java.net.URL; import java.awt.image.*; import java.util.*; import java.io.Serializable; import java.beans.*; import java.awt.event.*; public class MioBottone extends Button implements Serializable { private Image imm; private Image imm1; private int Immagine = 1; private String s=""; private int x,y; private PropertyChangeSupport changes = new PropertyChangeSupport(this); public void update(Graphics g) { paint(g); } public void paint(Graphics g) { if (Immagine == 1) { g.drawImage(imm,x,y,this); setEnabled(true); } else { g.drawImage(imm1,x,y,this); } } public MioBottone() { super(" Cliccare qui'"); enableEvents(AWTEvent.MOUSE_EVENT_MASK); setFont(new Font("TimesRoman",Font.BOLD, 36)); this.s = s; this.x = 5; this.y = 5; setEnabled(false); Image imm = null; Image imm1 = null; try { URL url = getClass().getResource("imma.gif"); Toolkit tk = Toolkit.getDefaultToolkit(); imm = tk.createImage((ImageProducer) url.getContent()); java.net.URL url1 = getClass().getResource("imma1.gif"); imm1 = tk.createImage((ImageProducer) url1.getContent()); } catch (Exception ex) { System.err.println("Errore di caricamento immagini"); } this.imm = imm; this.imm1 = imm1; } public void addPropertyChangeListener(PropertyChangeListener l) { changes.addPropertyChangeListener(l); } public void removePropertyChangeListener(PropertyChangeListener l) { changes.removePropertyChangeListener(l); } protected void processEvent(AWTEvent evt) { switch (evt.getID()) { case Event.MOUSE_DOWN: Immagine = 2; repaint(); super.processEvent(evt); return; case Event.MOUSE_UP: Immagine = 1; repaint(); super.processEvent(evt); return; } super.processEvent(evt); } public int getPosx() { return x; } public int getPosy() { return y; } public void setPosx(int nuovax) { int vecchiax = x; x = nuovax; changes.firePropertyChange("Posx", new Integer(vecchiax), new Integer(nuovax)); } public void setPosy(int nuovay) { int vecchiay= y; y = nuovay; changes.firePropertyChange("Posy", new Integer(vecchiay), new Integer(nuovay)); } }
Ora ci occupiamo
di rendere disponibili un minimo di informazioni su questo bean, in modo
che un qualsiasi ambiente di sviluppo possa ricavare le caratteristiche
principali interrogando appositi metodi. Lo standard per la costruzione
di un JavaBean dice che la classe che contiene questo tipo di informazioni
deve chiamarsi <nome javabean>BeanInfo.class.
Quindi creeremo
il file MioBottoneBeanInfo.java, implementazione della classe SimpleBeanInfo
fornita dalle API del bdk: tale kit fornisce un insieme di metodi per la
costruzione di un semplice JavaBean.
Inoltre, per
aggiungere proprietà al bottone, dobbiamo ridefinire il metodo getPropertyDescriptors()
che restituisce un vettore di PropertyDescriptor[] contenente le
informazioni sulle proprietà.
package dany.Bottoni; import java.beans.*; public class MioBottoneBeanInfo extends SimpleBeanInfo { public PropertyDescriptor[] getPropertyDescriptors() { try { // Definizione delle proprietà collegate al JavaBean MioBottone. PropertyDescriptor background = new PropertyDescriptor("background", MioBottone.class); PropertyDescriptor foreground = new PropertyDescriptor("foreground", MioBottone.class); PropertyDescriptor font = new PropertyDescriptor("font", MioBottone.class); PropertyDescriptor label = new PropertyDescriptor("label", MioBottone.class); PropertyDescriptor Posx = new PropertyDescriptor("Posx", MioBottone.class); PropertyDescriptor Posy = new PropertyDescriptor("Posy", MioBottone.class); // Impostazione delle proprietà "Bound". background.setBound(true); foreground.setBound(true); font.setBound(true); label.setBound(true); Posx.setBound(true); Posy.setBound(true); // Ritorno delle proprietà PropertyDescriptor rv[] = {background, foreground, font, label, Posx, Posy}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } }
public EventSetDescriptor[] getEventSetDescriptors() { try { // Definizione degli eventi associati al JavaBean MioBottone. EventSetDescriptor push = new EventSetDescriptor(MioBottone.class, "actionPerformed",java.awt.event.ActionListener.class,"actionPerformed"); EventSetDescriptor changed = new EventSetDescriptor(MioBottone.class,"propertyChange",java.beans.PropertyChangeListener.class,"propertyChange"); // Etichette della proprietà. Servono ad un eventuale tool di sviluppo per poterle // presentare all'utente push.setDisplayName("button push"); changed.setDisplayName("bound property change"); // Ritorno degli eventi EventSetDescriptor[] rv = { push, changed}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } }Per finire dotiamo il JavaBean di un'icona per la sua rappresentazione in un tool :
public java.awt.Image getIcon(int iconKind) {Il parametro iconKind serve ad individuare numero di colori che il monitor può gestire. Può assumere i seguenti valori :
java.awt.Image img = loadImage("imma.gif");
return img;
}
package dany.Bottoni; import java.beans.*; public class MioBottoneBeanInfo extends SimpleBeanInfo { public PropertyDescriptor[] getPropertyDescriptors() { try { PropertyDescriptor background = new PropertyDescriptor("background", MioBottone.class); PropertyDescriptor foreground = new PropertyDescriptor("foreground", MioBottone.class); PropertyDescriptor font = new PropertyDescriptor("font", MioBottone.class); PropertyDescriptor label = new PropertyDescriptor("label", MioBottone.class); PropertyDescriptor Posx = new PropertyDescriptor("Posx", MioBottone.class); PropertyDescriptor Posy = new PropertyDescriptor("Posy", MioBottone.class); background.setBound(true); foreground.setBound(true); font.setBound(true); label.setBound(false); Posx.setBound(true); Posy.setBound(true); PropertyDescriptor rv[] = {background, foreground, font, label, Posx, Posy}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } } public EventSetDescriptor[] getEventSetDescriptors() { try { EventSetDescriptor push = new EventSetDescriptor(MioBottone.class, "actionPerformed",java.awt.event.ActionListener.class, "actionPerformed"); EventSetDescriptor changed = new EventSetDescriptor(MioBottone.class,"propertyChange",java.beans.PropertyChangeListener.class,"propertyChange"); push.setDisplayName("button push"); changed.setDisplayName("bound property change"); EventSetDescriptor[] rv = { push, changed}; return rv; } catch (IntrospectionException e) { throw new Error(e.toString()); } } public java.awt.Image getIcon(int iconKind) { java.awt.Image img = loadImage("imma.gif"); return img; } }
Generazione del file jar contenente i files che riguardano il JavaBean
Dopo aver compilato le nostre 2 classi possiamo dire che il nostro JavaBean è composto dai seguenti files:
Name: dany/Bottoni/MioBottone.class Java-Bean: True Name: dany/Bottoni/MioBottoneBeanInfo.class Name: dany/Bottoni/imma.gif Name: dany/Bottoni/imma1.gif
jar cfm MioBottone.jar manifest.mf dany\Bottoni\MioBottone.class dany\Bottoni\MioBottone.class dany\Bottoni\MioBottoneBeanInfo.class dany\Bottoni\imma.gif dany\Bottoni\imma1.gifVerrà creato il file MioBottone.jar che rappresenta un componente utilizzabile in un ambiente di sviluppo che fa uso di JavaBean.
Test del JavaBean mediante l'ambiente di sviluppo scritto in java "BeanBox"
Passiamo ora a testare il JavaBean creato. Nel pacchetto BDK la Sun Microsystem fornisce un piccolo ambiente di sviluppo scritto in java per testare i JavaBean, chiamato Beanbox. Si presenta con tre frame :
Verranno visualizzati
i 3 frame come mostrato nella figura 1.
Figura 1.
A questo punto cliccare sul voce loadjar del menù file, cercare il file MioBottone.jar e caricarlo.
Il JavaBean verrà aggiunto con la sua icona nella toolbar come si vede in fondo alla lista nella figura 2.
Trascinarlo sulla maschera , figura 3.
Figura 3.
Il JavaBean entra subito in esecuzione ; infatti cliccando su di esso vedremo l'immagine cambiare. Come si può vedere dalla figura 4, il frame delle proprietà contiene esattamente le proprietà che abbiamo definito. Se cambiamo queste proprietà vedremo il loro effetto immediato sul JavaBean.
Figura 4.
Per esempio se cambiamo le coordinate dell'immagine Posx e Posy vedremo l'immagine spostarsi all'interno del bottone. Ora che abbiamo visto come funzionano gli eventi internamente all'oggetto (MouseDown e MouseUp), vediamo come funzionano gli eventi dall'esterno. Dobbiamo in pratica provare a usare l'evento che abbiamo incluso nel javabean e cioè ActionPerformed.
A tale scopo trascinare il JavaBean Juggler dalla ToolBar sulla maschera del BeanBox che siccome riguarda un'animazione entrerà subito in esecuzione mettendosi in movimento. Poi con il JavaBean MioBottone selezionato, cliccare sul menù Edit->Events->button push->ActionPerformed (Figura 5. ; notare che l'etichetta "button push" l'avevamo attribuita noi da programma).
Apparirà una riga rossa che parte dal MioBottone. Cliccare sul Juggler mettendo così termine alla riga rossa (Figura 6).
Figura 6.
In questo modo abbiamo associato l'evento del click del MioBottone ad un'azione sul Juggler ; azione che psossiamo scegliere dalla lista che il programma ci mostra (Figura 7.)
Figura 7.
Scegliamo l'azione stopJuggling. A questo punto viene creata sotto la directory bdk\beanbox la directory tmp\sun\beanbox e viene generato e compilato il codice seguente contenuto in un file .java (il nome della classe viene generato automaticamente) :
Cliccando sul MioBottone, entrerà in esecuzione il codice compilato arrestando l'animazione.// Automatically generated event hookup file. package tmp.sun.beanbox; public class ___Hookup_140a292f31 implements java.awt.event.ActionListener, java.io.Serializable { public void setTarget(sunw.demo.juggler.Juggler t) { target = t; } public void actionPerformed(java.awt.event.ActionEvent arg0) { target.stopJuggling(arg0); } private sunw.demo.juggler.Juggler target; }
|
||
|
||
MokaByte ricerca
nuovi collaboratori
|
||
|