Java - Kresba
Základní entity a jejich kresba • ve třídě Graphics nemůžeme nastavit linii, šířku a typ, z grafických atributů jí můžeme nastavit pouze barvu • Linie (čára) ... drawLine(int x1, int y1, int x2, int y2) ... vykreslí linii, jdoucí z počátečního bodu P1[x1, y1] do koncového bodu P2[x2, y2]. • Eliptická výseč. ... drawArc(int x, int y, int sirka, int vyska, int start_uhel, int konc_uhel). Souřadnice x, y představují levý horní roh obdélníku zadané šířky a délky, do kterého je výseč vepsána, jsou dány počáteční a koncový úhel ovlivňující délku oblouku. • Elipsa ... drawOval(int x, int y, int sirka, int vyska) slouží k vykreslení elipsy vepsané do obdélníku zadané šířky a délky, jsou dány souřadnice levého horního rohu obdélníka. • Polygon ... polygon představuje uzavřenou oblast definovanou lomovými body spojenými úsečkami. Lze ho nakreslit metodou drawPolygon(), která je přetížená. Existují dvě varianty: drawPolygon(int [x], int [y], int pocet_vrcholu) a drawPolygon(Polygon p). V první je polygon defnován polem x-ových a y-ových souřadnic, druhý objektem typu polygon. • Polyline (lomená čára) ... drawPolyline( int [x], int [y], int pocet_vrcholu). Význam parametrů je stejný jako u polygonu. • Obdélník ... drawRect(int x, int y, int sirka, int vyska). Význam parametrů je stejný jako u elipsy. • 3D obdélník ... draw3DRect(int x, int y, int sirka, int vyska, boolean stav) vytvoří plastický obdélník připomínající tlačítko. Tlačítko může být zamáčklé nebo nezamáčklé, rozhoduje o tom booleovská proměnná stav. • Text ... drawString(String text, int x, int y) - text umístěný na specifické souřadnice. Vyplňování entit barvou • Útvary jsou standardně vyplňovány stejnou barvou, jakou byly nakresleny. Připomeňme metody setColor( Color c) a getColor() pro nastavení a získání barvy. Pokud chceme vyplnit útvar jinou barvou, než je nakreslen jeho obrys, nastavíme barvu pro výplň a vyplníme útvar, změníme barvu vykreslíme obrys útvaru. Parametry metod jsou stejné jako v případě metod pro kresbu nevyplněných entit. • Vyplněný 3D obdélník ... fill3DRect(int x, int y, int sirka, int vyska, boolean stav).
•
Vyplněná eliptická výseč ... fillArc(int x, int y, int sirka, int vyska, int
• •
start_uhel, int konc_uhel) Vyplněná elipsa ... fillOval(int x, int y, int sirka, int vyska) Vyplněný polygon ... fillPolygon(int [x], int [y], int pocet_vrcholu) nebo fillPolygon(Polygon p).
Grafický kontext • poskytuje uživatelský souřadnicový systém a vše, co potřebujeme ke kreslení čehokoliv na komponentě • grafický kontext = instance třídy Graphics (awt) nebo jeho potomka Graphics2D (swing) • Graphics i Graphics2D jsou abstraktní třídy • grafický kontext je vždy získán pro použití s konkrétní komponentou • instance třídy Graphics2D se stará o mapování uživatelských souřadnic na souřadnice strojové, zahrnuje informaci o stroji, který je cílem výstupu • odkaz na grafický kontext musíme mít předtím, než v něm začneme kreslit • odkaz na grafický kontext můžeme vždy získat také pomocí metody getGraphics()
2/28/11
1/8
Java - kresba
Kreslení • naše kreslící třída bude: ◦ potomkem třídy JComponent ◦ bude obsahovat metodu paint() nebo nověji paintComponent(), pomocí těchto metod kreslíme • grafický kontext je předán metodě paintComponent() • grafickému kontextu Graphics můžeme nastavit vlastnosti: ◦ barva ... g.setColor(Color barva) ◦ typ písma ... g.setFont(new Font("SansSerif",Font.ITALIC+Font.BOLD,20)); příklad 1a - Graphics: public class KresbaObrazce extends JComponent { public void paintComponent(Graphics g) { g.setColor(Color.BLUE); g.fillRect(40,50,300,200); g.setColor(Color.YELLOW); g.setFont(new Font("SansSerif",Font.ITALIC+Font.BOLD,20)); g.drawString("ahoj",160,160); }
}
•
•
grafickému kontextu Graphics2D můžeme nastavit vlastnosti: ◦ paint = kresba = barva ... g2D.setPaint() ◦ stroke = tah = styl čáry ◦ font = písmo ◦ transform = transformace ◦ clip = oříznutí ◦ composite = kompozice = jak budou kresleny překrývající se tvary můžeme použít metody pro kreslení: ◦ ◦ ◦ ◦
•
draw(Shape tvar) fill(Shape tvar) drawString(String text) drawImage()
metody pro překreslování ◦ paint() nebo nověji paintComponent() ... volána vždy, když má být komponenta rekonstruována, způsobí překreslení celé komponenty ◦ repaint() ... způsobí překreslení celé komponenty voláním metody paint() ▪ je přetížená ▪ jako parametr můžeme použít časový limit a oblast, která má být překreslena
příklad 1b - Graphics2D: public class KresbaObrazce extends JComponent { public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D)g; // musíme přetypovat g2d.setPaint(Color.RED); g2d.draw(new Rectangle(100,100,200,200)); g2d.setPaint(Color.GREEN); int[] x = {10, 240, 150}; int[] y = {30, 100, 310}; g2d.draw(new Polygon(x,y,3)); }
}
2/28/11
2/8
Java - kresba
•
Instanci třídy Kresba obrazce pak použijeme v hlavním okně GUI:
public class Platno extends JFrame { private Container obsah; private JPanel po; private KresbaObrazce ko; public Platno() { inicializace(); obsah(); zviditelneni(); } public void inicializace() { this.setSize(400,400); this.setTitle("Kreslící plátno"); obsah = this.getContentPane(); obsah.setLayout(new BorderLayout()); } public void obsah() { po = new JPanel(); po.setBackground(Color.WHITE); po.setLayout(new BorderLayout()); obsah.add(po, BorderLayout.CENTER); ko = new KresbaObrazce(); po.add(ko); }
}
public void zviditelneni () { this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setVisible(true); }
2/28/11
3/8
Java - kresba
Příklad 2: Přidáme si panel s možností volby obrazce a budeme reagovat na stisk odpovídajícího tlačítka: public class Platno extends JFrame { private private private private private
int sirka, vyska; Container obsah; JButton[] co = new JButton[3]; JPanel pb, po; KresbaObrazce ko;
public Platno(int sirka, int vyska) { this.sirka = sirka; this.vyska = vyska; inicializace(); obsah(); zviditelneni(); } public void inicializace() { this.setSize(sirka,vyska); this.setTitle("Plátno"); obsah = this.getContentPane(); obsah.setLayout(new BorderLayout()); } public void obsah() { pb = new JPanel(); this.getContentPane().add(pb, BorderLayout.NORTH); co[0] = new JButton("nakresli kruh"); co[1] = new JButton("nakresli obdélník"); co[2] = new JButton("napis text"); for (int i=0; i<3; i++) { pb.add(co[i]); co[i].addActionListener(new Kresba(i)); } po = new JPanel(); po.setBackground(Color.WHITE); po.setLayout(new BorderLayout()); this.getContentPane().add(po, BorderLayout.CENTER); ko = new KresbaObrazce(-1); po.add(ko); } /* handler = zobrazí odpovídající obrazec */ class Kresba implements ActionListener { int druh; public Kresba(int druh) { this.druh = druh; } public void actionPerformed(ActionEvent e) { kresli(e, druh); } } public void kresli(ActionEvent e, int druh) ko.setObrazec(druh); po.repaint(); }
{
public void zviditelneni () { this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setVisible(true); } }
2/28/11
4/8
Java - kresba
public class KresbaObrazce extends JComponent { private int druh; public KresbaObrazce(int druh) { this.druh=druh; } public void setObrazec(int druh) { this.druh=druh; } public void paintComponent(Graphics g) { switch (druh) { case -1: System.out.println("začátek"); break; case 0: g.setColor(Color.RED); g.drawOval(40,40,100,100); break; case 1: g.setColor(Color.BLUE); g.drawRect(100,200,120,60); break; case 2: g.setColor(Color.GREEN); g.setFont(new Font("SansSerif",Font.ITALIC+Font.BOLD,20)); g.drawString("ahoj",160,160); break; } } }
2/28/11
5/8
Java - kresba
Příklad 3: Vybudujeme vlastní garfické komponenty: public class Bod { private int x,y; public Bod(int x, int y) { this.x=x; this.y=y; } int getX() int getY()
{ return x; } { return y; }
} ---------------------------------------------------------------------------------public class Kruh { private int polomer; private Bod stred; public Kruh(Bod stred, int polomer) { this.stred = stred; this.polomer=polomer; } public Bod getStred() { return this.stred; } public int getPolomer() { return this.polomer; } } ---------------------------------------------------------------------------------import java.util.*; public class GenerujKruh { int sirka, vyska; int x, y, polomer; private Kruh k; Random rnd; public GenerujKruh(int sirka, int vyska) { this.sirka = sirka; this.vyska = vyska; rnd = new Random(); polomer = rnd.nextInt(sirka/6)+3; x = rnd.nextInt(sirka-2*polomer) + polomer; y = rnd.nextInt(vyska-2*polomer) + polomer; }
k = new Kruh(new Bod(x, y), polomer);
Kruh getKruh() { return k; } } ---------------------------------------------------------------------------------import java.awt.*; import javax.swing.JComponent;
2/28/11
6/8
Java - kresba
public class KresbaKruhu extends JComponent { private private private boolean
GenerujKruh kr; int sirka, vyska; Kruh k; kreslit;
public KresbaKruhu() { kreslit = false; } public void setKruh() { sirka = this.getWidth(); vyska = this.getHeight(); kr = new GenerujKruh(sirka, vyska); k = kr.getKruh(); kreslit = true; repaint(); } public void paintComponent(Graphics g) { if (kreslit) { g.setColor(Color.RED); int x = k.getStred().getX() - k.getPolomer(); int y = k.getStred().getY() - k.getPolomer(); g.drawOval(x, y, 2*k.getPolomer(), 2*k.getPolomer()); } } } ----------------------------------------------------------------------------------public class Platno extends JFrame { private private private private
int sirka, vyska; JButton tlac; JPanel pb, po; KresbaKruhu kk;
public Platno(int sirka, int vyska) { this.sirka = sirka; this.vyska = vyska; inicializace(); obsah(); } public void inicializace() { this.setSize(sirka,vyska); this.setTitle("Kružnice"); this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); this.setLayout(new BorderLayout()); } public void obsah() { pb = new JPanel(); this.getContentPane().add(pb, BorderLayout.NORTH); tlac = new JButton("generuj kruh"); pb.add(tlac); tlac.addActionListener(new Kresba()); po = new JPanel(); po.setBackground(Color.WHITE); po.setLayout(new BorderLayout()); this.getContentPane().add(po, BorderLayout.CENTER); kk = new KresbaKruhu(); po.add(kk); }
2/28/11
7/8
Java - kresba
/* handler = zobrazí odpovídající obrazec */ class Kresba implements ActionListener { public void actionPerformed(ActionEvent e) { kresli(e); } } public void kresli(ActionEvent e) kk.setKruh(); }
{
public static void main (String[] args) { Platno p = new Platno(500,700); p.setVisible(true); } }
2/28/11
8/8
Java - kresba