Programavimas

Sukurkite daugybę pupelių: sukurkite daugkartinius „JavaBeans“ komponentus

Šioje trumpoje serijoje nagrinėjame „JavaBeans“ programinės įrangos komponentų kūrimą. Galų gale dauguma pupelių bus manipuliuojamos pupelių vystymosi aplinkoje; tačiau mums čia rūpi tik šaltinio lygio sistemos aspektai. „JavaBeans“ kūrimo, t. Y. Tobulinimo pagal „JavaBeans“ specifikaciją, pranašumai yra keli:

  • Pupomis vizualinio vystymosi aplinkose gali lengvai manipuliuoti vartotojai, kuriems nereikia techniškai mokėti kurti Java šaltinio lygio.

  • Dėl standartinės sąsajos pupeles galima lengvai paskirstyti, o tai leidžia trečiųjų šalių komponentus lengviau integruoti į kūrimo pastangas.

  • Kūrėjai gali lengvai perkelti vienam projektui sukurtą kodą į daugkartinio naudojimo komponentų biblioteką, prie kurios bus galima prisijungti ateityje.

Audros akis

Viduje konors

pirmoji šios serijos dalis

, mes sukūrėme dvi paprastas pupeles: nevizualinę pavojaus pupelę ir grafinę kairės / dešinės rodyklės pupelę. Abu jie buvo papildyti vaizdu

pritaikymas

ir

pupelių informacija

klasės. Pupelėse, kurias apimsime šį mėnesį, neteiksime pritaikymo priemonių; Vietoj to, mes sutelksime dėmesį į esamų pupelių ir komponentų naudojimą, kad sukurtume didesnes, geresnes pupeles.

Būtinos sąlygos

Tęsdamas dviejų dalių seriją, aš įgausiu žinių apie ankstesnėje dalyje aptartus klausimus, įskaitant papildomus straipsnius ir išteklius.

Pupelės

Nuo šios serijos pradžios iki pabaigos mes sukūrėme šias pupeles:

AlarmBean Negrafinis pupelis, kuris iššaukia įvykį po nurodyto atidėjimo.
ArrowBean

Grafinė kairės / dešinės rodyklės pupelė.

„ProgressBean“

Grafinis progreso rodymo pupelis.

„NumberFieldBean“

Grafinis skaitmuo Teksto laukas pupelė su ritinėliais. Ši pupelė naudoja „ArrowBean“ pupeles.

„FontChooserBean“

Grafinis šrifto parinkimo pupelis. Ši pupelė naudoja „NumberFieldBean“ pupelę.

„FontSelectorBean“

Grafinis šrifto parinkiklio pupelis, rodantis dabartinį šriftą ir pateikiantis mygtukus Gerai / Atšaukti. Ši pupelė naudoja „FontChooserBean“ pupeles.

„FontDialogBean“

Grafinis šriftų parinkimo elementas, kuris iššaukia šrifto parinkiklį atskirame dialogo lange. Ši pupelė naudoja „FontSelectorBean“ pupeles.

Mes aptarėme AlarmBean ir ArrowBean pupelės išsamiai praėjusį mėnesį; šiame epizode mes aptarsime likusias pupeles skirtingu išsamumo lygiu.

Jums gali būti įdomu, kodėl mes statome tris šrifto pupeles. Galutinis tikslas yra tiesiog sukurti šrifto parinkiklio pupelę, kuri pasirodys šrifto dialogo lange, kai vartotojas spustelės mygtuką. Ši užduotis labai natūraliai suskirstyta į tris mūsų sukurtas pupeles: pirmoji yra vartotojo sąsaja šrifto pasirinkimui, antroji prideda dialogo valdiklius ir šrifto pavyzdį, o trečioji pateikia mygtuką, kad iššoktų dialogas, ir jame yra dialogo valdymo kodas.

Be pupelių šiuos daiktus turėtume sukurti kaip specializuotus AWT komponentus arba kaip vieną monolitinę klasę; naudojant pupeles, mes galime sukurti tris dalis kaip savarankiškas pupeles, kurios gali būti pakartotinai naudojamos savaime.

Mūsų taikymo sritis

