Programavimas

Darbo su „Java 2D“ pradžia

„Java 2D“ API yra pagrindinė „Java 1.2“ platformos API (įvairios informacijos apie API ir jos diegimą ieškokite šaltiniuose). API diegimas yra „Java Foundation Classes“ (JFC) dalis dabartinėse „Sun JDK“ beta versijose, skirtose „Windows NT / 95“ ir „Solaris“. Kai „Java 1.2“ bus baigta kurti, „Java 2D“ turėtų tapti prieinama daugiau platformų.

Atkreipkite dėmesį, kad nors „Java 2D“ buvo sukurtas šiek tiek nepriklausomai nuo kitų JFC dalių, vis dėlto jis yra pagrindinė 1.2 AWT dalis. Mes skirsime ir nurodysime 2D specifines savybes diskusijoms, tačiau turėtumėte nepamiršti, kad ši funkcija yra tokia pat svarbi 1.2 grafikos elementams kaip senoji „1.0“ ir „1.1 AWT“ pagalba.

„Java 2D“ išplečia ankstesnius AWT mechanizmus, skirtus 2D grafikos piešimui, teksto ir šriftų valdymui, vaizdų įkėlimui ir naudojimui, spalvų ir spalvų erdvių apibrėžimui ir tvarkymui. Šiuos naujus mechanizmus nagrinėsime šioje ir būsimose skiltyse.

Pastaba apie nomenklatūrą ir konvencijas

Šiame stulpelyje mano pagrindinė kūrimo platforma bus kompiuteris, kuriame veikia „Windows 95“ arba „Windows NT“. Tikiuosi, jei įmanoma, pateikti kitų konkrečiai platformai būdingų patarimų ir gudrybių, tačiau daugiausia dėmesio skirsiu „Windows“, nes būtent ten praleisiu didžiąją laiko dalį.

Kai rašau metodo pavadinimą, jis visada turi būti formos metodo pavadinimas (). Galiniai skliaustai skirti tai atskirti kaip metodą. Metodui gali būti naudojami parametrai. Praktiškai tai visada turėtų aiškiai parodyti kontekstas.

Šaltinio kodų sąrašai bus pateikti su eilutės numeriais. Aš planuoju naudoti eilučių numerius kryžminei nuorodai į straipsnio tekstą ir atitinkamą kodų sąrašą. Tai taip pat turėtų palengvinti stulpelio komentavimą, jei nuspręstumėte spausdinti kopiją. Tačiau atkreipkite dėmesį, kad iš stulpelio susieti šaltinio failai bus įprasti * .java failai (be eilutės numerių), kad galėtumėte juos atsisiųsti ir kurti.

Kadangi ateinančiais mėnesiais rašysiu apie daugelį „Media and Communications“ API, noriu įsitikinti, kad visas pavyzdinis kodas yra prasmingas kaip visuma, taip pat atskirose jo dalyse. Bandysiu nuosekliai įvardyti savo pavyzdžius ir sudėti juos į jausminius paketus.

Mano paketų hierarchijos viršuje bus:

com.javaworld.media 

Kiekvienoje API ar temoje, apie kurią rašau, šiame aukščiausiame lygyje bus bent viena pakuotė. Pvz., Visas šio „Java 2D“ straipsnio kodas bus:

com.javaworld.media.j2d 

Taigi, norėdami pasinaudoti pirmuoju „Java 2D“ programos pavyzdžiu, turėtumėte atsisiųsti kodą, įdėti jį į savo klasės kelią ir naudoti:

java com.javaworld.media.j2d.Pavyzdys01 

(Jei vardų sritis yra per ilga jūsų skoniui arba dėl kokių nors kitų priežasčių norite naudoti kodo pavyzdį nenaudodami visiškai kvalifikuoto pavadinimo, tiesiog pakomentuokite paketo eilutę kiekvieno šaltinio kodo failo pradžioje.)

Sugeneruosiu „Java Archive“ (jar) failą kiekvienam straipsnio pavyzdiniam kodui ir klasės failams. Šis archyvas bus prieinamas kiekvieno stulpelio ištekliuose, jei norite jį atsisiųsti ir vykdyti pavyzdžius iš archyvo.

Aš taip pat turėsiu atnaujintą „jar“ failą, kuriame bus visas kodas ir klasės iš mano dabartinio ir ankstesnio Žiniasklaidos programavimas stulpeliai. Šį visa apimančią stiklainio failą bus galima rasti mano asmeninėje svetainėje.

