Programmering

Bygg en mengde bønner: Lag gjenbrukbare JavaBeans-komponenter

I denne korte serien undersøker vi utviklingen av JavaBeans programvarekomponenter. Til slutt vil de fleste bønner bli manipulert i et miljø for utvikling av bønner; vi er imidlertid bare opptatt av kildenivåene i rammeverket. Fordelene med å utvikle JavaBeans - det vil si å utvikle seg til JavaBeans-spesifikasjonen - er flere ganger, blant dem:

  • Bønner kan enkelt manipuleres i visuelle utviklingsmiljøer av brukere som ikke trenger å være teknisk dyktige i Java-utvikling på kildenivå.

  • På grunn av standardgrensesnittet kan bønner lett distribueres, noe som gjør at tredjepartskomponenter lettere kan integreres i utviklingsarbeidet.

  • Utviklere kan enkelt overføre kode som er utviklet for ett prosjekt til et gjenbrukbart bibliotek med komponenter, som er tilgjengelig i fremtidig utviklingsarbeid.

Stormens øye

I

første del av denne serien

, vi utviklet to enkle bønner: en ikke-visuell alarmbønne og en grafisk venstrepil / høyrepilbønne. Begge ble utvidet med visuelle

tilpasning

og

bønneinformasjon

klasser. I bønnene vi dekker denne måneden, vil vi ikke tilby tilpassere; i stedet konsentrerer vi oss om å bruke eksisterende bønner og komponenter for å skape større, bedre bønner.

Forutsetninger

Som en fortsettelse av en todelt serie vil jeg anta kjennskap til problemstillingene som ble diskutert i forrige del, inkludert tilleggsartikler og ressurser.

Bønnene

Fra start til slutt i denne serien utvikler vi følgende bønner:

AlarmBean En ikke-grafisk bønne som fyrer av en hendelse etter en spesifisert forsinkelse.
ArrowBean

En grafisk venstre-pil / høyre-pil bønne.

ProgressBean

En grafisk bønne for fremdriftsvisning.

NumberFieldBean

Et grafisk tall Tekstfelt bønne med rulleknapper. Denne bønnen bruker ArrowBean-bønnen.

FontChooserBean

En grafisk bønner til valg av font. Denne bønnen bruker NumberFieldBean-bønnen.

FontSelectorBean

En grafisk skriftvelgerbønne som viser gjeldende skrift og inneholder OK / Avbryt-knappene. Denne bønnen bruker FontChooserBean-bønnen.

FontDialogBean

En grafisk skriftvelgerbønne som popper opp skriftvelgeren i en egen dialog. Denne bønnen bruker FontSelectorBean bønne.

Vi diskuterte AlarmBean og ArrowBean bønner i detalj forrige måned; i denne episoden vil vi diskutere de resterende bønnene i varierende detaljnivå.

Du lurer kanskje på hvorfor vi bygger tre fontbønner. Det endelige målet er ganske enkelt å produsere en fontvelgerbønne som dukker opp en fontdialog når brukeren klikker på en knapp. Denne oppgaven deles veldig naturlig inn i de tre bønnene vi skal produsere: Den første er brukergrensesnittet for skriftvalget, den andre legger til dialogkontroller og en skrifteksempel, og den tredje introduserer en knapp for å dukke opp dialogen og inneholder den grunnleggende dialoghåndteringskode.

Uten bønner måtte vi utvikle disse artiklene som spesialiserte AWT-komponenter eller som en enkelt monolitisk klasse; ved hjelp av bønner kan vi utvikle de tre delene som uavhengige bønner som er gjenbrukbare i seg selv.

Vårt omfang

Som med den første delen av denne serien, er vi bare opptatt av beanismene i disse klassene og ikke de faktiske muttere og bolter som får dem til å tikke. Som et resultat vil vi diskutere bønnene i skjelettform, og fremheve de fragmentene som er spesielt relevante i rødt, og la de andre detaljene stå igjen for på fritiden. Vi vil heller ikke bekymre oss for tilpasningene, som vi dekket i tilstrekkelig detalj med vår diskusjon av de to første bønnene.

For å se tvangsarbeidet bak bønnene, sjekk ut den komplette kildekoden.

Å bygge ProgressBean bønne

ProgressBean

er en enkel fremdriftsbønne. Det er en tilpasset AWT-komponent som viser en prosentverdi og grafisk stangrepresentasjon av denne verdien, som vist i figuren nedenfor. Den avslører to egenskaper: gjeldende og maksimale barverdier.

Nåværende verdi er eksponert som en observerbar eiendom. Observerbare egenskaper er egenskaper hvis endringer kan observeres. Observatører blir registrert med bønnen på samme måte som lyttere til begivenhetene, og de får beskjed når en eiendom endres. Individuelle egenskaper til en bønne må gjøres eksplisitt observerbar av bønnen; det er ikke mulig å observere endringer i hvilken som helst eiendom til en bønne.