Kaip ir pirmosios šios serijos dalies atveju, mes rūpinamės tik šių klasių pupelėmis, o ne tikrais veržlėmis ir varžtais, kurie priverčia jas pažymėti. Dėl to aptarsime pupeles griaučių pavidalu, raudonai paryškindami ypač svarbius fragmentus ir palikdami kitas detales, kurias galėsite peržiūrėti laisvalaikiu. Taip pat nesusirūpinsime pritaikymo priemonėmis, kurias pakankamai išsamiai aptarėme aptardami pirmąsias dvi pupeles.

Norėdami pamatyti priverstinį darbą už pupelių, patikrinkite visą šaltinio kodą.

„ProgressBean“ pupelių kūrimas

„ProgressBean“

yra paprastas pažangos rodymo pupelis. Tai yra pasirinktinis AWT komponentas, rodantis procentinę vertę ir grafinį šios vertės vaizdą, kaip parodyta toliau pateiktame paveikslėlyje. Tai atskleidžia dvi savybes: dabartinę ir maksimalią juostos vertę.

Dabartinė vertė rodoma kaip stebimas turtas. Stebimos savybės yra savybės, kurių pokyčius galima pastebėti. Stebėtojai registruojami pupelėje taip pat, kaip ir renginių klausytojai, ir jiems pranešama, kai pasikeičia nuosavybė. Pupelė turi aiškiai pastebėti atskiras pupelių savybes; neįmanoma pastebėti bet kokios pupelės savybės pokyčių.

Ši pupelė įgyvendinama šiose dviejose klasėse:

  • „ProgressBean“ - Pagrindinė pupelių klasė

  • „ProgressBeanBeanInfo“ - Informacijos apie pupeles klasė

Klasė „ProgressBean“

„ProgressBean“ klasė yra pagrindinė pupelių klasė, paprastas pasirinktinis AWT komponentas ir „Java“ pupelės.

visuomenės klasė „ProgressBean“ pratęsia komponentą ... 

Ši pupelė yra lengvas komponentas, todėl mes pratęsiame Komponentas vietoj Drobėir pateikti tinkamą dažyti() metodas. Lengvųjų komponentų karkasas yra efektyvesnis nei tradicinių užsakomųjų komponentų karkasas, reikalaujantis mažiau vietinės langinės sistemos išteklių. Kaip komponentą mes automatiškai paveldime „JavaBeans“ nurodytą serijinį pritaikomumą ir pateikiame numatytąjį „no-arg“ konstruktorių.

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

Čia mes apnuoginame Spalva nuosavybė baras (rodomos juostos spalva) ir tarpt nuosavybė maksimaliai (didžiausia juostos vertė).

public synchronized void setValue (int v) {if (reikšmė! = v) {reikšmė = v; perdažyti (); „fireValueChange“); }} public int getValue () ... 

tarpt nuosavybė vertė yra pastebimas, o tai reiškia, kad mes turime informuoti visus suinteresuotus klausytojus, kai tik pasikeičia jo vertė. Šiuo tikslu mes vadiname savo „fireValueChange“ () būdas informuoti klausytojus setValue () vadinamas.

saugomi „PropertyChangeSupport“ klausytojai = nauja „PropertyChangeSupport“ (ši); public void addPropertyChangeListener (PropertyChangeListener l) {klausytojai.addPropertyChangeListener (l); } public void removePropertyChangeListener (PropertyChangeListener l) {klausytojai.removePropertyChangeListener (l); } 

Čia mes tvarkome objektų, užregistruotų pranešti, kai pasikeičia pastebimas turtas, sąrašą. Mes naudojame klasę „PropertyChangeSupport“ nuo java.pupos paketą, kad išlaikytumėte šį sąrašą. Šios klasės konstruktorius reikalauja, kad nurodytume pupelę, iš kurios kils nuosavybės pokyčių įvykiai; šiuo atveju taip yra taiir jos pateikti metodai leidžia mums išlaikyti sąrašą.

Atskleidžiant metodus addPropertyChangeListener () ir removePropertyChangeListener (), mes automatiškai nurodome, kad ši pupelė turi pastebimų savybių. Tačiau mes nenurodome kuri savybes galima pastebėti. Ši informacija turi būti tinkamai dokumentuota su pupelėmis.

