A rajzoló alrendszer először a paint() metódust hívja, ha rajzolni kell. A paint() metódus a következő három metódust hívja:
Rajzolhatunk mind a négy metódussal. Mi most a paint() metódussal kezdjük.
Látni fogjuk, hogy rajzolni többféle képen, szinten minden komponensre rajzolhatunk. Ez utóbbi lehetőség nem szokványos dolog. Sok programozói eszköztár nem teszi lehetővé minden komponensre való rajzolást.
Rendszerint a következő esetekben következik be:
A fenti esetekben végrehajtódik a paint() metódus.
Elsőként az ablakkeretre fogunk rajzolni. Elkészítünk egy ablakkeretet, majd a paint() metódussal rajzolunk rá. A rajzolómetódus előtt meg kell adni, hogy milyen színnel szeretnénk rajzolni. A rajzolás során x, y koordinátákat adunk, a rajz elhelyezéséhez. Az x a vízszintes, az y a függőleges koordináta. A kezdőpont a bal felső sarok. Vagyis a bal felső sarok a 0,0 origó.
import javax.swing.JFrame; import java.awt.Graphics; import java.awt.Color; class Program01 extends JFrame { Program01() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program01(); } @Override public void paint(Graphics g) { g.setColor(Color.BLUE); g.fillRect(30, 30, 100, 30); } }
Ügyeljünk arra, hogy ha keretre rajzolunk, akkor a vízszintes 0 az ablak tetején van, és nem a címsornál kezdődik.
Elemezzük a g.fillRect(30, 30, 100, 30); metódust. A metódus egy téglalapot rajzol az ablakkeretre. Az első két koordináta x, y. A másik kettő, szélesség és magasság. Ezek után általánosan így írhatjuk fel:
g.fillRect(x, y, szélesség, magasság);
Fentebb már láttuk, hogy az x a vízszintes koordináta, az y a függőleges.
Adott színek:
Saját szín megadása, például királykék:
g.setColor(new Color(0, 0, 80));
A színt RGB kódolással keverjük ki.
Néhány rajzolómetódus:
Ha AWT vagy Swing komponenseket is használunk, akkor a grafika nem jelenik meg. A super.paint(g) meghívásával, viszont megrajzolódik.
import javax.swing.JFrame; import javax.swing.JButton; import java.awt.Graphics; import java.awt.Color; class Program01 extends JFrame { JButton button = new JButton("Kattints"); Program01() { button.setLocation(25, 30); button.setSize(100, 30); setLayout(null); add(button); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String args[]) { new Program01(); } @Override public void paint(Graphics g) { super.paint(g); g.setColor(Color.BLUE); g.fillRect(150, 30, 100, 30); } }
A JComponent osztályból készíthetünk újabb komponenseket.
import javax.swing.JFrame; import javax.swing.JComponent; import java.awt.Graphics; import java.awt.Color; class Program01 extends JFrame { SajatKomponens sk = new SajatKomponens(); Program01() { this.add(sk); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program01(); } } class SajatKomponens extends JComponent { public void paint(Graphics g) { g.setColor(Color.BLUE); g.fillRect(30, 30, 100, 30); } }
Ha valamilyen komponensre rajzolunk, akkor felülírhajtuk a paintComponent() metódust is:
import javax.swing.JFrame; import javax.swing.JComponent; import java.awt.Graphics; import java.awt.Color; class Program01 extends JFrame { SajatKomponens sk = new SajatKomponens(); Program01() { this.add(sk); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program01(); } } class SajatKomponens extends JComponent { @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillRect(30, 30, 100, 30); } }
A JPanel osztályból örökítem a főosztályt, majd egy JFrame ablakot hozok létre az osztályon belül és ehhez hozzáadom a főosztályt konstruktorként meghívva.
import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Program2 extends JPanel { public static void main(String[] a) { JFrame ablak = new JFrame(); ablak.setSize(400, 400); ablak.add(new Program2()); ablak.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ablak.setVisible(true); } public void paint(Graphics g) { g.setColor (Color.red); /* Az utolsó két paraméter fokban van megadva. A fokokat ha óraszámlaphoz hasonlítom, akkor a kezdés 3 óránál van. x, y, szélesség, magasság, kezdés_fok, hozzáadott_fok */ g.drawArc (5, 15, 50, 75, 25, 165); } }
import javax.swing.JFrame; import javax.swing.JButton; import java.awt.Graphics; import java.awt.Color; class Program04 extends JFrame { SajatGomb gomb = new SajatGomb(); Program04() { gomb.setLocation(25, 25); gomb.setSize(100, 30); this.setLayout(null); this.add(gomb); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setSize(400, 300); this.setVisible(true); } public static void main(String args[]) { new Program04(); } } class SajatGomb extends JButton { @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Color.BLUE); g.fillRect(5, 5, 10, 10); } }
Ha nem hívjuk meg a super.paintComponent(g) utasítást, akkor nem rajzolódik ki minden részlet, de így járunk akkor is, ha paintComponent(Graphics g) helyett csak a paint(Graphics g) metódust írjuk át.
import javax.swing.*; import java.awt.*; class Program extends JFrame { Program() { getContentPane().add(new SajatKomponens()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } public class SajatKomponens extends JComponent { public void paint(Graphics g) { g.setColor(Color.blue); g.drawRect(10, 10, 50, 50); } } }
import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; public class Program2 { SajatPanel panel1; JFrame ablak; Program2() { panel1 = new SajatPanel(); ablak = new JFrame(); ablak.setSize(400, 400); ablak.add(panel1); ablak.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ablak.setVisible(true); } public static void main(String[] a) { new Program2(); } class SajatPanel extends JPanel { public void paint(Graphics g) { g.setColor (Color.red); g.drawArc (5, 15, 50, 75, 25, 165); } } }
A következő nem éppen grafika, de a látvány inkább közel áll ahhoz.
import javax.swing.*; import java.awt.*; class Program extends JFrame { JPanel panel1; JPanel panel2; Program() { panel1 = new JPanel(); panel2 = new JPanel(); panel1.setSize(200, 200); panel1.setLocation(50, 50); panel1.setBackground(Color.blue); panel2.setSize(200, 200); panel2.setLocation(50, 280); panel2.setBackground(Color.red); this.setLayout(null); this.add(panel1); this.add(panel2); this.setSize(800, 600); this.setLocationRelativeTo(null); this.setVisible(true); } public static void main(String args[]) { new Program(); } }
A Graphics2D osztály a Graphics osztály kiterjesztése, amely lehetővé teszi fejlettebb geometriai alakzatok, koordináta transzformációkat, színkezelést, szövegelrendezést.
import javax.swing.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Line2D; class Program extends JFrame { Program() { getContentPane().add(new SajatKomponens()); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String args[]) { new Program(); } public class SajatKomponens extends JComponent { public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.blue); Line2D lin = new Line2D.Float(100, 100, 250, 260); g2.draw(lin); } } }
A példából láthatjuk, hogy a Graphics2D objektumot a Graphics objektumból készítjük típuskényszerítéssel.
A Canvas osztály direkt rajzolófelületnek tervezték.
import java.awt.*; import javax.swing.*; class Program extends JFrame { Canvas vaszon = new Vaszon(); Program() { add(vaszon); setSize(300, 200); setVisible(true); } class Vaszon extends Canvas { public void paint(Graphics g) { g.drawLine(10,10, 50, 50); } } public static void main(String args[]) { new Program(); } }
A példában egy Canvas osztályból egy beépített osztályt készítünk.
Ha egy panelen megvalósítjuk a paint() metódust, akkor elveszti a háttérszínét. Ezért a paint() metódusban egy megkerülőmegoldást alkalmazunk, a komponenssel egyező nagyságú téglalapot rajzolunk:
import javax.swing.*; import java.awt.*; class SajatPanel extends JPanel { SajatPanel() { setBackground(Color.blue); setBounds(100, 100, 300, 300); } public void paint(Graphics g) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(getForeground()); Color szin = new Color(0,0,255); g.setColor(szin); g.drawString("valami", 50, 10); } } class Program extends JFrame { SajatPanel panel; Program() { panel = new SajatPanel(); panel.setBackground(Color.blue); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(null); add(panel); setSize(800, 600); setVisible(true); } public static void main(String[] argv) { new Program(); } }
Az ide vonatkozó rész:
g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), getHeight()); g.setColor(getForeground());
A fontbeállítás egyik eszköze a Font osztály. A Font osztály konstruktorának paramétereként megadható a fontcsalád, a font stílusa és a font mérete.
Font courier = new Font ("Courier", Font.PLAIN, 12); Font system = new Font ("System", Font.BOLD, 16); Font helvetica = new Font ("Helvetica", Font.BOLD, 18); g.setFont (courier); g.drawString ("Courier", 10, 30); g.setFont (system); g.drawString ("System", 10, 70); g.setFont (helvetica); g.drawString ("Helvetica", 10, 90);
A következő példában lekérdezzük a font minden tulajdonságát, majd beállítjuk csak a méretét:
Font eredetiFont = g.getFont(); Font ujFont = eredetiFont.deriveFont(eredetiFont.getSize() * 1.4F); g.setFont(ujFont);
Sokszög rajzolására külön osztály áll rendelkezésre, a Polygon. A Polygon osztály objektumához pontokat tudunk hozzáadni. Minden pontot x, y koordinátával adunk meg. Végül a fillPolygon() metódussal rajzoljuk meg.
import javax.swing.JFrame; import java.awt.Canvas; import java.awt.Graphics; import java.awt.Color; import java.awt.Polygon; class Program01 extends JFrame { RajzVaszon rajzVaszon = new RajzVaszon(); Program01() { add(rajzVaszon); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setVisible(true); } public static void main(String[] args) { new Program01(); } } class RajzVaszon extends Canvas { public void paint(Graphics g) { g.setColor(Color.red); Polygon poly = new Polygon(); poly.addPoint(200, 200); poly.addPoint(250, 250); poly.addPoint(250, 300); g.fillPolygon(poly); } }
A fillPolygon() metódus három paramétert is fogadhat, ahol tömbként adom át a pontok koordinátáit. A pontokat két külön tömbben adjuk meg, harmadik paraméterként a pontok száma.
int xpoints[] = {30, 150, 30, 150, 30}; int ypoints[] = {30, 30, 150, 150, 30}; int npoints = 5; g.fillPolygon(xpoints, ypoints, npoints);
class SajatCanvas extends java.awt.Canvas { SajatCanvas() { setSize(800, 600); } public void paint(java.awt.Graphics g) { drawHorizontalRule(g); drawVerticalRule(g); drawContent(g); } public void drawContent(java.awt.Graphics g) { //Ide rajzolunk } public void drawHorizontalRule(java.awt.Graphics g) { java.awt.Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); int width = (int) dim.getWidth(); g.drawLine(5, 5, width, 5); for(int i=5; i<width; i++) { if((i%10)==0) g.drawLine(i, 5, i, 10); if((i%50)==0) { g.drawLine(i, 5, i, 15); g.drawString(Integer.toString(i), i, 30); } if((i%100)==0) g.drawLine(i, 5, i, 20); } } public void drawVerticalRule(java.awt.Graphics g) { java.awt.Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); int height = (int) dim.getHeight(); g.drawLine(5, 5, 5, height); for(int i=5; i<height; i++) { if((i%10)==0) g.drawLine(5, i, 10, i); if((i%50)==0) { g.drawLine(5, i, 15, i); g.drawString(Integer.toString(i), 30, i); } if((i%100)==0) g.drawLine(5, i, 20, i); } }
A következő példa vonalak rajzolását mutatja be, egérrel.
import javax.swing.*; import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import java.util.*; class Program01 { public static void main ( String[] args ) { JFrame paint = new JFrame (); paint.add ( new JComponent () { private ArrayList<Shape> shapes = new ArrayList<Shape>(); private Shape currentShape = null; { MouseAdapter mouseAdapter = new MouseAdapter () { public void mousePressed ( MouseEvent e ) { currentShape = new Line2D.Double ( e.getPoint (), e.getPoint () ); shapes.add ( currentShape ); repaint (); } public void mouseReleased ( MouseEvent e ) { currentShape = null; repaint (); } public void mouseDragged ( MouseEvent e ) { Line2D shape = ( Line2D ) currentShape; shape.setLine ( shape.getP1 (), e.getPoint () ); repaint (); } }; addMouseListener ( mouseAdapter ); addMouseMotionListener ( mouseAdapter ); } protected void paintComponent ( Graphics g ) { Graphics2D g2d = ( Graphics2D ) g; g2d.setPaint ( Color.BLACK ); for ( Shape shape : shapes ) { g2d.draw ( shape ); } } } ); paint.setSize ( 500, 500 ); paint.setLocationRelativeTo ( null ); paint.setVisible ( true ); } }
A panelt mintegy kép tárolójaként használjuk a következő példában.
import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Image; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.ImageIcon; class ImagePanel extends JPanel { private Image img; ImagePanel(Image img) { this.img = img; setPreferredSize(new Dimension(200, 200)); setLayout(null); } public void paintComponent(Graphics g) { g.drawImage(img, 0, 0, null); } } class Program01 extends JFrame { ImagePanel imagePanel = new ImagePanel(new ImageIcon("kep.png").getImage()); Program01() { add(imagePanel); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public static void main(String[]args) { new Program01(); } }
Két új osztályt is használunk, az Image és az ImageIcont.
Eseménykezelőből azért különleges a rajzolás, mert ezt a paint() metódusból szoktuk végezni, ahol paraméterként megkapjunk egy java.awt.Graphics objektumot. Az eseménykezelőben viszont nincs a formális paraméterek között ilyen objektum. Ezen segít a getGraphics() metódus, amelyet a JPanel objektumon hívhatunk meg.
Az alábbi példában átkonvertáljuk Graphics2D objektummá.
private void jButtonMouseClicked(java.awt.event.MouseEvent evt) { Graphics2D gfx = (Graphics2D)jPanel1.getGraphics(); gfx.drawLine(0, 0, 100, 100); }
A teljes példa:
import javax.swing.JFrame; import javax.swing.JButton; import java.awt.Graphics; import java.awt.Color; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; class Program01 extends JFrame { final static long serialVersionUID = 1; JButton button = new JButton("Kattints"); Program01() { button.setLocation(25, 30); button.setSize(100, 30); button.addMouseListener(new MouseListener(){ public void mouseExited(MouseEvent evt) { } public void mouseEntered(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void mousePressed(MouseEvent evt) { } public void mouseClicked(MouseEvent evt) { buttonMouseClick(evt); } }); setLayout(null); add(button); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(400, 300); setVisible(true); } public void buttonMouseClick(MouseEvent evt) { Graphics g = getGraphics(); g.setColor(Color.BLUE); g.fillRect(150, 30, 100, 30); } public static void main(String args[]) { new Program01(); } }
clearRect(int x, int y, int width, int height)