Denne bønnen er implementert med følgende to klasser:

  • ProgressBean - Hovedbønneklassen

  • ProgressBeanBeanInfo - Bønneinformasjonsklassen

Klasse ProgressBean

De

ProgressBean klasse er hovedbønneklassen, en enkel tilpasset AWT-komponent og Java bønne.

offentlig klasse ProgressBean utvider komponent ... 

Denne bønnen er en lett komponent, så vi utvider Komponent i stedet for Lerret, og gi et passende maling() metode. Rammeverket for lette komponenter er mer effektivt enn det tradisjonelle rammeverket for tilpassede komponenter, og krever færre ressurser fra det lokale vindusvinduet. Som en komponent arver vi automatisk seriabiliteten som er pålagt av JavaBeans, og vi gir standard no-arg-konstruktøren.

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

Her avslører vi Farge eiendom barground (fargen på linjen som vises) og int eiendom maksimum (maksimum barverdi).

offentlig synkronisert ugyldig setValue (int v) {if (verdi! = v) {verdi = v; male på nytt (); fireValueChange (); }} offentlig int getValue () ... 

De int eiendom verdi er observerbar, noe som betyr at vi må informere alle interesserte lyttere når verdien endres. For dette formål kaller vi vår fireValueChange () metode for å informere lytterne når som helst setValue () er kalt.

beskyttede PropertyChangeSupport-lyttere = nye PropertyChangeSupport (dette); offentlig tomrom addPropertyChangeListener (PropertyChangeListener l) {listeners.addPropertyChangeListener (l); } offentlig tomrom removePropertyChangeListener (PropertyChangeListener l) {listeners.remPropertyChangeListener (l); } 

Her fører vi en liste over objekter som er registrert for å bli varslet når en observerbar eiendom endres. Vi bruker klassen PropertyChangeSupport fra java.bønner pakke for å opprettholde denne listen. Konstruktøren for denne klassen krever at vi spesifiserer bønnen som skal være opprinnelsen til eiendomsendringshendelser; i dette tilfellet er det detteog metodene den gir, lar oss opprettholde listen.

Ved å avsløre metodene addPropertyChangeListener () og removePropertyChangeListener (), indikerer vi automatisk at denne bønnen har observerbare egenskaper. Vi angir imidlertid ikke hvilken egenskaper er observerbare. Denne informasjonen må dokumenteres med bønnen.

beskyttet Integer oValue = new Integer (verdi); beskyttet ugyldig fireValueChange () {listeners.firePropertyChange ("value", oValue, oValue = new Integer (value)); } 

Vi kaller denne metoden for å varsle lyttere om en endring i vår verdi eiendom; vi bruker firePropertyChange () metoden i listen vår for å formidle dette varselet. Den første parameteren er navnet på eiendommen, som skal samsvare med navnet på en eksponert eiendom; den andre parameteren er den gamle verdien av eiendommen; og den tredje eiendommen er den nye verdien. De PropertyChangeSupport klasse returnerer uten å gjøre noe hvis de gamle og nye verdiene er de samme.

Klasse ProgressBeanBeanInfo

De

ProgressBeanBeanInfo klasse beskriver ganske enkelt ProgressBean bønne, skjuler all arvet informasjon som vi ønsker å skjule.

Å bygge NumberFieldBean bønne

Denne bønnen implementerer en vanlig brukergrensesnittkomponent, det rullbare nummerinntastingsfeltet - et numerisk tekstfelt som gir økning og redusering av piler, som vist i figuren nedenfor. Denne bønnen bringer opp et viktig JavaBeans-konsept:

programmatisk manipulering av bønner

.

Programmatisk manipulering av bønner refererer til mekanismene som JavaBeans gir for programmatisk oppretting og tilgang til bønner. Selv om det er mulig å få tilgang til bønner ved hjelp av standard Java-objektoppretting (ny X ()) og støpemekanismer ((Y) x) anbefales det at du bruker de medfølgende JavaBeans-mekanismene for å muliggjøre fremtidig utvidelse av JavaBeans-rammeverket.

Denne bønnen er implementert med følgende to klasser:

  • NumberFieldBean - Hovedbønneklassen

  • NumberFieldBeanBeanInfo - Bønneinformasjonsklassen

Klassenummer FieldBean

De NumberFieldBean klasse, hovedbønneklassen, er en AWT-beholder som legger til tre komponenter: to ArrowBean bønner og en Tekstfelt. Programmatisk tilgang til ArrowBean klasse krever at vi benytter meg av mekanismene for manipulering av bønner jeg nevnte for et øyeblikk siden.

Den nåværende numeriske verdien blir eksponert som en observerbar egenskap. Selv om det er en normal egenskap som kan nås og manipuleres gjennom vanlige tilgangsmetoder for bønner, er det også observerbar, slik at lyttere kan registrere seg for å bli varslet når verdien endres. Vi avfyrer ikke en hendelse når brukeren trykker på Return, selv om det ville være en åpenbar utvidelse av denne klassen.

