Graphics Class Basics in Java
All drawing in Java is done through a Graphics object, which provides basic commands for shapes, text, and color.
Predicting Who Does the Drawing
Suppose you want a Java program to draw a shape, some text, or a colored region on the screen. Which object does the actual drawing? Take a moment to guess before reading on. This article answers that question, then shows how a second, more capable class fits into the same picture. Along the way you will look at a short paintComponent method and trace the graphics object it receives.
What do you think happens?
Which object does the actual drawing when a Java program puts a shape, text, or color on the screen?
Reveal answer
A Graphics object
In Java, every drawing operation is carried out through an object of type Graphics. Your program does not talk to the screen directly; it asks the Graphics object to perform the drawing.
The Graphics Object as a Single Drawing Channel
In Java, every drawing operation is carried out through an object of type Graphics. Think of this object as the single channel through which pixels reach the screen. When you want to draw something, you do not talk to the screen directly. You ask the Graphics object to perform the drawing for you.
Because all drawing passes through this one object, the Graphics object is also the place where drawing state lives. It is the drawing context: the thing that knows where drawing should go and which settings currently apply. The source describes the Graphics class as the everyday toolkit that a program uses, so understanding what that toolkit offers is the next step.
What the Basic Graphics Class Offers
The Graphics class is a basic class for drawing operations. It supplies the everyday commands a program needs, and those commands fall into three groups: commands for drawing shapes, commands for drawing text, and commands for selecting the color that subsequent drawing will use. Those three groups cover a lot of ordinary needs.
Graphics2D as a Subclass of Graphics
Java's second drawing class is Graphics2D. It is a sub-class of Graphics, and it provides a larger set of drawing operations than its parent. The subclass relationship has an important consequence: because Graphics2D inherits from Graphics, every method defined in Graphics is also available on a Graphics2D object. Nothing the basic class offers is lost. The subclass only adds to it.
Read the diagram from the bottom up. Every method you know from Graphics is still there when you hold a Graphics2D object, and the Graphics2D level adds the extra drawing operations on top. This is why a program that is written against Graphics2D loses nothing compared with one written against Graphics.
How paintComponent Receives the Graphics Context
A program rarely creates a drawing object on its own in this context. Instead, the paintComponent() method of a JComponent hands you a graphics context. Its declared type is Graphics, and you use that context to draw on the component.
The important detail is what the context actually is at runtime. Even though it is declared as Graphics, the source states that the graphics context actually belongs to the sub-class Graphics2D. The declared type tells you the minimum you are guaranteed to have. The actual object carries more capability than the declaration shows, and that extra capability is available once you cast.
Casting to Graphics2D Step by Step
To reach the advanced drawing methods, you type-cast the Graphics context to Graphics2D and store the result in a variable of type Graphics2D. The source shows this pattern inside a paintComponent method, where the first line calls the parent version of the method and the cast follows it. The example below follows that same order. The drawing calls shown (setColor and fillRect) are ordinary Graphics methods, so you can see that the cast variable g2 is used the same way the parameter g would be.
public class CanvasPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLUE);
g2.fillRect(20, 20, 100, 50);
}
}- 1Line 1 declares a class that extends
JPanelso it can draw on the screen. - 2Line 2 overrides
paintComponent, the method that receives the graphics context. - 3Line 3 declares the parameter g with the type Graphics, as the method signature specifies.
- 4Line 4 calls the parent version of
paintComponentfirst, as the source's pattern shows. - 5Line 5 casts g to Graphics2D and stores the result in g2. No new drawing surface is created; g2 is a second, more specifically typed reference to the same context.
- 6Line 6 sets the drawing color using g2, which affects subsequent drawing on that context.
- 7Line 7 draws a filled rectangle through g2 into the same context that g refers to.
- The parameter g is declared as Graphics, which is the type the
paintComponentmethod receives. - The cast (Graphics2D) g produces a reference of the more specific type.
- g2 is used for drawing after the cast.
The diagram shows what the cast actually does. There is one context object, and both g and g2 point to it. The cast changes which methods the compiler lets you call through the variable, because g2 is typed as Graphics2D. It does not duplicate the drawing surface, so drawing calls made through g2 land on the same context that g refers to.
Tracing the Context Through the Example
Following the Graphics Object Through paintComponent
In the CanvasPanel example, track which references exist, what they point to, and which variable is used to draw the rectangle.
- 1Method entry
The Swing painting system calls
paintComponentand passes in a graphics context. The parameter g is declared as Graphics and holds that context. - 2Parent call
super.paintComponent(g)runs first, using the same context. Nothing new is created at this point. - 3Cast
(Graphics2D) g produces a reference typed as Graphics2D. The result is stored in g2. Both g and g2 now refer to the same context.
- 4Drawing
setColorandfillRectare called through g2. They act on the one shared context, so the blue rectangle goes to the same destination g would have drawn to.
There is one graphics context. The parameter g and the cast variable g2 are two references to it, and the drawing commands issued through g2 affect that single context.
Mistakes With Graphics and Graphics2D
The following mistakes come up when learners first use the Graphics and Graphics2D types together. Each one is tied to a fact from the source: the cast does not create a new surface, the parent call comes first, and the advanced methods belong to Graphics2D.
Common mistake Believing the cast creates a new drawing surface
What it looks likeGraphics2D g2 = (Graphics2D) g; then expecting g2 to draw on a blank area separate from g
Why it failsThe cast gives a second, more specifically typed reference to the same graphics context. It does not make a new surface.
Do this insteadTreat g and g2 as two names for one context. Drawing through either one goes to the same place.
Common mistake Calling advanced Graphics2D methods through a variable declared as Graphics
What it looks likeGraphics g and then calling a Graphics2D-only operation on g directly
Why it failsThe variable's declared type is Graphics, and Graphics2D adds operations that the Graphics type does not offer.
Do this insteadCast g to Graphics2D into a variable of type Graphics2D, then call the advanced operation through that variable.
Common mistake Skipping the parent call to paintComponent
What it looks likeWriting the cast and drawing code without calling super.paintComponent(g) first
Why it failsThe source's pattern calls the parent version of the method first, and the cast follows it. Departing from that order means the code no longer matches the established structure.
Do this insteadStart the method with super.paintComponent(g), then perform the cast and drawing.
Common mistake Assuming Graphics2D is a separate, unrelated class
What it looks likeThinking that a Graphics2D object lacks the shape, text, and color commands of Graphics
Why it failsGraphics2D is a sub-class of Graphics and inherits every Graphics method.
Do this insteadRemember that Graphics2D contains everything Graphics offers, plus a larger set of drawing operations.
Practice: Tracing a Cast Variable
Using the CanvasPanel example, suppose you add a second line after the fillRect call that changes the color to red and draws another rectangle using g instead of g2. Predict whether the second rectangle goes to the same graphics context as the first. Then explain your answer in terms of the two references g and g2.
Hints
- Ask whether g and g2 refer to the same object or to two different ones.
- Recall that the cast creates a second reference, not a new drawing surface.
- Think about what color setting was applied earlier and whether it still applies on the shared context.
Key Takeaways
- All drawing in Java is done through a Graphics object, which offers basic commands for shapes, text, and color.
- Graphics2D is a sub-class of Graphics with a larger set of drawing operations, and it inherits every Graphics method.
- The graphics context passed to
paintComponent()is declared as Graphics but actually belongs to Graphics2D, so it can be cast to reach the advanced methods. - Casting creates a more specifically typed reference to the same context, not a new drawing surface.
- Common mistakes include assuming the cast makes a new surface, calling Graphics2D methods through a Graphics-typed variable, and skipping the parent
paintComponentcall.