package elte.java2_utikalauz5.beans; import java.awt.*; import java.util.*; import java.beans.*; /** Egy egyszerű bean kötött tulajdonságokkal és egy vétózhatóval. A vétózható tulajdonság a "funPercent". VetoablePropertyChange figyelők elutasíthatják a tulajdonság javasolt változását egy PropertyVetoException kivétel eldobásával. @link.forrásfájl {@docRoot}/../data/beans/src SmileyBean.java @link.letöltés {@docRoot}/../data/beans SmileyBean.jar @since Java 2 Útikalauz programozóknak */ public class SmileyBean extends Component implements PropertyChangeListener { /** Verziószám */ private final static long serialVersionUID = 15L; /** * Konstruktor */ public SmileyBean() { } /** * Kirajzolja a mosolygó arcot */ public void paint(Graphics g) { g.setColor( faceColor ); g.fillArc( 5, 5, 40, 40, 0, 360 ); g.setColor( drawColor ); g.drawArc( 5, 5, 40, 40, 0, 360 ); g.fillArc( 15, 18, 5, 5, 0, 360 ); g.fillArc( 30, 18, 5, 5, 0, 360 ); int a = ( int )( 0.5 + ( ourFunPercent / 100.0 ) * MAX_SMILEY_ANGLE ); if ( a < 4 ) { a = 0; } // Hogy az ív ne legyen kisebb, mint egy pixel g.drawArc( 15, 15, 20, 20, -( 180 - a ) / 2, -a ); } /** * A propertyChangeEvent kezelője, az esemény alapján beállítja * a funPercent új értékét */ public void propertyChange( PropertyChangeEvent event ) { Integer newValue = ( Integer )event.getNewValue(); try { setFunPercent( newValue.intValue() ); } catch ( PropertyVetoException e ) { } } public Dimension getPreferredSize() { return new Dimension(50,50); } /** * Visszatér rajzolat színével */ public synchronized Color getDrawColor() { return drawColor; } /** * Beállítja a rajzolat színét. Ez egy kötött tulajdonság */ public void setDrawColor( Color newColor ) { Color oldColor = drawColor; drawColor = newColor; changes.firePropertyChange( "drawColor", oldColor, newColor ); repaint(); } /** * Visszatér az arc színével */ public synchronized Color getFaceColor() { return faceColor; } /** * Beállítja az arc színét. Ez egy kötött tulajdonság */ public void setFaceColor( Color newColor ) { Color oldColor = faceColor; faceColor = newColor; changes.firePropertyChange( "faceColor", oldColor, newColor ); repaint(); } /** * Visszatér a minimális értesítendő változás értékével */ public synchronized int getMinChangeToNotify() { return minChangeToNotify; } /** * Beállítja a minimális értesítendő változás értékét. * Ez egy kötött tulajdonság */ public void setMinChangeToNotify( int newMinChangeToNotify ) { int oldMinChangeToNotify = minChangeToNotify; minChangeToNotify = newMinChangeToNotify; changes.firePropertyChange( "minChangeToNotify", oldMinChangeToNotify, newMinChangeToNotify ); } /** * Visszatér az aktuálisan beállított színsémával */ public synchronized String getColorScheme() { return colorScheme; } /** * Beállítja az aktuális színsémát */ public void setColorScheme( String scheme ) { if ( scheme.equals( COL_GRAY ) ) { setFaceColor( Color.lightGray ); setDrawColor( Color.darkGray ); colorScheme = scheme; } else if ( scheme.equals( COL_ATROCIOUS ) ) { setFaceColor( new Color( 10, 75, 10 ) ); setDrawColor( new Color( 255, 128, 128 ) ); colorScheme = scheme; } else if ( scheme.equals( COL_HIDEOUS ) ) { setFaceColor( new Color( 255, 200, 0 ) ); setDrawColor( new Color( 255, 95, 255 ) ); colorScheme = scheme; } else { // Egyébként legyen alapértelmezett scheme = COL_DEFAULT; } if ( scheme.equals( COL_DEFAULT ) ) { setFaceColor( Color.yellow ); setDrawColor( Color.black ); colorScheme = scheme; } } /** * Visszaadja az aktuális vidámság fokozatot százalékban */ public synchronized int getFunPercent() { return ourFunPercent; } /** * Beállítja a vidámság fokozatot százalékban, hacsak nem dob el egy * regisztrált VetoableChangeListener egy PropertyVetoException kivételt. * Ez egy vétozható kötött tulajdonság. */ public void setFunPercent( int newFunPercent ) throws PropertyVetoException { if ( newFunPercent <= 100 && newFunPercent >= 0 ) { int oldFunPercent = ourFunPercent; // Először értesítjük a vétózókat a változásról. Ha bármelyik kivételt dob // nem kapjuk el, hanem a függvény hívójának delegáljuk tovább. vetos.fireVetoableChange("funPercent", new Integer( oldFunPercent ), new Integer( newFunPercent ) ); // Ha senki nem vétózott, menjünk tovább és változtassuk meg az értéket ourFunPercent = newFunPercent; if ( oldFunPercent != newFunPercent ) { repaint(); } changes.firePropertyChange("funPercent", new Integer( oldFunPercent ), new Integer( newFunPercent ) ); // Értesíti a regisztrált SmileyListener figyelőket, ha a változás // meghaladja a minChangeToNotify értéket if ( Math.abs( oldFunPercent - newFunPercent ) >= minChangeToNotify ) { notifySmileyChanged( oldFunPercent, newFunPercent ); } } } //-------------------------------------------------------------------------- // A következő metódusok a SmileyListener-eket kezelik /** * Hozzáad egy SmileyListenert */ public synchronized void addSmileyListener( SmileyListener l ) { smileyListeners.addElement( l ); } /** * Kitörli a regisztrációs listáról a SmileyListenert */ public synchronized void removeSmileyListener( SmileyListener l ) { smileyListeners.removeElement( l ); } /** * Értesíti a figyelőket, ha változás történt */ protected void notifySmileyChanged( int oldFunPercent, int newFunPercent ) { Vector thisList = new Vector(); SmileyEvent thisEvent = new SmileyEvent( this, oldFunPercent, newFunPercent ); // Készítsünk másolatot a listáról, hogy más szálak által lehetséges // változásai ne tegyenek keresztbe synchronized ( this ) { thisList = ( Vector )smileyListeners.clone(); } // Küldjük el az eseményt minden regisztrált figyelőnek for ( int i = 0; i < thisList.size(); i++ ) { ( ( SmileyListener )thisList.elementAt( i ) ).smileyChanged( thisEvent ); } } //---------------------------------------------------------------------- // A figyelők regisztrálását biztosító metódusok: /** * Az itt megadott PropertyChangeListener objektumok propertyChange metódusa * lesz meghívva valahányszor egy kötött tulajdonság megváltozik. * A Javabeans specifikáció nem határozza meg, hogy milyen sorrendben * hívódjanak meg a figyelők metódusai. */ public void addPropertyChangeListener( PropertyChangeListener l ) { changes.addPropertyChangeListener( l ); } /** * Kiveszi a megadott PropertyChangeListener figyelőt a SmileyBean belső * regisztrációs listájából. */ public void removePropertyChangeListener( PropertyChangeListener l ) { changes.removePropertyChangeListener( l ); } /** * Az itt megadott VetoableChangeListeners objektumok vetoableChange metódusa * lesz meghívva valahányszor egy vétózható tulajdonság megváltozik. * A SmileyBean jelenleg egy ilyen tulajdonságot tartalmaz: "funPercent". * A Javabeans specifikáció nem határozza meg, hogy milyen sorrendben * hívódjanak meg a figyelők metódusai. */ public void addVetoableChangeListener( VetoableChangeListener l ) { vetos.addVetoableChangeListener( l ); } /** * Kiveszi a megadott VetoableChangeListener figyelőt a SmileyBean belső * regisztrációs listájából. */ public void removeVetoableChangeListener( VetoableChangeListener l ) { vetos.removeVetoableChangeListener( l ); } //---------------------------------------------------------------------- // Privát adatmezők: private PropertyChangeSupport changes = new PropertyChangeSupport( this ); private VetoableChangeSupport vetos = new VetoableChangeSupport( this ); // A SmileyListener figyelők private Vector smileyListeners = new Vector(); private Color drawColor = Color.black; private Color faceColor = Color.yellow; private int ourFunPercent = 50; private int minChangeToNotify = 10; private static final int MAX_SMILEY_ANGLE = 150; private String colorScheme = COL_DEFAULT; public static final String COL_DEFAULT = "default"; public static final String COL_GRAY = "gray"; public static final String COL_ATROCIOUS = "atrocious"; public static final String COL_HIDEOUS = "hideous"; }