Java AWT Graphics Example


The Java 2D API is powerful and complex. However, the vast majority of uses for the Java 2D API utilize a small subset of its capabilities encapsulated in the java.awt.Graphics class. This lesson covers the most common needs of applications developers.
Most methods of the Graphics class can be divided into two basic groups:

Methods such as setFont and setColor define how draw and fill methods render.
Drawing methods include:

Depending on your current need, you can choose one of several methods in the Graphics class based on the following criteria:

Fill methods apply to geometric shapes and include fillArc, fillRect, fillOval, fillPolygon. Whether you draw a line of text or an image, remember that in 2D graphics every point is determined by its x and y coordinates. All of the draw and fill methods need this information which determines where the text or image should be rendered..

For example, to draw a line, an application calls the following:

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

2. The java.awt.Graphics Class: Graphics Context and Custom Painting

A graphics context provides the capabilities of drawing on the screen. The graphics context maintains states such as the color and font used in drawing, as well as interacting with the underlying operating system to perform the drawing. In Java, custom painting is done via the java.awt.Graphics class, which manages a graphics context, and provides a set of device-independent methods for drawing texts, figures and images on the screen on different platforms.

The java.awt.Graphics is an abstract class, as the actual act of drawing is system-dependent and device-dependent. Each operating platform will provide a subclass of Graphics to perform the actual drawing under the platform, but conform to the specification defined in Graphics.

2.1 Graphics Class’ Drawing Methods

The Graphics class provides methods for drawing three types of graphical objects:

1.Text strings: via the drawString() method. Take note that System.out.println() prints to the system console, not to the graphics screen.
2.Vector-graphic primitives and shapes: via methods rawXxx() and fillXxx(), where Xxx could be Line, Rect, Oval, Arc, PolyLine, RoundRect, or 3DRect.
3.Bitmap images: via the drawImage() method.

// 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 Graphics Class’ Methods for Maintaining the Graphics Context

The graphic context maintains states (or attributes) such as the current painting color, the current font for drawing text strings, and the current painting rectangular area (called clip). You can use the methods getColor(), setColor(), getFont(), setFont(), getClipBounds(), setClip() to get or set the color, font, and clip area. Any painting outside the clip area is ignored.

// 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 Graphics Class’ Other Methods

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 Graphics Coordinate System

In Java Windowing Subsystem (like most of the 2D Graphics systems), the origin (0,0) is located at the top-left corner.

EACH component/container has its own coordinate system, ranging for (0,0) to (width-1, height-1) as illustrated.

You can use method getWidth() and getHeight() to retrieve the width and height of a component/container. You can use getX() or getY() to get the top-left corner (x,y) of this component’s origin relative to its parent.

3 Custom Painting Template

Under Swing, custom painting is usually performed by extending (i.e., subclassing) a JPanel as the drawing canvas and override the paintComponent(Graphics g) method to perform your own drawing with the drawing methods provided by the Graphics class. The Java Windowing Subsystem invokes (calls back) paintComponent(g) to render the JPanel by providing the current graphics context g, which can be used to invoke the drawing methods.

The extended JPanel is often programmed as an inner class of a JFrame application to facilitate access of private variables/methods. Although we typically draw on the JPanel, you can in fact draw on any JComponent (such as JLabel, JButton).

The custom painting code template is as follows:

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();
      // 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
      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.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() {
         public void run() {
            new CGTemplate(); // Let the constructor do the job

Dissecting the Program

3.1 Refreshing the Display via repaint()

At times, we need to explicitly refresh the display (e.g., in game and animation). We shall NOT invoke paintComponent(Graphics) directly. Instead, we invoke the JComponent’s repaint() method. The Windowing Subsystem will in turn call back the paintComponent() with the current Graphics context and execute it in the event-dispatching thread for thread safety. You can repaint() a particular JComponent (such as a JPanel) or the entire JFrame. The children contained within the JComponent will also be repainted.

4. Colors and Fonts

4.1 java.awt.Color

The class java.awt.Color provides 13 standard colors as named-constants. They are: Color.RED, GREEN, BLUE, MAGENTA, CYAN, YELLOW, BLACK, WHITE, GRAY, DARK_GRAY, LIGHT_GRAY, ORANGE, and PINK. (In JDK 1.1, these constant names are in lowercase, e.g., red. This violates the Java naming convention for constants. In JDK 1.2, the uppercase names are added. The lowercase names were not removed for backward compatibility.)

You can use the toString() to print the RGB values of these color (e.g., System.out.println(Color.RED)):

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]

To retrieve the individual components, you can use getRed(), getGreen(), getBlue(), getAlpha(), etc.

To set the background and foreground (text) color of a component/container, you can invoke:

JLabel label = new JLabel("Test");

4.2 java.awt.Font

The class java.awt.Font represents a specific font face, which can be used for rendering texts. You can use the following constructor to construct a Font instance:

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

You can use the setFont() method to set the current font for the Graphics context g for rendering texts. For example,

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");
JLabel lbl = new JLabel("Hello");
g.drawString("In default Font", 10, 20);     // in default font
Font myFont3 = new Font(Font.SANS_SERIF, Font.ITALIC, 12);
g.drawString("Using the font set", 10, 50);  // in myFont3

Font’s Family Name vs. Font Name

A font could have many faces (or style), e.g., plain, bold or italic. All these faces have similar typographic design. The font face name, or font name for short, is the name of a particular font face, like “Arial”, “Arial Bold”, “Arial Italic”, “Arial Bold Italic”. The font family name is the name of the font family that determines the typographic design across several faces, like “Arial”. For example,

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]

Logical Font vs. Physical Font

JDK supports these logical font family names: “Dialog”, “DialogInput”, “Monospaced”, “Serif”, or “SansSerif”. JDK 1.6 provides these String constants: Font.DIALOG, Font.DIALOG_INPUT, Font.MONOSPACED, Font.SERIF, Font.SANS_SERIF.

Physical font names are actual font libraries such as “Arial”, “Times New Roman” in the system.

GraphicsEnvironment’s getAvailableFontFamilyNames() and getAllFonts()

You can use GraphicsEnvironment’s getAvailableFontFamilyNames() to list all the font family names; and getAllFonts() to construct all Font instances (with font size of 1 pt). For example,
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();

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

The Output of the code when executed will look like the one below.

5. Download The Source Code

This was an example of creation of JAVA AWT Graphics.

You can download the full source code of this example here: AWTGraphicsExample
Exit mobile version