Programování

Začínáme s Java 2D

Rozhraní Java 2D API je základní rozhraní API platformy Java 1.2 (různé zdroje informací o rozhraní API a jeho implementacích najdete v části Zdroje). Implementace API jsou k dispozici jako součást Java Foundation Classes (JFC) v aktuálních beta verzích Sun JDK pro Windows NT / 95 a Solaris. Jakmile bude dokončena Java 1.2, měla by být Java 2D dostupná na více platformách.

Všimněte si, že ačkoli Java 2D byl vyvinut poněkud nezávisle na ostatních částech JFC, je přesto základní součástí 1,2 AWT. Uděláme rozdíl a pro diskusi upozorníme na 2D specifické funkce, ale měli byste si pamatovat, že tato funkce je stejně důležitá pro grafiku 1.2 jako stará podpora 1.0 a 1.1 AWT.

Java 2D rozšiřuje předchozí mechanismy AWT pro kreslení 2D grafiky, manipulaci s textem a písmem, načítání a používání obrázků a definování a řešení barev a barevných prostorů. Budeme zkoumat tyto nové mechanismy v tomto i budoucích sloupcích.

Poznámka o nomenklatuře a konvencích

V tomto sloupci bude mou primární vývojovou platformou počítač se systémem Windows 95 nebo Windows NT. Doufám, že poskytnu další tipy a triky specifické pro platformu, kde je to možné, ale zaměřím se na Windows, protože tam budu trávit většinu času.

Když píšu název metody, měl by mít vždy tvar název metody (). Koncové závorky jsou určeny k oddělení od sebe jako metoda. Metoda může, ale nemusí brát parametry. V praxi by to měl kontext vždy objasnit.

Seznamy zdrojových kódů budou uvedeny včetně čísel řádků. Mám v plánu použít čísla řádků ke křížovým odkazům na text článku a výpisy kódů, jak je to vhodné. To by vám také mělo výrazně usnadnit anotaci sloupce, pokud se rozhodnete vytisknout kopii. Pamatujte však, že zdrojové soubory odkazované ze sloupce budou běžné soubory * .java (čísla bez řádků), abyste si s nimi mohli stahovat a vyvíjet.

Protože budu v příštích měsících psát o mnoha mediálních a komunikačních API, chci se ujistit, že veškerý ukázkový kód má smysl jako celek i v jeho jednotlivých částech. Pokusím se důsledně pojmenovat své příklady a umístit je do smyslných balíčků.

Vrchol mé hierarchie balíčků bude:

com.javaworld.media 

Každé API nebo téma, o kterém píšu, bude mít pod touto nejvyšší úrovní alespoň jeden dílčí balíček. Například veškerý kód pro tento článek Java 2D bude v:

com.javaworld.media.j2d 

Chcete-li tedy vyvolat první ukázkovou aplikaci v prostředí Java 2D, stáhli byste kód, vložte jej do své cesty ke třídě a poté použijte:

java com.javaworld.media.j2d.Example01 

(Pokud je obor názvů příliš dlouhý podle vašich představ nebo z nějakého jiného důvodu chcete použít ukázkový kód, aniž byste museli používat plně kvalifikovaný název, jednoduše okomentujte řádek balíčku na začátku každého souboru zdrojového kódu.)

Vygeneruji soubor Java Archive (jar) pro ukázkový kód a soubory tříd každého článku. Tento archiv bude k dispozici ve zdrojích každého sloupce, pokud si jej chcete stáhnout a spustit příklady z archivu.

Budu také udržovat aktuální soubor jar obsahující veškerý kód a třídy z mého aktuálního a předchozího Programování médií sloupce. Tento všeobjímající soubor jar bude k dispozici na mém osobním webu.

Jedna poslední poznámka k příkladům: Každý příklad jsem se rozhodl vytvořit, pokud si výslovně nevšimnu jinak, samostatnou aplikaci nebo applet. To čas od času povede k určitému opakování kódu, ale mám pocit, že nejlépe zachovává integritu každého jednotlivého příkladu.

Dost o konvencích. Pojďme začít programovat s Java 2D!

Graphics2D: Lepší třída grafiky

Ústřední třídou v rámci Java 2D API je java.awt.Graphics2D abstraktní třída, které podtřídy java.awt. Grafika rozšířit funkčnost 2D vykreslování. Graphics2D přidává jednotnější podporu pro manipulaci s různými tvary, což ve skutečnosti umožňuje text, čáry a všechny druhy dalších dvourozměrných tvarů srovnatelných v jejich schopnostech a užitečnosti.

Začněme jednoduchým příkladem, který ukazuje, jak získáte a používáte a Graphics2d odkaz.

Balíček 001 com.javaworld.media.j2d; 002 003 import java.awt. *; 004 import java.awt.event. *; 005 006 veřejná třída Example01 rozšiřuje rámec {007 / ** 008 * Vytvoří instanci objektu Example01. 009 ** / 010 public static void main (String args []) {011 nový Example01 (); 012} 013 014 / ** 015 * Náš konstruktor Example01 nastaví velikost rámečku, přidá vizuální komponenty 016 * a poté je zviditelní pro uživatele. 017 * Používá třídu adaptéru, aby se vypořádal s tím, že uživatel zavře 018 * rámec. 019 ** / 020 public Example01 () {021 // Název našeho rámečku. 022 super („Java 2D Example01“); 023024 // Nastavení velikosti rámečku. 025 setSize (400 300); 026 027 // Musíme zapnout viditelnost našeho rámu 028 // nastavením parametru Viditelný na hodnotu true. 029 setVisible (true); 030 031 // Nyní si chceme být jisti, že řádně zlikvidujeme prostředky 032 // tento rámec používá, když je okno zavřené. K tomu používáme 033 // anonymní adaptér vnitřní třídy. 034 addWindowListener (new WindowAdapter () 035 {public void windowClosing (WindowEvent e) 036 {dispose (); System.exit (0);} 037} 038); 039} 040 041 / ** 042 * Metoda barvy poskytuje skutečné kouzlo. Tady jsme 043 * vrhli Graphics objekt na Graphics2D pro ilustraci 044 *, že můžeme použít stejné staré grafické schopnosti s 045 * Graphics2D, které jsme zvyklí používat s Graphics. 046 ** / 047 public void paint (Graphics g) {048 // Takto jsme nakreslili čtverec o šířce 049 // o 200, výšce 200 a počínaje x = 50, y = 50. 050 g. SetColor (Coloredred); 051 g.drawRect (50,50,200,200); 052 053 // Nastavíme Color na modrou a potom pomocí objektu Graphics2D 054 // nakreslíme obdélník, odsazený od čtverce. 055 // Zatím jsme pomocí Graphics2D neudělali nic, co jsme 056 // nemohli dělat ani pomocí Graphics. (Ve skutečnosti 057 // používáme metody Graphics2D zděděné od Graphics.) 058 Graphics2D g2d = (Graphics2D) g; 059 g2d.setColor (barva modrá); 060 g2d.drawRect (75,75,300,200); 061} 062} 

Když spustíte Příklad01, měli byste vidět červený čtverec a modrý obdélník, jak je znázorněno na obrázku níže. Všimněte si, že existuje známý problém s výkonem verze JDK 1.2 Beta 3 pro Windows NT / 95 (nejnovější verze 1.2 od tohoto sloupce). Pokud je tento příklad ve vašem systému bolestně pomalý, možná budete muset obejít chybu, jak je popsáno v JavaWorldJava Tip 55 (tento tip viz Zdroje níže).

Všimněte si, že stejně jako přímo nevytvoříte instanci Grafika objekt, nevytvoříte instanci a Graphics2D objekt. Modul runtime Java spíše vytvoří objekt vykreslení a předá jej malovat() (řádek 047 v seznamu kódů Example01) a na platformách Java 1.2 a dále tento objekt implementuje Graphics2D abstraktní třída také.

Doposud jsme s našimi 2D grafickými schopnostmi neudělali nic zvláštního. Pojďme přidat nějaký kód na konec našeho předchozího příkladu malovat() metoda a přinést několik nových funkcí Java 2D (Příklad02):

001 / ** 002 * Zde používáme nové funkce Java 2D API, jako jsou afinní 003 * transformace a objekty tvaru (v tomto případě obecná 004 * jedna, GeneralPath). 005 ** / 006 public void paint (Graphics g) {007 g.setColor (Color.red); 008 g.drawRect (50,50,200,200); 009 010 Graphics2D g2d = (Graphics2D) g; 011 g2d.setColor (barva modrá); 012 g2d.drawRect (75,75,300,200); 013 014 // Nyní nakreslíme další obdélník, ale tentokrát použijeme obecnou cestu k určení segmentu po segmentu. 016 // Dále se chystáme přeložit a otočit tento 017 // obdélník vzhledem k prostoru zařízení (a tedy k 018 // první dva čtyřúhelníky) pomocí AffineTransform. 019 // Změníme také jeho barvu. 020 Cesta GeneralPath = nová cesta GeneralPath (GeneralPath.EVEN_ODD); 021 path.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 path.closePath (); 026 027 AffineTransform at = nový AffineTransform (); 028 at.setToRotation (-Math.PI / 8.0); 029 g2d. Transformace (zavináč); 030 at.setToTranslation (50,0f, 200,0f); 031 g2d. Transformace (zavináč); 032 033 g2d.setColor (barva zelená); 034 g2d.fill (cesta); 035} 

Všimněte si, že od té doby GeneralPath se nachází v java.awt.geom balíček, musíme si být jisti, že přidáme také řádek importu:

importovat java.awt.geom. *; 

Výstup příkladu 02 je uveden na následujícím obrázku.

Java 2D umožňuje specifikaci libovolných tvarů pomocí java.awt.Shape rozhraní. Toto rozhraní implementuje celá řada výchozích tvarů, jako jsou obdélníky, polygony, 2D čáry atd. Jedním z nejzajímavějších z hlediska flexibility je java.awt.geom.GeneralPath.

GeneralPathvám umožní popsat cestu s libovolným počtem hran a potenciálně extrémně složitým tvarem. V příkladu 02 jsme vytvořili obdélník (řádky 020-025), ale stejně snadno jsme mohli přidat další stranu nebo strany, abychom vytvořili pětiúhelník nebo sedmiúhelník nebo nějaký jiný mnohostranný polygon. Všimněte si také, že na rozdíl od standardu Grafika kód, Java 2D nám umožňuje určit souřadnice pomocí čísel s plovoucí desetinnou čárkou místo celých čísel. Prodejci CAD na světě, radujte se! Ve skutečnosti Java 2D podporuje celé číslo, dvojnásobek, a plovoucí aritmetika na mnoha místech.

Pravděpodobně jste si také všimli, že když jsme vytvořili cestu, předali jsme parametr, GeneralPath.EVEN_ODD, do konstruktoru (řádek 020). Tento parametr představuje a vinutí pravidlo který řekne rendereru, jak určit vnitřek tvaru určeného naší cestou. Další informace o pravidlech navíjení Java 2D naleznete v dokumentaci Java 2D javadoc, na kterou se odkazuje v části Zdroje.

Další významná inovace v příkladu 02 se točí kolem použití a java.awt.geom.AffineTransforms (řádky 027-031). Specifika takových transformací nechám na čtenáři (viz Zdroje pro články, které o tom pojednávají podrobněji), ale stačí říct, že AffineTransformUmožňuje vám pracovat s libovolnou grafikou Java 2D a přeložit ji (přesouvat), otáčet, měnit její velikost, stříhat nebo provádět kombinace těchto manipulací.

Klíč k AffineTransform spočívá v pojetí Prostor zařízení a Uživatelský prostor. Prostor zařízení je oblast, do které se na obrazovce vykreslí grafika. To je analogické se souřadnicemi, které se používají při vytváření pravidelného stylu AWT Grafika- 2D grafika. Uživatelský prostor je však přeložitelný, otočný souřadný systém, který může být ovládán jedním nebo více AffineTransforms.

Souřadnicové systémy prostoru zařízení a prostoru uživatele se zpočátku překrývají s počátkem v levé horní části vykreslovací plochy (zde rámeček). Kladná osa x se pohybuje přímo od počátku, zatímco kladná osa y se pohybuje dolů.

Po první transformaci v Příkladu 02 (řádky 028 a 029) byl souřadný systém uživatelského prostoru otočen o 22,5 stupňů proti směru hodinových ručiček vzhledem k prostoru zařízení. Oba stále sdílejí stejný původ. (Všimněte si, že rotace jsou určeny v radiánech, přičemž -PI / 8 radiánů se rovná -22,5 stupňů nebo 22,5 stupňů CCW.) Pokud bychom se zde zastavili a nakreslili obdélník, otočil by se většinou mimo naše zorné pole v aplikace Rám.

Poté po dokončení rotace použijeme druhou transformaci (řádky 030 a 031), tuto translaci. Tím se posune souřadný systém uživatelského prostoru vzhledem k prostoru zařízení a posune se o 200,0 (plovoucí) jednotky a doprava o 50,0 (plovoucí) jednotky.

Když vyplníme zelený obdélník, bude přeložen a otočen vzhledem k prostoru zařízení.

Bezierových a vyšších řádků

Nyní, když jsme zkoumali, jak lze transformace použít k manipulaci s grafickými objekty, přezkoumejme, jak vytváříme složité a zajímavé libovolné tvary.

Křivky se používají v celé matematice a počítačové grafice k aproximaci složitých tvarů pomocí konečného, ​​dobře definovaného (a ideálně malého) počtu matematických bodů. Zatímco standardní AWT v minulosti přímo nepodporovalo kreslení s libovolnými křivkami (platformy Java 1.0 nebo 1.1), Java 2D přidává integrovanou podporu pro křivky prvního, druhého a třetího řádu. Křivky můžete nakreslit dvěma koncové body a nula, jedna nebo dvě kontrolní body. Java 2D vypočítává křivky prvního a druhého řádu pomocí lineárních a kvadratických vzorců a kubické nebo třetího řádu pomocí Bézierových křivek.

(Bézierovy křivky jsou typem parametrické polynomické křivky, které mají některé velmi žádoucí vlastnosti související s výpočtem uzavřených křivek a povrchů. Používají se v mnoha grafických aplikacích. Další informace o použití parametrických polynomů a Bézierových křivek najdete v části Zdroje. v počítačové grafice.) GeneralPath metody, které kreslí každou z těchto křivek, jsou:

  • lineTo () pro přímé segmenty (uveďte pouze koncové body)
  • quadTo () pro kvadratické křivky (uveďte jeden kontrolní bod)
  • curveTo () pro třetí objednané křivky (uveďte dva kontrolní body nakreslené pomocí kubické Bézierovy křivky)
$config[zx-auto] not found$config[zx-overlay] not found