Felhasználói eszközök

Eszközök a webhelyen


oktatas:programozas:java:java_gui_swing_grafika

< Java

Java Swing Grafika

  • Szerző: Sallai András
  • Copyright © 2011, Sallai András
  • Szerkesztve: 2011, 2013, 2014, 2015, 2021
  • Licenc: CC BY-SA 4.0

A rajzolásról

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:

  • paintComponent()
  • paintBorder()
  • paintChildren()

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.

Rendszer által kiváltott rajzolás

Rendszerint a következő esetekben következik be:

  • megjelenik egy komponens
  • a komponens átméreteződik
  • a komponens változik (például láthatóvá válik egy eddig kitakart rész)

A fenti esetekben végrehajtódik a paint() metódus.

Rajzolás a keretre

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ó.

Program01.java
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:

  • Color.BLACK
  • Color.BLUE
  • Color.CYAN
  • Color.DARK_GRAY
  • Color.GRAY
  • Color.GREEN
  • Color.LIGHT_GRAY
  • Color.MAGENTA
  • Color.ORANGE
  • Color.PINK
  • Color.RED
  • Color.WHITE
  • Color.YELLOW

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:

  • drawLine(int x1, int y1, int x2, int y2)
  • drawOval(int x, int y, int width, int height)
  • drawRect(int x, int y, int width, int height)
  • drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
  • drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)
  • draw3DRect(int x, int y, int width, int height, boolean raised)
  • drawString(String str, int x, int y)
  • fillOval(int x, int y, int width, int height)
  • fillRect(int x, int y, int width, int height)
  • fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)
  • fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)
  • fill3DRect(int x, int y, int width, int height, boolean raised)

Rajzolás keretre és komponenshasználat

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.

Program01.java
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);
	}
}

Rajzolás JComponentre

A JComponent osztályból készíthetünk újabb komponenseket.

Program01.java
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);
	}	
}

A paintComponent()

Ha valamilyen komponensre rajzolunk, akkor felülírhajtuk a paintComponent() metódust is:

Program01.java
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);
	}	
}

Ablak a panelosztályban

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.

Program2.java
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);
	}
}

Rajzolás nyomógombra

Program01.java
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.

Csak rajz

Program.java
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);
		}
	}
}

Saját panel osztály

Program2.java
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);
		}
	}
}

Két színes panel

A következő nem éppen grafika, de a látvány inkább közel áll ahhoz.

Program.java
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();
	}
}

Graphics2D

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.

Program.java
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.

Canvas osztály

A Canvas osztály direkt rajzolófelületnek tervezték.

Program
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.

Háttérszín rajzoláskor

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:

Program.java
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());

Fontbeállítás

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ása

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.

Program01.java
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);

Koordináta rendszer rajzolása

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);
		}		
	}

Vonalak rajzolása

A következő példa vonalak rajzolását mutatja be, egérrel.

Program01.java
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 );
	}
 
}

Kép panelon

A panelt mintegy kép tárolójaként használjuk a következő példában.

Program01.java
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.

Rajzolás eseménykezelőből

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:

Program01.java
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();
	}
}

Törlés

clearRect(int x, int y, int width, int height)
oktatas/programozas/java/java_gui_swing_grafika.txt · Utolsó módosítás: 2023/08/03 19:29 szerkesztette: admin