[[oktatas:programozás:java|< Java]]
====== Java Swing Grafika ======
* **Szerző:** Sallai András
* Copyright (c) 2011, Sallai András
* Szerkesztve: 2011, 2013, 2014, 2015, 2021
* Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC BY-SA 4.0]]
* Web: https://szit.hu
===== 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ó.
{{:oktatas:programozás:java:koordinatarendszer.png|}}
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.
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.
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:
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.
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 =====
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 =====
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 =====
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.
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.
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.
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:
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.
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
===== Vonalak rajzolása =====
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 shapes = new ArrayList();
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.
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:
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)
===== Link =====
* https://www.oracle.com/java/technologies/painting.html (2021)