Paskutinis pavyzdžių punktas: Aš pasirinkau kiekvieną pavyzdį, išskyrus atvejus, kai konkrečiai pažymiu kitaip, atskirą programą ar programėlę. Tai paskatins kartkartėmis šiek tiek pakartoti kodą, tačiau manau, kad tai geriausiai išsaugo kiekvieno atskiro pavyzdžio vientisumą.

Užtenka apie suvažiavimus. Pradėkime programuoti naudodami „Java 2D“!

„Graphics2D“: geresnė grafikos klasė

Centrinė „Java 2D“ API klasė yra java.awt.Grafika2D abstrakta klasė, kuri poklasius java.awt.Grafika išplėsti 2D atvaizdavimo funkcionalumą. Grafika2D prideda vienodesnę paramą manipuliuojant įvairiomis figūromis, todėl tekstas, eilutės ir visos kitos dvimatės formos yra palyginamos pagal savo galimybes ir naudingumą.

Pradėkime nuo paprasto pavyzdžio, parodančio, kaip jūs gaunate ir naudojate a Grafika2d nuoroda.

001 paketas com.javaworld.media.j2d; 002 003 importuoti java.awt. *; 004 importuoti java.awt.event. *; 005 006 viešoji klasė „Example01“ pratęsia rėmelį {007 / ** 008 * Intuituoja objektą „Example01“. 009 ** / 010 public static void main (String args []) {011 new Example01 (); 012} 013 014 / ** 015 * Mūsų pavyzdys01 konstruktorius nustato rėmelio dydį, prideda 016 * vaizdinius komponentus ir tada juos mato vartotojui. 017 * Jis naudoja adapterio klasę, kad vartotojas uždarytų rėmelį 018 *. 019 ** / 020 public example01 () {021 // Pavadinkite mūsų kadrą. 022 super („Java 2D pavyzdys01“); 023 024 // Nustatykite rėmelio dydį. 025 setSize (400 300); 026 027 // Turime įjungti rėmelio 028 // matomumą nustatydami „Visible“ parametrą į „true“. 029 setVisible (tiesa); 030 031 // Dabar norime būti tikri, kad tinkamai pašaliname išteklius 032 //, kurį šis rėmelis naudoja, kai langas uždarytas. Tam naudojame 033 // anoniminį vidinės klasės adapterį. 034 addWindowListener (naujas WindowAdapter () 035 {public void windowClosing (WindowEvent e) 036 {dispose (); System.exit (0);} 037} 038); 039} 040 041 / ** 042 * Dažų metodas suteikia tikrąją magiją. Čia mes 043 * išmetėme grafikos objektą į „Graphics2D“, kad iliustruotume 044 *, kad su 045 * „Graphics2D“ galime naudoti tas pačias senas grafikos galimybes, kurias esame įpratę naudoti su „Graphics“. 046 ** / 047 public void paint (g grafika) {048 // Štai kaip piešėme kvadratą, kurio plotis 049 // iš 200, aukštis 200, pradedant nuo x = 50, y = 50. 050 g. SetColor (spalva. Raudona); 051 g.drawRect (50,50,200,200); 052 053 // Nustatykime spalvą į mėlyną, tada naudokime objektą „Graphics2D 054 //“, kad nupieštume stačiakampį, atsuktą iš kvadrato. 055 // Iki šiol mes nieko nedarėme naudodami „Graphics2D“, kad 056 // negalėtume padaryti ir naudodami „Graphics“. (Mes iš tikrųjų esame 057 // naudodami „Graphics2D“ metodus, paveldėtus iš „Graphics“.) 058 „Graphics2D“ g2d = („Graphics2D“) g; 059 g2d.setColor (spalva. Mėlyna); 060 g2d.drawRect (75,75,300,200); 061} 062} 

Vykdydami01 pavyzdį, turėtumėte pamatyti raudoną kvadratą ir mėlyną stačiakampį, kaip parodyta paveikslėlyje žemiau. Atminkite, kad yra žinoma „Windows NT / 95“ versijos „JDK 1.2 Beta 3“ našumo problema (naujausias 1.2 leidimas šiame stulpelyje). Jei šis pavyzdys jūsų sistemoje yra lėtai, jums gali tekti išspręsti klaidą, kaip aprašyta „JavaWorld“„Java“ patarimas 55 (žr. toliau pateiktus šio patarimo šaltinius).

Atkreipkite dėmesį, kad lygiai taip pat, kaip jūs tiesiogiai neiškreipiate a Grafika objekto, jūs neiškreipiate a Grafika2D objektas arba. „Java“ vykdymo laikas sukuria atvaizdavimo objektą ir perduoda jį dažyti() (047 eilutė „Example01“ kodų sąraše), o „Java 1.2“ platformose ir toliau, šis objektas įgyvendina Grafika2D abstrakti klasė taip pat.

Iki šiol nieko ypatingo nepadarėme naudodami 2D grafikos galimybes. Pridėkime šiek tiek kodo prie ankstesnio pavyzdžio pabaigos dažyti() metodą ir atneškite keletą naujų „Java 2D“ funkcijų (02 pavyzdys):

001 / ** 002 * Čia mes naudojame naujas „Java 2D“ API funkcijas, tokias kaip „affine 003 *“ transformacijos ir „Shape“ objektai (šiuo atveju bendrasis „004 * one“, „GeneralPath“). 005 ** / 006 „public void paint“ (g grafika) {007 g.setColor (Color.red); 008 g. „DrawRect“ (50,50,200,200); 009 010 Grafika2D g2d = (Grafika2D) g; 011 g2d.setColor (spalva. Mėlyna); 012 g2d.drawRect (75,75,300,200); 013 014 // Dabar nupieškime kitą stačiakampį, tačiau šį kartą leiskite 015 // naudoti „GeneralPath“, kad nurodytumėte segmentą pagal segmentą. 016 // Be to, mes išversime ir pasuksime šį stačiakampį 017 //, palyginti su įrenginio erdve (taigi, į 018 // pirmus du keturkampius), naudodami „AffineTransform“. 019 // Mes taip pat pakeisime jo spalvą. 020 „GeneralPath path“ = naujas „GeneralPath“ („GeneralPath.EVEN_ODD“); 021 kelias.moveTo (0,0f, 0,0f); 022 path.lineTo (0,0f, 125,0f); 023 path.lineTo (225.0f, 125.0f); 024 path.lineTo (225,0f, 0,0f); 025 kelias.closePath (); 026 027 „AffineTransform“ = naujas „AffineTransform“ (); 028 at.setToRotation (-Math.PI / 8.0); 029 g2d. Transformacija (at); 030 at.setToTranslation (50,0f, 200,0f); 031 g2d.transformuoti (at); 032 033 g2d.setColor (Spalva.žalia); 034 g2d. Užpildymas (kelias); 035} 

Atkreipkite dėmesį, kad nuo Bendrasis kelias yra įsikūręs java.awt.geom paketą, turime būti tikri, kad pridėjome ir importavimo eilutę:

importuoti java.awt.geom. *; 

02 pavyzdžio išvestis parodyta šiame paveikslėlyje.

„Java 2D“ leidžia nurodyti savavališkas formas naudojant java.awt. Forma sąsaja. Įvairios numatytosios formos, tokios kaip stačiakampiai, daugiakampiai, 2D linijos ir kt., Įgyvendina šią sąsają. Vienas iš įdomiausių iš jų lankstumo požiūriu yra java.awt.geom.GeneralPath.

Bendrasis keliasLeiskite apibūdinti kelią su savavališku kraštų skaičiumi ir potencialiai itin sudėtinga forma. 02 pavyzdyje mes sukūrėme stačiakampį (020–025 eilutės), tačiau lygiai taip pat lengvai galėjome pridėti kitą kraštą ar šonus, kad padarytume penkiakampį, septyniakampį ar kokį kitą daugiašalį daugiakampį. Taip pat atkreipkite dėmesį, kad skirtingai nuo standarto Grafika kodas, „Java 2D“ leidžia mums nurodyti koordinates vietoj sveikųjų skaičių naudojant slankiojo kablelio skaičius. Pasaulio CAD pardavėjai, džiaukis! Tiesą sakant, „Java 2D“ palaiko sveikasis skaičius, dvigubaiir plaukiojantis aritmetika daugelyje vietų.

Jūs tikriausiai taip pat pastebėjote, kad kai sukūrėme kelią, mes perdavėme parametrą, „GeneralPath.EVEN_ODD“, į konstruktorių (020 eilutė). Šis parametras reiškia a vyniojimo taisyklė tai nurodo atvaizduotojui, kaip nustatyti formos, nurodytos mūsų kelyje, vidų. Norėdami sužinoti daugiau apie „Java 2D“ apvijos taisykles, žr. „Java 2D“ javadoc dokumentaciją, nurodytą šaltiniuose.

Kita svarbi 02 pavyzdžio naujovė yra susijusi su a naudojimu java.awt.geom.AffineTransforms (027–031 eilutės). Tokių transformacijų ypatumus paliksiu skaitytojui (žr. Straipsnių, kuriuose tai išsamiau aptariama, šaltinius), tačiau pakanka pasakyti, kad „AffineTransform“Jie leidžia valdyti bet kurią „Java 2D“ grafiką, kad ją būtų galima išversti (perkelti), pasukti, keisti mastelį, kirpti ar atlikti šių manipuliacijų derinius.

Raktas į „AffineTransform“ slypi sąvokoje Įrenginio erdvė ir Vartotojo erdvė. „Device Space“ yra ta sritis, į kurią grafika bus perteikta ekrane. Tai yra analogiška koordinatėms, kurios naudojamos kuriant įprastą AWT stilių Grafika2D grafika. Tačiau „User Space“ yra išverčiama, sukama koordinačių sistema, kurią gali valdyti vienas ar daugiau „AffineTransform“s.

„Device Space“ ir „User Space“ koordinačių sistemos iš pradžių sutampa, o kilmė pateikimo paviršiaus viršutiniame kairiajame kampe (čia - „Frame“). Teigiama x ašis juda tiesiai nuo pradžios, o teigiama y ašis - žemyn.

Po pirmosios transformacijos 02 pavyzdyje (028 ir 029 eilutės) „User Space“ koordinačių sistema buvo pasukta 22,5 laipsnių prieš laikrodžio rodyklę, palyginti su „Device Space“. Abu jie vis dar turi tą pačią kilmę. (Atkreipkite dėmesį, kad apsisukimai nurodomi radianais, kai -PI / 8 radianai lygūs -22,5 laipsnių arba 22,5 laipsniai CCW.) Jei mes čia sustotume ir nupieštume stačiakampį, jis dažniausiai būtų pasuktas iš mūsų regėjimo lauko. taikymas Rėmas.

Po to, kai sukimasis, mes pritaikysime antrą transformaciją (030 ir 031 eilutės), tai yra vertimas. Tai perkelia „User Space“ koordinačių sistemą, palyginti su „Device Space“, perkeliant ją žemyn 200,0 (plūduriuojančiais) ir dešiniais 50,0 (plūduriuojančiais) vienetais.

Kai užpildome žalią stačiakampį, jis išverčiamas ir pasukamas, palyginti su įrenginio erdve.

Beziero ir aukštesnio lygio kreivių

Išnagrinėję, kaip transformacijos gali būti naudojamos manipuliuojant grafiniais objektais, dar kartą panagrinėkime, kaip mes kuriame sudėtingas ir įdomias savavališkas formas.

Kreivės visoje matematikoje ir kompiuterinėje grafikoje naudojamos apytiksliai vertinant sudėtingas formas, naudojant baigtinį, tiksliai apibrėžtą (ir idealiu atveju mažą) matematinių taškų skaičių. Nors anksčiau standartinis AWT tiesiogiai nepalaikė piešimo savavališkomis kreivėmis („Java 1.0“ arba „1.1“ platformos), „Java 2D“ prideda integruotą palaikymą pirmos, antros ir trečios eilės kreivėms. Kreives galite piešti dviem pabaigos taškai ir nulis, vienas arba du valdymo taškai. „Java 2D“ apskaičiuoja pirmos ir antros eilės kreives, naudodamas tiesines ir kvadratines formules, o kubines arba trečios eilės kreives, naudodamas Bezier kreives.

(Bezjė kreivės yra tam tikros parametrinės daugianario kreivės rūšis, pasižyminčios labai pageidaujamomis savybėmis, susijusiomis su uždarų kreivių ir paviršių skaičiavimu. Jie naudojami daugelyje grafikos programų. Daugiau informacijos apie parametrinių polinomų ir Bezjė kreivių naudojimą ieškokite šaltiniuose. kompiuterinėje grafikoje.) Bendrasis kelias metodai, piešiantys kiekvieną iš šių kreivių, yra šie:

  • lineTo () tiesiems segmentams (nurodykite tik galinius taškus)
  • quadTo () kvadratinėms kreivėms (nurodykite vieną valdymo tašką)
  • kreivėTo () trečios eilės kreivėms (nurodykite du kontrolinius taškus, nubrėžtus naudojant kubinę Bezier kreivę)