offentlig klasse NumberFieldBean utvider Container implementerer ActionListener ... 

Vi forlenger Container og implementere ActionListener for å motta hendelser fra bønner og AWT-komponenter som vi bruker. Forlenger Container i stedet for det mer tradisjonelle Panel betyr at denne bønnen, som ProgressBean bønne er en lett komponent.

offentlig NumberFieldBean () ... 

Som en bønne må vi tilby en offentlig konstruktør uten argumenter. Merk at vi ikke skal tilby andre konstruktører for programmatisk bruk; å gjøre det ville gå mot JavaBeans tilgangsmekanisme.

prøv {down = (ArrowBean) Beans.instantiate (getClass () .getClassLoader (), "org.merlin.beans.arrow.ArrowBean"); } fange (Unntak ex) {ex.printStackTrace (); } 

Her lager vi en ArrowBean ved hjelp av den programmatiske mekanismen for instantiering av bønner Vi bruker ikke standard Java ny operatør; i stedet bruker vi instantiate () metode for klassen Bønner. Vi spesifiserer ClassLoader å bruke for lasting av bønneklassen; i dette tilfellet bruker vi vårt eget ClassLoader og det fullt kvalifiserte navnet på bønneklassen ("org.merlin.beans.arrow.ArrowBean"), og støp den resulterende Gjenstand til riktig klasse.

Merk at instantiate () metoden kan kaste en rekke unntak (for eksempel hvis den angitte bønnen ikke kunne bli funnet). Vi fanger ganske enkelt opp og viser slike unntak, som forresten ikke burde oppstå hvis bønnen er riktig installert.

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

Her kaster vi ArrowBean til en Komponent og legg det til som vanlig Komponent. Vi bruker ikke standarden (Komponent) type støpemekanisme, og vi bruker ikke det faktum at vår AlarmBean er en underklasse av Komponent; i stedet bruker vi getInstanceOf () metode for klassen Bønner. Vi spesifiserer bønnen som vi ønsker å kaste og Klasse objekt som vi ønsker å kaste den (i dette tilfellet, Komponent.klasse).

Selv om denne tilnærmingen gir liten mening akkurat nå, vil fremtidige versjoner av JavaBeans støtte bønner som består av flere klassefiler, samt bønner som kan avsløre forskjellige aspekter av seg selv som de forskjellige klassene. For eksempel kan en bønne se ut til å underklasse begge deler Komponent og RemoteObject ved å tilby to sammenkoblede klasser: a Komponent og en RemoteObject. Ved å bruke JavaBeans-støpemekanismen kan det rette bønneobjektet returneres automatisk, slik at bønner kan ha tilsynelatende flere arv, selv om Java ikke støtter dette naturlig. For detaljer, se "Glasgow" JavaBeans-spesifikasjonen. (En lenke til denne spesifikasjonen er gitt i Ressurser-delen av denne artikkelen.)

Det er nødvendig for oss å bruke disse tilgangsmekanismene for bønner nå, slik at vi kan overføre våre bønner til fremtidige JavaBeans-teknologier uten problemer.

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

Her konfigurerer vi ArrowBean bruker setDirection () tilgang til eiendommen og addActionListener () registreringsmetode. Vi kan bruke disse eiendomstilgangene og registreringsmetodene for lytter direkte på bønnen vi nettopp opprettet; det er bare nødvendig å bruke JavaBeans type casting-funksjonen når vi får tilgang til et aspekt av en bønne som er arvet fra en annen klasse.

offentlig synkronisert ugyldig setValue (int v) {field.setText (String.valueOf (v)); fireValueChange (getValue ()); } offentlig synkronisert int getValue () ... 

Her avslører vi int eiendom verdi, som er verdien av dette feltet. Denne egenskapen kan observeres, så vi må varsle lyttere når den endres. Vi gjør dette ved å ringe vår fireValueChange () metode.

public void setColumn (int c) ... public int getColumn () ... public synchronized void setMinimum (int m) ... public int getMinimum () ... public synchronized void setMaximum (int m) ... public int getMaximum () ... public synchronized void setStep (int s) ... public int getStep () ... 

Her avslører vi int eiendommer kolonner, minimum, maksimum, og steg, som er henholdsvis antall kolonner som vises i Tekstfelt, minimums- og maksimumsverdiene som dette feltet skal inneholde, og hvor mye pilknappene skal endre verdien. Disse egenskapene kan ikke observeres.

Merk at vi bruker synkronisering for å sikre trådsikkerhet der det er aktuelt.

offentlig synkronisert ugyldig handlingPerformert (ActionEvent e) {int-verdi = getValue (); hvis (e.getSource () == ned) {if (verdi> minimum) {verdi = (verdi - trinn> verdi)? minimum: klemme (verdi - trinn); setValue (verdi); }} ... 
$config[zx-auto] not found$config[zx-overlay] not found