apsaugotas sveikasis skaičius oValue = naujas sveikasis skaičius (reikšmė); apsaugota tuštuma fireValueChange () {klausytojai.firePropertyChange ("value", oValue, oValue = new Sveikasis skaičius (reikšmė)); } 

Mes vadiname šį metodą norėdami pranešti klausytojams apie mūsų pasikeitimus vertė nuosavybė; mes naudojame „firePropertyChange“ () mūsų pranešimo platinimo metodas. Pirmasis parametras yra ypatybės pavadinimas, kuris turėtų sutapti su paveiktos nuosavybės pavadinimu; antrasis parametras yra senoji turto vertė; o trečioji nuosavybė yra nauja vertė. „PropertyChangeSupport“ klasė grįžta nieko nedarant, jei senos ir naujos vertybės yra vienodos.

„Class ProgressBeanBeanInfo“

„ProgressBeanBeanInfo“ klasė tiesiog apibūdina „ProgressBean“ bet kokia paveldėta informacija, kurią mes norime užgožti.

Sukurkite pupelių „NumberFieldBean“

Ši pupelė įgyvendina bendrą vartotojo sąsajos komponentą, ritininio numerio įvedimo lauką - skaitinį teksto lauką, kuriame pateikiamos prieaugio ir mažinimo rodyklės, kaip parodyta toliau pateiktame paveikslėlyje. Ši pupelė iškelia svarbią „JavaBeans“ koncepciją:

programinis manipuliavimas pupelėmis

.

Programinis manipuliavimas pupelėmis reiškia mechanizmus, kuriuos „JavaBeans“ numato programiškai kurti ir pasiekti pupeles. Nors prieiti prie pupelių galima naudojant standartinį „Java“ objektų kūrimą (naujas X ()) ir tipo liejimo mechanizmai ((Y) x), rekomenduojama naudoti pateiktus „JavaBeans“ mechanizmus, kad ateityje būtų galima išplėsti „JavaBeans“ sistemą.

Ši pupelė įgyvendinama šiose dviejose klasėse:

  • „NumberFieldBean“ - Pagrindinė pupelių klasė

  • NumberFieldBeanBeanInfo - Informacijos apie pupeles klasė

Klasės numerisFieldBean

„NumberFieldBean“ klasė, pagrindinė pupelių klasė, yra AWT konteineris, kuriame yra trys komponentai: du ArrowBean pupelės ir a Teksto laukas. Programinė prieiga prie ArrowBean klasė reikalauja, kad mes panaudotume manipuliavimo pupelėmis mechanizmus, kuriuos jau minėjau prieš akimirką.

Dabartinė skaitinė vertė parodoma kaip stebima savybė. Nors tai yra įprasta savybė, prie kurios galima prieiti ir su ja manipuliuoti naudojant įprastus pupelių prieigos metodus, taip pat yra stebimas, todėl klausytojai gali užsiregistruoti ir būti informuoti, kai pasikeičia jo vertė. Mes neatšaukiame įvykio, kai vartotojas paspaudžia „Return“, nors tai būtų akivaizdus šios klasės pratęsimas.

viešoji klasė „NumberFieldBean“ pratęsia „Container“ įgyvendina „ActionListener“ ... 

Mes pratęsiame Konteineris ir įgyvendinti „ActionListener“ norėdami gauti įvykius iš mūsų naudojamų pupelių ir AWT komponentų. Pratęsimas Konteineris vietoj tradiciškesnio Skydelis reiškia, kad ši pupelė, kaip ir „ProgressBean“ pupelės yra lengvas komponentas.

public NumberFieldBean () ... 

Kaip pupelė, mes turime pateikti viešą „no-arg“ konstruktorių. Atkreipkite dėmesį, kad neturėtume teikti kitų konstruktorių programiniam naudojimui; tai prieštarautų „JavaBeans“ prieigos mechanizmui.

pabandykite {down = (ArrowBean) Pupelės.įtvirtinkite (getClass () .getClassLoader (), "org.merlin.beans.arrow.ArrowBean"); } sugauti (Išimtis ex) {ex.printStackTrace (); } 

