JavaBeans (2. část) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Java

JavaBeans (2. část)

1. března 2001, 00.00 | Další díl seriálu o JavaBeans. Dnes si ukážeme, jak může jedna Bean reagovat na změnu některé vlastnosti jiné Bean.

Daňový úřad

Dnes si ukážeme, jak může jedna Bean reagovat na změnu některé vlastnosti jiné Bean. Jako zdroj použijeme Plantaz z minulého pokračování a jako cíl novou Bean s názvem DanovyUrad. Ta bude ukazovat aktuální daňové zatížení plantáže. V minulém díle jsme viděli, jak vyvolat událost, dnes si ukážeme, jak na takovou událost reagovat. Daňový úřad bude vypadat následovně:

import java.beans.*;
import javax.swing.*;

public class DanovyUrad extends JPanel implements java.io.Serializable {
	private int vyseDani;
	private JLabel label = new JLabel();
	private final int DAN_ZE_STROMU = 2;

	public DanovyUrad() {
	    setVyseDani(0);
            this.add(label);
	}
	public void setVyseDani(int novaVyseDani) {
	    label.setText(String.valueOf(novaVyseDani));
	    vyseDani = novaVyseDani;
	}
	public int getVyseDani() {
	    return vyseDani;
	}
    public void reagujNaUdalost(PropertyChangeEvent evt) {
      Integer iObject = (Integer) evt.getNewValue();
      setVyseDani(DAN_ZE_STROMU * iObject.intValue());
    }
}

Konstanta DAN_ZE_STROMU udává výši daní z jednoho kávového stromu. Jakmile dojde ke změně vlastnosti pocetStromu v objektu Plantaz2, je vyvolána událost typu PropertyChangeEvent. Jestliže na tuto událost navážeme (pomocí Beanboxu) metodu reagujNaUdalost, pak každá změna počtu stromů způsobí aktualizaci vlastnosti vyseDani (výše daní je součinem počtu stromů a dani z jediného stromu) v objektu DanovyUrad. Hodnota této vlastosti je zobrazena na displeji.

