2 Grafický výstup s využitím knihovny Studijní cíl Tento blok je věnován základním principům při vytváření grafického výstupu pomocí standardních metod, které poskytuje grafické rozhraní. V textu budou objasněny principy zobrazení grafického výstupu, jednotlivé zobrazovací metody, pojem grafický kontext, základní práce s barvami, kreslení základních grafických primitiv a zobrazení textu.
Doba nutná k nastudování
3-4 hodiny
Průvodce studiem Při studiu tohoto bloku se předpokládá, že student ovládá základy programování v jazyce Java a je schopen vytvářet jednoduché aplikace s využitím grafického uživatelského rozhraní.
2.1 Program s grafickým výstupem V minulém bloku byly vysvětleny principy vytváření aplikací s využitím grafického uživatelského rozhraní (GUI). To samo o sobě znamená pouze to, že programy využívají pro komunikaci s uživatelem rozhraní, které je v grafickém režimu. Program „běží“ v okně, jenž může obsahovat různé ovládací prvky, a celé je to řešeno v grafickém nikoliv textovém režimu. V tomto bloku bude cílem naučit se vytvářet s využitím standardních grafických metod takové programy, které budou schopny produkovat na obrazovce (respektive v okně aplikace) určitý grafický výstup. Ke splnění tohoto cíle je znát: Co se má kreslit obecně data, která specifikují rastrový nebo vektorový obraz; Jak se to nakreslí kreslící metody, které realizují příslušný grafický výstup;
KST/IPOGR Počítačová grafika
1-1
Petr Veselý KST FEI Univerzita Pardubice
Kdy se to nakreslí správné umístění kreslících metod v kódu tak, aby byl výstup realizován právě tehdy, když je to potřeba.
2.2 Princip zobrazování obsahu V dalším výkladu budeme předpokládat výstup na zařízení typu monitor, neboť výstup na tiskové výstupní zařízení probíhá v některých aspektech odlišně. Grafický výstup probíhá vždy (mimo specifických případů kreslení na celou plochu obrazovky) na plochu určité vizuální komponenty, která je k tomu určena. Překreslení (vykreslení) obsahu komponenty se realizuje při příchodu zprávy „paint“. Standardně se o zobrazení stará samostatné vlákno a principiálně nelze určit přesný okamžik vykreslení. I v případě, že je požadováno okamžité překreslení obsahu komponenty, je obsah vykreslen při nejbližším vhodném okamžiku. Rodičovská komponenta zabezpečí překreslení dceřiných komponent (tj. těch, které jsou vloženy do jejího kontejneru). Každá komponenta je zodpovědná za svůj obsah, to znamená, že každá komponenta musí znát jak má vypadat a co má výt na její ploše zobrazeno. Při vykreslování komponent je důležité je pořadí komponent (z-order).
Obrázek 1: Hierarchické uspořádání komponent ovlivní pořadí vykreslování
KST/IPOGR Počítačová grafika
1-2
Petr Veselý KST FEI Univerzita Pardubice
2.3 Zobrazovací metody Zobrazovací metody jsou odpovědí na otázku „kdy, v které části kódu kreslit“. Kód pro zobrazení (co se má vykreslit) je v metodě: paint (Graphics g) pro AWT paintComponent (Graphics g) pro Swing Tyto zděděné prázdné metody je třeba přepsat (+ volání metody předka). Pro zobrazení komponenty se volá: clearRect(…), která zabezpečí vymazání plochy (části) barvou pozadí; paintComponent(…) případně paint(…), která provede vykreslení obsahu Pro programové překreslení se volá metoda: repaint(), která dále volá metodu
update (Graphics g) { g.clearRect(…)
// zabezpečí vymazání
paintComponent(g);
// respektive paint (g);
}
Přepsáním metody update(), tak, že vynecháme volání clearRect(…), lze zabezpečit NEPŘEMAZÁVÁNÍ původního obsahu
2.4 Grafický kontext Z pohledu programování grafických aplikací pro operační systém, který používá grafické uživatelské rozhraní (systém oken) je každá komponenta oknem, to znamená určitou oblastí na obrazovce, do které může být směřován grafický výstup. Pro kreslení do libovolného okna je potřeba jednoznačně z pohledu operačního systému specifikovat okno, kam bude výstup směřovat a získat pro toto okno tzv. grafický kontext. V knihovnách AWT a JFC je grafický kontext zapouzdřen KST/IPOGR 1-3 Petr Veselý Počítačová grafika KST FEI Univerzita Pardubice
do třídy Graphics a Graphics2D, které nám poskytují především jednotlivé kreslící metody pro realizaci grafického výstupu v daném okně. Jinými slovy: při požadavku na kreslení na plochu určité komponenty (okna) je třeba získat instanci třídy Graphics (nebo Graphics2D) pro danou komponentu a pomocí kreslících metod získané instance realizovat požadovaný výstup. Třída Graphics je v balíčku java.awt. V Javě je grafický kontext STAVOVÝ (pamatuje si stav, např. nastavenou barvu). Instanci třídy Graphics lze získat pro každou třídu, která je potomkem Components. Instanci třídy Graphics nelze vytvořit pomocí konstruktoru, ale lze ji získat: jako parametr v zobrazovacích metodách paint a paintComponent; pomocí metody getGraphics(), která vytvoří nový grafický kontext pro danou komponentu.
2.5 Double Buffering Double Buffering je technika, zamezující „blikání“ obrazu při překreslování obsahu komponenty, ke kterému dochází díky cyklickému opakování rychle se střídajících jednotlivých fází při kreslení, jak je naznačeno na následujícím obrázku.
hotový snímek vymazání obsahu postupné vykreslení jednoho objektu vykreslení dalšího objektu … = hotový snímek
Obrázek 2: Fáze při animaci objektu (pohybující se auto)
KST/IPOGR Počítačová grafika
1-4
Petr Veselý KST FEI Univerzita Pardubice
Princip Double Bufferingu spočívá v to, že místo vykreslování jednotlivých fází při komponování výsledného obrazu přímo na výstupní zařízení, je obraz postupně (tak jak vzniká) vykreslován do pomocné obrazové paměti (tzv. zadní plátno) a teprve v okamžiku, kdy je obraz zcela hotov, je kompletně přenesen na zobrazovací zařízení. Tím je zamezeno střídání se zobrazení částí obrazu a samotného pozadí, které způsobovalo nepříjemný efekt „blikání“.
Obrázek 3: Princip Double Bufferingu
2.6 Kreslení grafických primitiv Mezi základní grafické primitivy, jejichž zobrazení podporuje třída Graphics, patří úsečka, lomená čára, pravoúhelník se stranami rovnoběžnými s osami souřadnicového systému, pravoúhelník se zaoblenými rohy, elipsa (kuželosečka) v základní poloze, eliptický oblouk, eliptická výseč, mnohoúhelník, text a rastrový obrázek (bitmapa). Základní kreslící metody třídy Graphic lze rozdělit na zobrazení textu drawString, zobrazení rastrového obrázku drawImage, zobrazení liniových objektů (případně zobrazení obrysu plošných objektů) drawXXX a zobrazení výplně plošných objektů fillXXX. KST/IPOGR 1-5 Petr Veselý Počítačová grafika KST FEI Univerzita Pardubice
Obrázek 4: Grafické primitivy, které je možno zobrazit pomocí metod třídy Graphics
2.6.1 Úsečka, lomená čára
void drawLine(int x1, int y1, int x2, int y2)
[x1, y1] představuje počáteční bod, [x2, y2] představuje koncový bod. Metoda kreslí čáru včetně počátečního a koncového bodu.
void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
Metoda kreslí lomenou čáru mezi jednotlivými body. Jejich souřadnice jsou uloženy v polích xPoints a yPoint. Parametr nPoints určuje, kolik prvků z polí souřadnic bude použito. Pokud je poslední a první bod totožný, je lomená čára uzavřena. 2.6.2 Pravoúhelník
void drawRect(int x, int y, int width, int height)
Levý horní roh je určen bodem se souřadnicemi [x, y], pravý dolní roh je určen bodem se souřadnicemi [x+width, y+height].
void fillRect(int x, int y, int width, int height)
Levý horní roh je určen bodem se souřadnicemi [x, y], pravý dolní roh je určen bodem se souřadnicemi [x+width-1, y+height-1].
KST/IPOGR Počítačová grafika
1-6
Petr Veselý KST FEI Univerzita Pardubice
2.6.3 Pravoúhelník s oblými rohy
void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
Obrys pravoúhelníku se zakulacenými rohy je vykreslen rohovými oblouky o horizontálním poloměru arcWidth a vertikálním poloměru arcHeight. Rozměry jsou totožné s drawRect.
void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
Výplň pravoúhelníku se zakulacenými rohy je vykreslena rohovými oblouky o horizontálním poloměru arcWidth a vertikálním poloměru arcHeight. Rozměry jsou totožné s fillRect.
Pojmy k zapamatování Grafický kontext, Graphics, Double Buffering, z-order, grafická primitiva,
Otázky na procvičení 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Jaký je princip obnovování obsahu okna (komponenty)? Na čem závisí pořadí překreslování jednotlivých komponent? Co je to grafický kontext? Do jaké třídy je zapouzdřen v knihovnách AWT a JFC? Jaké metody poskytuje třída Graphics? Jak lze získat instanci třídy Graphics? Co to znamená, když je grafický kontext stavový? Které metody jsou zodpovědné za obsah okna (komponenty)? Co je to a jak funguje Double Buffering? Jakým způsobem se nastavuje barva pro kreslení?
Odkazy a další studijní prameny
http://owebu.bloger.cz/Programovani/Java-Grafika-59-dil http://java.sun.com/docs/books/tutorial/2d/index.html http://www.linuxsoft.cz/article.php?id_article=244 Herout, P. Java a grafické uživatelské prostředí. České Budějovice : Koop, 2007.
KST/IPOGR Počítačová grafika
1-7
Petr Veselý KST FEI Univerzita Pardubice