Programování

Vytváření spousty fazolí: Vytvářejte opakovaně použitelné komponenty JavaBeans

V této krátké sérii zkoumáme vývoj softwarových komponent JavaBeans. Nakonec bude s většinou fazolí manipulováno ve vývojovém prostředí fazolí; zde se však zajímáme pouze o aspekty rámce na úrovni zdroje. Výhody vývoje prostředí JavaBeans - tj. Vývoj podle specifikace JavaBeans - jsou několikanásobné:

  • S fazolemi mohou ve vizuálních vývojových prostředích snadno manipulovat uživatelé, kteří nemusí být technicky zdatní ve vývoji jazyka Java na zdrojové úrovni.

  • Kvůli standardnímu rozhraní jsou fazole snadno distribuovatelné, což umožňuje snadnější integraci komponent třetích stran do vývoje.

  • Vývojáři mohou snadno přenést kód, který byl vyvinut pro jeden projekt, do opakovaně použitelné knihovny komponent, ke které lze získat přístup v budoucích vývojových snahách.

Oko bouře

V

první díl této série

, vyvinuli jsme dvě jednoduché fazole: nevizuální poplachovou fazole a grafickou šipku vlevo / vpravo. Oba byly doplněny vizuálem

přizpůsobitel

a

fazolové informace

třídy. V fazolích, které tento měsíc pokryjeme, nebudeme poskytovat přizpůsobení; místo toho se soustředíme na používání existujících fazolí a komponent k vytváření větších a lepších fazolí.

Předpoklady

Jako pokračování dvoudílné série předpokládám znalost problematiky diskutované v předchozím pokračování, včetně doplňkových článků a zdrojů.

Fazole

Od začátku do konce této série vyvíjíme následující fazole:

AlarmBean Non-graphical bean that fires off an event after a specified delay.
ArrowBean

Grafická fazole se šipkou doleva / doprava.

ProgressBean

Grafická fazole pro zobrazení pokroku.

NumberFieldBean

Grafická číslice Textové pole fazole s rolovacími knoflíky. Tato fazole využívá fazole ArrowBean.

FontChooserBean

Grafická fazole pro výběr písma. Tato fazole využívá fazole NumberFieldBean.

FontSelectorBean

Grafická fazole pro výběr písma, která zobrazuje aktuální písmo a poskytuje tlačítka OK / Storno. Tato fazole využívá fazole FontChooserBean.

FontDialogBean

Grafická fazole pro výběr písma, která v samostatném dialogovém okně zobrazí výběr písma. Tato fazole využívá fazole FontSelectorBean.

Diskutovali jsme o AlarmBean a ArrowBean fazole podrobně minulý měsíc; v této epizodě budeme diskutovat zbývající fazole s různou úrovní podrobností.

Možná se divíte, proč stavíme tři fazole písma. Konečným cílem je jednoduše vytvořit fazole pro výběr písma, která zobrazí dialogové okno s písmem, když uživatel klikne na tlačítko. Tento úkol se přirozeně dělí na tři fazole, které vytvoříme: První je uživatelské rozhraní pro výběr písma, druhé přidává ovládací prvky dialogu a ukázku písma a třetí zavádí tlačítko pro vyskakování dialogu a obsahuje základní kód pro zpracování dialogu.

Bez fazolí bychom museli tyto položky vyvíjet jako specializované komponenty AWT nebo jako jednu monolitickou třídu; pomocí fazolí můžeme tři části vyvinout jako nezávislé fazole, které jsou samy o sobě opakovaně použitelné.

Náš rozsah

Stejně jako v prvním pokračování této série se zabýváme pouze beanismem těchto tříd, nikoli skutečnými maticemi a šrouby, díky nimž se zatrhávají. Ve výsledku probereme fazole v kosterní formě, zvýrazníme červeně fragmenty, které mají zvláštní význam, a ostatní podrobnosti necháme nahlédnout do volného času. Ani se nebudeme zabývat přizpůsobitelnostmi, které jsme dostatečně podrobně pokryli naší diskusí o prvních dvou fazolích.

Chcete-li vidět nucenou práci za fazolemi, podívejte se na kompletní zdrojový kód.

Budování fazole ProgressBean

ProgressBean

je jednoduchá fazole pro zobrazení průběhu. Jedná se o vlastní komponentu AWT, která zobrazuje procentuální hodnotu a grafické pruhové vyjádření této hodnoty, jak je znázorněno na obrázku níže. Vystavuje dvě vlastnosti: aktuální a maximální hodnoty pruhu.

Aktuální hodnota je vystavena jako pozorovatelná vlastnost. Pozorovatelné vlastnosti jsou vlastnosti, jejichž změny lze pozorovat. Pozorovatelé jsou zaregistrováni u objektu bean stejným způsobem jako posluchači událostí a jsou upozorněni, kdykoli se změní vlastnost. Jednotlivé vlastnosti fazole musí být fazolí výslovně pozorovatelné; není možné pozorovat změny jen u jakékoli vlastnosti kteréhokoli fazole.

Tato fazole je implementována s následujícími dvěma třídami:

  • ProgressBean - Hlavní třída fazolí

  • ProgressBeanBeanInfo - Informační třída fazole

Třída ProgressBean

The

ProgressBean třída je hlavní třída fazole, jednoduchá vlastní komponenta AWT a Java fazole.

veřejná třída ProgressBean rozšiřuje komponentu ... 

Tato fazole je lehká součást, takže ji rozšiřujeme Součástka namísto Plátno, a poskytnout odpovídající malovat() metoda. Odlehčený rámec komponent je efektivnější než tradiční rámec vlastních komponent, což vyžaduje méně prostředků místního systému oken. Jako součást automaticky zdědíme serializovatelnost nařízenou JavaBeans a poskytneme výchozí konstruktor no-arg.

public void setBarground (Color c) ... public Color getBarground () ... public synchronized void setMaximum (int m) ... public int getMaximum () ... 

Zde vystavujeme Barva vlastnictví barground (barva zobrazeného pruhu) a int vlastnictví maximum (maximální hodnota sloupce).

public synchronized void setValue (int v) {if (value! = v) {value = v; překreslit (); fireValueChange (); }} public int getValue () ... 

The int vlastnictví hodnota je pozorovatelný, což znamená, že musíme informovat všechny zúčastněné posluchače, kdykoli se jeho hodnota změní. Za tímto účelem nazýváme naše fireValueChange () způsob informování posluchačů kdykoli setValue () je nazýván.

chráněné posluchače PropertyChangeSupport = nový PropertyChangeSupport (toto); public void addPropertyChangeListener (PropertyChangeListener l) {listeners.addPropertyChangeListener (l); } public void removePropertyChangeListener (PropertyChangeListener l) {listeners.removePropertyChangeListener (l); } 

Zde udržujeme seznam objektů, které jsou registrovány, aby byly upozorňovány, kdykoli se změní pozorovatelná vlastnost. Používáme třídu PropertyChangeSupport z java.beans balíček udržovat tento seznam. Konstruktor pro tuto třídu vyžaduje, abychom zadali fazole, která bude původem událostí změny vlastnosti; v tomto případě ano tentoa metody, které poskytuje, nám umožňují tento seznam udržovat.

Odhalením metod addPropertyChangeListener () a removePropertyChangeListener (), automaticky označujeme, že tato fazole má pozorovatelné vlastnosti. To však nenaznačujeme který vlastnosti jsou pozorovatelné. Tyto informace musí být náležitě zdokumentovány fazolí.

chráněné celé číslo oValue = nové celé číslo (hodnota); protected void fireValueChange () {listeners.firePropertyChange ("value", oValue, oValue = new Integer (value)); } 

Tuto metodu nazýváme, abychom informovali posluchače o změně v naší hodnota vlastnictví; používáme firePropertyChange () metoda našeho seznamu k šíření tohoto oznámení. První parametr je název vlastnosti, která by se měla shodovat s názvem exponované vlastnosti; druhý parametr je stará hodnota vlastnosti; a třetí vlastnost je nová hodnota. The PropertyChangeSupport třída se vrací, aniž by cokoli dělala, pokud jsou staré a nové hodnoty stejné.

Třída ProgressBeanBeanInfo

The

ProgressBeanBeanInfo třída jednoduše popisuje ProgressBean fazole, zakrývající všechny zděděné informace, které chceme zakrýt.

Vytváření fazole NumberFieldBean

Tato fazole implementuje běžnou součást uživatelského rozhraní, pole pro rolovací číslo - číselné textové pole, které poskytuje šipky pro zvýšení a snížení, jak je znázorněno na obrázku níže. Tato fazole přináší důležitý koncept JavaBeans:

programová manipulace s fazolemi

.

Programová manipulace s fazolemi se týká mechanismů, které JavaBeans poskytuje pro programové vytváření a přístup k fazolím. Ačkoli je možné získat přístup k fazolím pomocí standardního vytváření objektů Java (nový X ()) a mechanismy odlévání typu ((Y) x), doporučujeme použít poskytnuté mechanismy JavaBeans, aby bylo možné budoucí rozšíření rámce JavaBeans.

Tato fazole je implementována s následujícími dvěma třídami:

  • NumberFieldBean - Hlavní třída fazolí

  • NumberFieldBeanBeanInfo - Informační třída fazole

Číslo třídy FieldBean

The NumberFieldBean class, the main bean class, is an AWT container that adds three components: two ArrowBean fazole a Textové pole. Programový přístup k internetu ArrowBean třída vyžaduje, abychom využili mechanismů manipulace s fazolemi, které jsem před chvílí zmínil.

Aktuální číselná hodnota je vystavena jako pozorovatelná vlastnost. I když se jedná o normální vlastnost, ke které lze přistupovat a manipulovat ji pomocí obvyklých metod přístupu fazole, je také pozorovatelný, aby se posluchači mohli zaregistrovat, aby byli upozorněni, kdykoli se změní jeho hodnota. Když uživatel stiskne Return, událost nespustíme, i když by to bylo zjevné rozšíření této třídy.

veřejná třída NumberFieldBean rozšiřuje kontejner implementuje ActionListener ... 

Prodlužujeme Kontejner a implementovat ActionListener za účelem přijímání událostí z fazolí a komponent AWT, které používáme. Prodlužování Kontejner místo tradičnějších Panel znamená, že tato fazole, jako ProgressBean fazole je lehká součást.

public NumberFieldBean () ... 

Jako fazole musíme poskytnout veřejný konstruktor no-arg. Všimněte si, že bychom neměli poskytovat další konstruktory pro programové použití; to by bylo v rozporu s přístupovým mechanismem JavaBeans.

try {down = (ArrowBean) Beans.instantiate (getClass () .getClassLoader (), "org.merlin.beans.arrow.ArrowBean"); } catch (Exception ex) {ex.printStackTrace (); } 

Zde vytvoříme ArrowBean pomocí programatického instančního mechanismu fazolí. Nepoužíváme standardní Javu Nový operátor; místo toho použijeme vytvořit instanci () metoda třídy Fazole. Specifikujeme ClassLoader použít k načtení třídy fazole; v tomto případě použijeme vlastní ClassLoader a plně kvalifikovaný název třídy fazole („org.merlin.beans.arrow.ArrowBean“) a výsledný odlitek Objekt do příslušné třídy.

Všimněte si, že vytvořit instanci () metoda může vyvolat celou řadu výjimek (například pokud nelze nalézt zadaný objekt bean). Jednoduše zachytíme a zobrazíme všechny takové výjimky, které by mimochodem neměly nastat, pokud je fazole správně nainstalována.

add ("East", (Component) Beans.getInstanceOf (down, Component.class)); 

Tady jsme obsadili ArrowBean do a Součástka a přidat to jako normální Součástka. Standard nepoužíváme (Součástka) mechanismus odlévání typu a nepoužíváme skutečnost, že náš AlarmBean je podtřída Součástka; místo toho použijeme getInstanceOf () metoda třídy Fazole. Určíme fazole, kterou chceme hodit, a Třída objekt, na který jej chceme vrhnout (v tomto případě Třída součásti).

Ačkoli tento přístup teď nemá moc smysl, budoucí verze JavaBeans budou podporovat fazole složené z více souborů tříd, stejně jako fazole, které mohou vystavovat různé aspekty sebe sama jako různé třídy. Například fazole může vypadat, že podtřídu obou Součástka a RemoteObject poskytnutím dvou spojených tříd: a Součástka a RemoteObject. Pomocí mechanismu odlévání typu JavaBeans lze příslušný objekt fazole vrátit automaticky, takže fazole mohou mít zjevnou vícenásobnou dědičnost, i když to Java nativně nepodporuje. Podrobnosti najdete ve specifikaci JavaBeans "Glasgow". (Odkaz na tuto specifikaci je uveden v části Zdroje tohoto článku.)

Je nutné, abychom nyní používali tyto přístupové mechanismy fazolí, abychom mohli bez problémů převést naše fazole na budoucí technologie JavaBeans.

down.setDirection (ArrowBean.LEFT); down.addActionListener (toto); 

Zde nakonfigurujeme ArrowBean za použití setDirection () přistupující objekt a addActionListener () způsob registrace. Tyto přistupující vlastnosti a metody registrace posluchače můžeme použít přímo na fazole, kterou jsme právě vytvořili; je pouze nutné použít funkci JavaBeans type-casting, když přistupujeme k aspektu fazole, která je zděděna z jiné třídy.

public synchronized void setValue (int v) {field.setText (String.valueOf (v)); fireValueChange (getValue ()); } veřejné synchronizované int getValue () ... 

Zde vystavujeme int vlastnictví hodnota, což je hodnota tohoto pole. Tato vlastnost je pozorovatelná, takže při každé změně musíme upozornit posluchače. Děláme to voláním našich fireValueChange () metoda.

public void setColumns (int c) ... public int getColumns () ... public synchronized void setMinimum (int m) ... public int getMinimum () ... public synchronized void setMaximum (int m) ... public int getMaximum () ... veřejné synchronizované neplatné setStep (int s) ... veřejné int getStep () ... 

Zde vystavujeme int vlastnosti sloupce, minimální, maximum, a krok, což je počet sloupců zobrazených v Textové pole, minimální a maximální hodnoty, které by toto pole mělo obsahovat, a částka, o kterou by měla tlačítka se šipkami změnit hodnotu. Tyto vlastnosti nejsou pozorovatelné.

Všimněte si, že používáme synchronizaci k zajištění bezpečnosti podprocesů, kde je to vhodné.

public synchronized void actionPerformed (ActionEvent e) {int value = getValue (); if (e.getSource () == dolů) {if (hodnota> minimum) {hodnota = (hodnota - krok> hodnota)? minimum: svorka (hodnota - krok); setValue (hodnota); }} ... 
$config[zx-auto] not found$config[zx-overlay] not found