Nyní do Beanboxu nahrajeme nové Beans (pomocí LoadJar..., vytvoříme instance BlueButton, Plantaz2 a DanovyUrad. Na stisk tlačítka navážeme metodu pridejStrom a na událost propertyChange volání metody reagujNaUdalost. Každý stisk tlačítka nyní způsobí přidání stromu a to zase způsobí zvýšení daňové zátěže. Opět (pro jednoduchost) není aktualizována změna velikosti Beans a tak je po zvýšení počtu míst zobrazeného čísla nutno pomocí myši zvětšit danou komponentu (aby se hodnota vešla na displej).

Uvedený příklad byl velmi jednoduchý, automaticky jsme předpokládali, že událost je vyvolána v důsledku změny vlastnosti pocetStromu. Pokud by byla metoda reagujNaUdalost vyvolána v důsledku změny jiné vlastnosti, pak by metoda getNewValue() vracela pro nás nesmyslnou hodnotu (hodnotu nějaké jiné vlastnosti). Naštěstí existuje metoda getPropertyName(), která vrací řetězec odpovídající názvu změněné vlastnosti. Testováním hodnoty zmíněného řetězce se můžeme přesvědčit o tom, zda skutečně došlo ke změně té vlastnosti, která nás zajímá.

Vlastnosti typu constrained

Některé vlastnosti bývají označovány jako constrained - "stísněné", jedná se o vlastnosti, jejichž hodnota musí ležet v určitých mezích. Předtím, než nastane změna vlastnosti, dojde nejprve ke kontrole, zda nová hodnota leží v požadovaných mezích. Pokud ne, ke změně vůbec nedojde. V našem případě bychom například mohli položit omezení, že počet stromů na plantáži nesmí být větší než 20.

Vytvoříme novou třídu Plantaz3, jejíž vlastnosti pocetStromu již bude constrained. Oproti třídě Plantaz2 provedeme pouze drobné změny. Nejprve musíme přidat objekt typu VetoableChangeSupport, pak musíme pozměnit metodu setPocetStromu tak, aby ještě před zavoláním metody firePropertyChange zavolala fireVetoableChange - ještě předtím, než oznámíme změnu vlastnosti, musíme zkusit, zda tuto vlastnost vůbec lze změnit. Před zavoláním fireVetoableChange nesmíme provádět žádné změny vlastnosti! Z toho důvodu je i změna zobrazeného textu zařazena až za volání této metody. Všechny metody, které mění hodnotu vlastnosti pocetStromu navíc musí nějakým způsobem zpracovávat výjimku PropertyVetoException. Poslední úpravou je přidání metod addVetoableChangeListener a removeVetoableChangeListener podobně, jako jsme to provedli s addPropertyChangeListener a removePropertyChangeListener.

Veškeré změny kódu vypadají následovně:

public class Plantaz3 extends JPanel implements java.io.Serializable {
	...
    private VetoableChangeSupport veto = new VetoableChangeSupport(this);

	public Plantaz3() throws PropertyVetoException {
	    setPocetStromu(0);
        this.add(label);
	}
	public void setPocetStromu(int novyPocetStromu) 
	     throws PropertyVetoException {
	    veto.fireVetoableChange("pocetStromu",
		new Integer(pocetStromu), new Integer(novyPocetStromu));
	    label.setText(String.valueOf(novyPocetStromu));
	    zmena.firePropertyChange("pocetStromu",
		new Integer(pocetStromu), new Integer(novyPocetStromu));
   	    pocetStromu = novyPocetStromu;
	}
	...
	public void pridejStrom() throws PropertyVetoException {
            setPocetStromu(getPocetStromu() + 1);
	}
	...
	public void addVetoableChangeListener(VetoableChangeListener l) {
    	    veto.addVetoableChangeListener(l);
	}
	public void removeVetoableChangeListener(VetoableChangeListener l)
	{
 	    veto.removeVetoableChangeListener(l);
	}
}

Reakce na změnu vlastnosti typu constrained

Bean, která reaguje na změnu vlastnosti typu constrained musí implementivat interface VetoableChangeListener. Tento interface obsahuje jedinou metodu - vetoableChange. Vyvoláním výjimky PropertyVetoException v implementaci metody, jsme "vetujeme" změnu vlastnosti, tj. zakážeme její změnu.

Jestliže vytvoříme nový daňový úřad, který bude implementovat uvedenou metodu tím způsobem, že na změnu vlastnosti pocetStromu na hodnotu větší než 20 (a menší než 0) bude reagovat vyvoláním výjimky PropertyVetoException, zajístíme, že uvedená vlastnost nebude moci nabývat hodnot mimo povolené meze.

Nový daňový úřad (DanovyUrad2) bude oproti svému "předchůdci" obsahovat navíc jedinou metodu:

    public void vetoableChange(PropertyChangeEvent evt)
            throws PropertyVetoException {
        Integer iObject = (Integer) evt.getNewValue();
        if (iObject.intValue()>20||iObject.intValue()<0) 
	      throw new PropertyVetoException("Mimo povolené meze!", evt);
    }

V případě, že nová hodnota vlastnosti neleží v povolených mezích je vyvolána výjimka, jejímž prvním parametrem je chybové hlášení a druhým událost typu PropertyChangeEvent.

Použití v BeanBoxu

Po přeložení obou nových tříd a jejich "uskladnění" do souborů typu JAR je možné vytvořit nové Beans v BeanBoxu. Najeďme na Plantaz3 a na událost vetoableChange (Edit|Events|vetoableChange|vetoableChange) navažme metodu vetoableChange komponenty DanovyUrad2. Obdobným způsobem na událost propertyChange navážeme metodu reagujNaUdalost, to jsme již dělali dříve.

Nyní můžeme provést pokus, v okně Properties změnit hodnotu vlastnosti pocetStromu. Jestliže nová hodnota leží v povolených mezích, reaguje na ni daňový úřad. Jakákoliv změna vlastnost mimo povolené meze není provedena vůbec. Zdrojové kódy jsou opět k dispozici ke stažení.

Tématické zařazení:

 » Rubriky  » Java  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: