Java >> Java Tutorial >  >> Java

Java-AWT-Grafikbeispiel

Einführung

Die Java 2D API ist leistungsfähig und komplex. Die überwiegende Mehrheit der Anwendungen für die Java-2D-API nutzt jedoch eine kleine Teilmenge ihrer Fähigkeiten, die in java.awt.Graphics eingekapselt sind Klasse. Diese Lektion behandelt die häufigsten Anforderungen von Anwendungsentwicklern.
Die meisten Methoden der Graphics-Klasse können in zwei grundlegende Gruppen unterteilt werden:

    • Zeichen- und Füllmethoden, mit denen Sie grundlegende Formen, Text und Bilder rendern können.
    • Attributeinstellungsmethoden, die beeinflussen, wie diese Zeichnung und Füllung aussieht.

Methoden wie setFont und setColor definieren, wie Zeichen- und Füllmethoden gerendert werden.
Zu den Zeichenmethoden gehören:

      • drawString – Zum Zeichnen von Text
      • drawImage – Zum Zeichnen von Bildern
      • drawLine, drawArc, drawRect, drawOval, drawPolygon – Zum Zeichnen geometrischer Formen

Abhängig von Ihrem aktuellen Bedarf können Sie basierend auf den folgenden Kriterien eine von mehreren Methoden in der Graphics-Klasse auswählen:

      • Ob Sie das Bild an der angegebenen Stelle in Originalgröße rendern oder so skalieren möchten, dass es in das angegebene Rechteck passt.
      • Ob Sie die transparenten Bereiche des Bildes lieber mit Farbe füllen oder transparent halten möchten.

Füllmethoden gelten für geometrische Formen und umfassen fillArc, fillRect, fillOval, fillPolygon. Unabhängig davon, ob Sie eine Textzeile oder ein Bild zeichnen, denken Sie daran, dass in 2D-Grafiken jeder Punkt durch seine x- und y-Koordinaten bestimmt wird. Alle Zeichen- und Füllmethoden benötigen diese Informationen, die bestimmen, wo der Text oder das Bild gerendert werden soll..

Um beispielsweise eine Linie zu zeichnen, ruft eine Anwendung Folgendes auf:

AWTGraphicsExample.java

java.awt.Graphics.drawLine(int x1, int y1, int x2, int y2)

2. Die java.awt.Graphics-Klasse:Grafikkontext und benutzerdefiniertes Malen

Ein Grafikkontext stellt die Möglichkeiten zum Zeichnen auf dem Bildschirm bereit. Der Grafikkontext verwaltet Zustände wie die beim Zeichnen verwendete Farbe und Schriftart sowie die Interaktion mit dem zugrunde liegenden Betriebssystem, um das Zeichnen auszuführen. In Java erfolgt das benutzerdefinierte Malen über java.awt.Graphics Klasse, die einen Grafikkontext verwaltet und eine Reihe von geräteunabhängigen Methoden zum Zeichnen von Texten, Figuren und Bildern auf dem Bildschirm auf verschiedenen Plattformen bereitstellt.

Die java.awt.Graphics ist eine abstrakte Klasse, da der eigentliche Akt des Zeichnens system- und geräteabhängig ist. Jede Betriebsplattform stellt eine Unterklasse von Graphics bereit, um das eigentliche Zeichnen unter der Plattform auszuführen, entspricht jedoch der in Graphics definierten Spezifikation.

2.1 Zeichenmethoden der Grafikklasse

Die Graphics-Klasse stellt Methoden zum Zeichnen von drei Arten von grafischen Objekten bereit:

1.Textstrings:über drawString() Methode. Beachten Sie, dass System.out.println() auf der Systemkonsole druckt, nicht auf dem Grafikbildschirm.
2. Vektorgrafik-Primitive und Formen:über Methoden rawXxx() und fillXxx() , wobei Xxx Line, Rect, Oval, Arc, PolyLine, RoundRect oder 3DRect sein kann.
3.Bitmap-Bilder:über drawImage() Methode.

AWTGraphicsExample.java

// Drawing (or printing) texts on the graphics screen:
drawString(String str, int xBaselineLeft, int yBaselineLeft);
 
// Drawing lines:
drawLine(int x1, int y1, int x2, int y2);
drawPolyline(int[] xPoints, int[] yPoints, int numPoint);
 
// Drawing primitive shapes:
drawRect(int xTopLeft, int yTopLeft, int width, int height);
drawOval(int xTopLeft, int yTopLeft, int width, int height);
drawArc(int xTopLeft, int yTopLeft, int width, int height, int startAngle, int arcAngle);
draw3DRect(int xTopLeft, int, yTopLeft, int width, int height, boolean raised);
drawRoundRect(int xTopLeft, int yTopLeft, int width, int height, int arcWidth, int arcHeight)
drawPolygon(int[] xPoints, int[] yPoints, int numPoint);
 
// Filling primitive shapes:
fillRect(int xTopLeft, int yTopLeft, int width, int height);
fillOval(int xTopLeft, int yTopLeft, int width, int height);
fillArc(int xTopLeft, int yTopLeft, int width, int height, int startAngle, int arcAngle);
fill3DRect(int xTopLeft, int, yTopLeft, int width, int height, boolean raised);
fillRoundRect(int xTopLeft, int yTopLeft, int width, int height, int arcWidth, int arcHeight)
fillPolygon(int[] xPoints, int[] yPoints, int numPoint);
 
// Drawing (or Displaying) images:
drawImage(Image img, int xTopLeft, int yTopLeft, ImageObserver obs);  // draw image with its size
drawImage(Image img, int xTopLeft, int yTopLeft, int width, int height, ImageObserver o);  // resize image on screen

2.2 Methoden der Grafikklasse zur Aufrechterhaltung des Grafikkontexts

Der Grafikkontext hält Zustände (oder Attribute) aufrecht, wie z. B. die aktuelle Malfarbe, die aktuelle Schriftart zum Zeichnen von Textketten und den aktuellen rechteckigen Malbereich (genannt Clip). Sie können die Methoden getColor() verwenden , setColor() , getFont() , setFont() , getClipBounds() , setClip() , um die Farbe, die Schriftart und den Clip-Bereich abzurufen oder festzulegen. Jedes Malen außerhalb des Clip-Bereichs wird ignoriert.

AWTGraphicsExample.java

// Graphics context's current color.
void setColor(Color c)
Color getColor()
 
// Graphics context's current font.
void setFont(Font f)
Font getFont()

// Set/Get the current clip area. Clip area shall be rectangular and no rendering is performed outside the clip area.
void setClip(int xTopLeft, int yTopLeft, int width, int height)
void setClip(Shape rect)
public abstract void clipRect(int x, int y, int width, int height) // intersects the current clip with the given rectangle
Rectangle getClipBounds()  // returns an Rectangle
Shape getClip()            // returns an object (typically Rectangle) implements Shape

2.3 Andere Methoden der Grafikklasse

AWTGraphicsExample.java

void clearRect(int x, int y, int width, int height)
   // Clear the rectangular area to background
void copyArea(int x, int y, int width, int height, int dx, int dy)
   // Copy the rectangular area to offset (dx, dy).
void translate(int x, int y)
   // Translate the origin of the graphics context to (x, y). Subsequent drawing uses the new origin.
FontMetrics getFontMetrics()
FontMetrics getFontMetrics(Font f)
   // Get the FontMetrics of the current font / the specified font

2.4 Grafisches Koordinatensystem

Im Java Windowing Subsystem (wie bei den meisten 2D-Grafiksystemen) befindet sich der Ursprung (0,0) in der oberen linken Ecke.

JEDE Komponente/jeder Behälter hat sein eigenes Koordinatensystem, das wie dargestellt von (0,0) bis (Breite-1, Höhe-1) reicht.

Sie können die Methoden getWidth() und getHeight() verwenden, um die Breite und Höhe einer Komponente/eines Containers abzurufen. Sie können getX() oder getY() verwenden, um die obere linke Ecke (x,y) des Ursprungs dieser Komponente relativ zu ihrem übergeordneten Element zu erhalten.

3 benutzerdefinierte Malvorlage

Unter Swing wird benutzerdefiniertes Malen normalerweise durch Erweitern (d. h. Unterklassen) eines JPanel ausgeführt als Zeichenfläche und überschreiben paintComponent(Graphics g) -Methode, um Ihre eigene Zeichnung mit den von der Graphics-Klasse bereitgestellten Zeichenmethoden auszuführen. Das Java Windowing Subsystem ruft paintComponent(g) auf (ruft zurück). um JPanel zu rendern durch Bereitstellen des aktuellen Grafikkontextes g, der zum Aufrufen der Zeichenmethoden verwendet werden kann.

Das erweiterte JPanel wird oft als innere Klasse eines JFrame programmiert Anwendung zur Erleichterung des Zugriffs auf private Variablen/Methoden. Obwohl wir normalerweise auf die JPanel zurückgreifen , können Sie tatsächlich auf jeden beliebigen JComponent zurückgreifen (z. B. JLabel, JButton).

Die benutzerdefinierte Malcodevorlage lautet wie folgt:

AWTGraphicsExample.java

import java.awt.*;       // Using AWT's Graphics and Color
import java.awt.event.*; // Using AWT event classes and listener interfaces
import javax.swing.*;    // Using Swing's components and containers
 
/** Custom Drawing Code Template */
// A Swing application extends javax.swing.JFrame
public class CGTemplate extends JFrame {
   // Define constants
   public static final int CANVAS_WIDTH  = 640;
   public static final int CANVAS_HEIGHT = 480;
 
   // Declare an instance of the drawing canvas,
   // which is an inner class called DrawCanvas extending javax.swing.JPanel.
   private DrawCanvas canvas;
 
   // Constructor to set up the GUI components and event handlers
   public CGTemplate() {
      canvas = new DrawCanvas();    // Construct the drawing canvas
      canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));
 
      // Set the Drawing JPanel as the JFrame's content-pane
      Container cp = getContentPane();
      cp.add(canvas);
      // or "setContentPane(canvas);"
 
      setDefaultCloseOperation(EXIT_ON_CLOSE);   // Handle the CLOSE button
      pack();              // Either pack() the components; or setSize()
      setTitle("......");  // "super" JFrame sets the title
      setVisible(true);    // "super" JFrame show
   }
 
   /**
    * Define inner class DrawCanvas, which is a JPanel used for custom drawing.
    */
   private class DrawCanvas extends JPanel {
      // Override paintComponent to perform your own painting
      @Override
      public void paintComponent(Graphics g) {
         super.paintComponent(g);     // paint parent's background
         setBackground(Color.BLACK);  // set background color for this JPanel
 
         // Your custom painting codes. For example,
         // Drawing primitive shapes
         g.setColor(Color.YELLOW);    // set the drawing color
         g.drawLine(30, 40, 100, 200);
         g.drawOval(150, 180, 10, 10);
         g.drawRect(200, 210, 20, 30);
         g.setColor(Color.RED);       // change the drawing color
         g.fillOval(300, 310, 30, 50);
         g.fillRect(400, 350, 60, 50);
         // Printing texts
         g.setColor(Color.WHITE);
         g.setFont(new Font("Monospaced", Font.PLAIN, 12));
         g.drawString("Testing custom drawing ...", 10, 20);
      }
   }
 
   // The entry main method
   public static void main(String[] args) {
      // Run the GUI codes on the Event-Dispatching thread for thread safety
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new CGTemplate(); // Let the constructor do the job
         }
      });
   }
}