Čia mes sukuriame ArrowBean naudojant programinį pupelių momentinį mechanizmą. Mes nenaudojame standartinės „Java“ naujas operatorius; vietoj to mes naudojame iš karto () klasės metodas Pupelės. Mes nurodome „ClassLoader“ naudoti pupelių klasei pakrauti; šiuo atveju mes naudojame savo „ClassLoader“ ir visiškai kvalifikuotas pupelių klasės pavadinimas ("org.merlin.beans.arrow.ArrowBean") ir mesti gautą Objektas į atitinkamą klasę.

Atkreipkite dėmesį, kad iš karto () metodas gali sukelti įvairias išimtis (pavyzdžiui, jei nurodytos pupelės nepavyko rasti). Mes tiesiog pagauname ir parodome tokias išimtis, kurių, beje, neturėtų pasitaikyti, jei pupelės yra tinkamai sumontuotos.

pridėti ("Rytai", (Komponentas) Pupos.getInstanceOf (žemyn, Komponentas.klasė)); 

Čia mes mesti ArrowBean į a Komponentas ir pridėkite jį kaip įprastą Komponentas. Mes nenaudojame standarto (Komponentas) tipo liejimo mechanizmas, ir mes nenaudojame fakto, kad mūsų AlarmBean yra poklasis Komponentas; vietoj to mes naudojame „getInstanceOf“ () klasės metodas Pupelės. Nurodome pupelę, kurią norime mesti, ir Klasė objektą, į kurį mes norime jį mesti (šiuo atveju Komponentas.klasė).

Nors šiuo metu šis požiūris neturi prasmės, būsimos „JavaBeans“ versijos palaikys pupeles, susidedančias iš kelių klasės failų, taip pat pupeles, kurios gali atskleisti skirtingus savo, kaip skirtingų klasių, aspektus. Pavyzdžiui, gali pasirodyti, kad pupelė klasifikuoja abu Komponentas ir „RemoteObject“ suteikiant dvi susietas klases: a Komponentas ir a „RemoteObject“. Naudojant „JavaBeans“ tipo liejimo mechanizmą, atitinkamą pupelių objektą galima grąžinti automatiškai, todėl pupelės gali turėti akivaizdų daugybinį paveldėjimą, nors „Java“ to savaime nepalaiko. Išsamesnės informacijos ieškokite „Glasgow“ „JavaBeans“ specifikacijoje. (Nuoroda į šią specifikaciją pateikiama šio straipsnio skyriuje „Ištekliai“.)

Šiuos pupelių prieigos mechanizmus turime naudoti dabar, kad galėtume be jokių problemų pakeisti pupeles į būsimas „JavaBeans“ technologijas.

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

Čia mes sukonfigūruojame ArrowBean naudojant setDirection () turto prižiūrėtojas ir addActionListener () registracijos būdas. Šiuos nuosavybės priėmėjus ir klausytojų registravimo metodus galime naudoti tiesiai ant ką tik sukurtos pupelės; „JavaBeans“ tipo liejimo funkciją būtina naudoti tik tada, kai prieiname prie pupelės, paveldėtos iš kitos klasės, aspektą.

public synchronized void setValue (int v) {field.setText (String.valueOf (v)); „fireValueChange“ („getValue“); } public synchronized int getValue () ... 

Čia mes apnuoginame tarpt nuosavybė vertė, kuri yra šio lauko vertė. Ši savybė yra stebima, todėl apie tai turime pranešti klausytojams, kai ji pasikeičia. Mes tai darome skambindami savo „fireValueChange“ () metodas.

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 () ... viešas sinchronizuotas negaliojantis setStep (int s) ... public int getStep () ... 

Čia mes apnuoginame tarpt savybes stulpeliai, minimumas, maksimaliaiir žingsnis, kurie yra atitinkamai stulpelių, rodomų Teksto laukas, mažiausia ir didžiausia reikšmės, kurias turėtų turėti šis laukas, ir suma, kuria rodyklių mygtukai turėtų pakeisti vertę. Šios savybės nepastebimos.

Atminkite, kad, jei reikia, siūlų saugumui užtikrinti naudojame sinchronizavimą.

viešai sinchronizuotas negaliojantis actionPerformed (ActionEvent e) {int value = getValue (); if (e.getSource () == žemyn) {if (reikšmė> mažiausia) {vertė = (reikšmė - žingsnis> vertė)? minimum: spaustukas (vertė - žingsnis); setValue (reikšmė); }} ...