Analyse des Programms

        • Benutzerdefiniertes Malen wird durch Erweitern von JPanel durchgeführt (DrawCanvas genannt) und überschreibt paintComponent(Graphics g) -Methode, um mit den von der Graphics-Klasse bereitgestellten Zeichenmethoden eigene Zeichnungen zu erstellen.
        • DrawCanvas ist als innere Klasse dieser JFrame-Anwendung konzipiert, um den Zugriff auf die privaten Variablen/Methoden zu erleichtern.
        • Java Windowing Subsystem ruft paintComponent(g) auf (ruft zurück). um den JPanel zu rendern , mit dem aktuellen Grafikkontext in g, wann immer es notwendig ist, die Anzeige zu aktualisieren (z. B. beim ersten Start, Wiederherstellen, Ändern der Größe usw.). Sie können die Zeichenmethoden (g.drawXxx() und g.fillXxx()) im aktuellen Grafikkontext g verwenden, um benutzerdefiniertes Zeichnen auf JPanel auszuführen .
        • Die Größe des JPanel wird über den setPreferredSize() gesetzt . Der JFrame setzt nicht seine Größe, sondern packt die enthaltenen Komponenten per pack().
        • In main() wird der Konstruktor im Event-Dispatch-Thread über die statische Methode javax.swing.SwingUtilities.invokeLater() aufgerufen (anstatt im Haupt-Thread zu laufen), um Thread-Sicherheit zu gewährleisten und Deadlocks zu vermeiden, wie von den Swing-Entwicklern empfohlen.

3.1 Aktualisieren der Anzeige über repaint()

Manchmal müssen wir die Anzeige explizit aktualisieren (z. B. in Spielen und Animationen). Wir werden paintComponent(Graphics) NICHT aufrufen direkt. Stattdessen rufen wir die Methode repaint() von JComponent auf. Das Windowing-Subsystem ruft wiederum den paintComponent() zurück mit dem aktuellen Graphics-Kontext und führen Sie ihn aus Sicherheitsgründen im ereignisverteilenden Thread aus. Sie können einen bestimmten JComponent neu zeichnen() (z. B. ein JPanel) oder der gesamte JFrame . Die in JComponent enthaltenen untergeordneten Elemente wird auch neu lackiert.

4. Farben und Schriftarten

4.1 java.awt.Color

Die Klasse java.awt.Color stellt 13 Standardfarben als benannte Konstanten bereit. Sie sind:Farbe.ROT, GRÜN, BLAU, MAGENTA, CYAN, GELB, SCHWARZ, WEISS, GRAU, DUNKEL_GRAU, HELL_GRAU, ORANGE und PINK. (In JDK 1.1 sind diese Konstantennamen in Kleinbuchstaben, z. B. rot. Dies verstößt gegen die Java-Namenskonvention für Konstanten. In JDK 1.2 werden die Namen in Großbuchstaben hinzugefügt. Die Namen in Kleinbuchstaben wurden aus Gründen der Abwärtskompatibilität nicht entfernt.)

Sie können toString() verwenden, um die RGB-Werte dieser Farbe zu drucken (z. B. System.out.println(Color.RED)):

AWTGraphicsExample.java

RED       : java.awt.Color[r=255, g=0,   b=0]
GREEN     : java.awt.Color[r=0,   g=255, b=0]
BLUE      : java.awt.Color[r=0,   g=0,   b=255]
YELLOW    : java.awt.Color[r=255, g=255, b=0]
MAGENTA   : java.awt.Color[r=255, g=0,   b=255]
CYAN      : java.awt.Color[r=0,   g=255, b=255]
WHITE     : java.awt.Color[r=255, g=255, b=255]
BLACK     : java.awt.Color[r=0,   g=0,   b=0]
GRAY      : java.awt.Color[r=128, g=128, b=128]
LIGHT_GRAY: java.awt.Color[r=192, g=192, b=192]
DARK_GRAY : java.awt.Color[r=64,  g=64,  b=64]
PINK      : java.awt.Color[r=255, g=175, b=175]
ORANGE    : java.awt.Color[r=255, g=200, b=0]

Um die einzelnen Komponenten abzurufen, können Sie getRed(), getGreen(), getBlue(), getAlpha() usw. verwenden.

Um die Hintergrund- und Vordergrundfarbe (Textfarbe) einer Komponente/eines Containers festzulegen, können Sie Folgendes aufrufen:

AWTGraphicsExample.java

JLabel label = new JLabel("Test");
label.setBackground(Color.LIGHT_GRAY);
label.setForeground(Color.RED);

4.2 java.awt.Font

Die Klasse java.awt.Font stellt eine bestimmte Schriftart dar, die zum Rendern von Texten verwendet werden kann. Sie können den folgenden Konstruktor verwenden, um eine Font-Instanz zu erstellen:

AWTGraphicsExample.java

public Font(String name, int style, int size);
// name:  Family name "Dialog", "DialogInput", "Monospaced", "Serif", or "SansSerif" or
//        Physical font found in this GraphicsEnvironment.
//        You can also use String constants Font.DIALOG, Font.DIALOG_INPUT, Font.MONOSPACED, 
//          Font.SERIF, Font.SANS_SERIF (JDK 1.6)
// style: Font.PLAIN, Font.BOLD, Font.ITALIC or Font.BOLD|Font.ITALIC (Bit-OR)
// size:  the point size of the font (in pt) (1 inch has 72 pt).

Sie können den setFont() verwenden Methode zum Setzen der aktuellen Schriftart für den Graphics-Kontext g zum Rendern von Texten. Zum Beispiel,

AWTGraphicsExample.java

Font myFont1 = new Font(Font.MONOSPACED, Font.PLAIN, 12);
Font myFont2 = new Font(Font.SERIF, Font.BOLD | Font.ITALIC, 16);  // bold and italics
JButton btn = new JButton("RESET");
btn.setFont(myFont1);
JLabel lbl = new JLabel("Hello");
lbl.setFont(myFont2);
......
g.drawString("In default Font", 10, 20);     // in default font
Font myFont3 = new Font(Font.SANS_SERIF, Font.ITALIC, 12);
g.setFont(myFont3);
g.drawString("Using the font set", 10, 50);  // in myFont3

Familienname der Schriftart vs. Name der Schriftart

Eine Schriftart kann viele Gesichter (oder Stile) haben, z. B. einfach, fett oder kursiv. Alle diese Gesichter haben ein ähnliches typografisches Design. Der Schriftartname oder kurz Schriftartname ist der Name einer bestimmten Schriftart, wie „Arial“, „Arial Bold“, „Arial Italic“, „Arial Bold Italic“. Der Name der Schriftfamilie ist der Name der Schriftfamilie, die das typografische Design über mehrere Schriften hinweg bestimmt, wie „Arial“. Zum Beispiel,

AWTGraphicsExample.java

java.awt.Font[family=Arial,name=Arial,style=plain,size=1]
java.awt.Font[family=Arial,name=Arial Bold,style=plain,size=1]
java.awt.Font[family=Arial,name=Arial Bold Italic,style=plain,size=1]
java.awt.Font[family=Arial,name=Arial Italic,style=plain,size=1]

Logische Schriftart vs. physische Schriftart

JDK unterstützt diese logischen Schriftfamiliennamen:„Dialog“, „DialogInput“, „Monospaced“, „Serif“ oder „SansSerif“. JDK 1.6 bietet diese String-Konstanten:Font.DIALOG, Font.DIALOG_INPUT, Font.MONOSPACED, Font.SERIF, Font.SANS_SERIF.

Physische Schriftartnamen sind tatsächliche Schriftartbibliotheken wie „Arial“, „Times New Roman“ im System.

getAvailableFontFamilyNames() und getAllFonts() von GraphicsEnvironment

Sie können getAvailableFontFamilyNames() von GraphicsEnvironment verwenden, um alle Schriftfamiliennamen aufzulisten; und getAllFonts() zum Erstellen aller Font-Instanzen (mit einer Schriftgröße von 1 pt). Beispiel:
GraphicsEnvironment env =GraphicsEnvironment.getLocalGraphicsEnvironment();

AWTGraphicsExample.java

    
// Get all font family name in a String[]
String[] fontNames = env.getAvailableFontFamilyNames();
for (String fontName : fontNames) {
   System.out.println(fontName);
}
      
// Construct all Font instance (with font size of 1)
Font[] fonts = env.getAllFonts();
for (Font font : fonts) {
   System.out.println(font);
}

Die Ausgabe des Codes sieht bei der Ausführung wie folgt aus.

AWTGraphicsExample.java

5. Laden Sie den Quellcode herunter

Dies war ein Beispiel für die Erstellung von JAVA AWT Graphics.

Java-Tag