Appendix B Java 2D graphics
The Java library includes a simple package for drawing 2D graphics, called java.awt
.
AWT stands for “Abstract Window Toolkit”.
We are only going to scratch the surface of graphics programming; you can read more about it in the Java tutorials at https://docs.oracle.com/javase/tutorial/2d/.
B.1 Creating graphics
There are several ways to create graphics in Java; the simplest way is to use java.awt.Canvas
and java.awt.Graphics
.
A Canvas
is a blank rectangular area of the screen onto which the application can draw.
The Graphics
class provides basic drawing methods such as drawLine
, drawRect
, and drawString
.
Here is an example program that draws a circle using the fillOval
method:
import java.awt.Canvas; import java.awt.Graphics; import javax.swing.JFrame; public class Drawing extends Canvas { |
public static void main(String[] args) { JFrame frame = new JFrame("My Drawing"); Canvas canvas = new Drawing(); canvas.setSize(400, 400); frame.add(canvas); frame.pack(); frame.setVisible(true); } public void paint(Graphics g) { g.fillOval(100, 100, 200, 200); } } |
The Drawing
class extends Canvas
, so it has all the methods provided by Canvas
, including setSize
.
You can read about the other methods in the documentation, which you can find by doing a web search for “Java Canvas”.
In the main
method, we:
- Create a
JFrame
object, which is the window that will contain the canvas. - Create a
Drawing
object (which is the canvas), set its width and height, and add it to the frame. - Pack the frame (resize it) to fit the canvas, and display it on the screen.
Once the frame is visible, the paint
method is called whenever the canvas needs to be drawn; for example, when the window is moved or resized.
The application doesn’t end after the main
method returns; instead, it waits for the JFrame
to close.
If you run this code, you should see a black circle on a gray background.
B.2 Graphics methods
You are probably used to Cartesian coordinates, where x and y values can be positive or negative. In contrast, Java uses a coordinate system where the origin is in the upper-left corner. That way, x and y are always positive integers. Figure B.1 shows these coordinate systems.
Graphical coordinates are measured in pixels; each pixel corresponds to a dot on the screen.
To draw on the canvas, you invoke methods on a Graphics
object.
You don’t have to create the Graphics
object; it gets created when you create the Canvas
, and it gets passed as an argument to paint
.
The previous example used fillOval
, which has the following signature:
/** * Fills an oval bounded by the specified rectangle with * the current color. */ public void fillOval(int x, int y, int width, int height) |
The four parameters specify a bounding box, which is the rectangle in which the oval is drawn.
x
and y
specify the the location of the upper-left corner of the bounding box.
The bounding box itself is not drawn (see Figure B.2).
To choose the color of a shape, invoke setColor
on the Graphics
object:
g.setColor(Color.red); |
The setColor
method determines the color of everything that gets drawn afterward.
Color.red
is a constant provided by the Color
class; to use it you have to import java.awt.Color
.
Other colors include:
black blue cyan darkGray gray green lightGray magenta orange pink white yellow |
You can create your own colors by specifying the red, green, and blue (RGB) components. For example:
Color purple = new Color(128, 0, 128); |
Each value is an integer in the range 0 (darkest) to 255 (lightest).
The color (0, 0, 0)
is black, and (255, 255, 255)
is white.
You can set the background color of the Canvas
by invoking setBackground
:
canvas.setBackground(Color.white); |
B.3 Example drawing
Suppose we want to draw a “Hidden Mickey”, which is an icon that represents Mickey Mouse (see https://en.wikipedia.org/wiki/Hidden_Mickey).
We can use the oval we just drew as the face, and then add two ears.
To make the code more readable, let’s use Rectangle
objects to represent bounding boxes.
Here’s a method that takes a Rectangle
and invokes fillOval
:
public void boxOval(Graphics g, Rectangle bb) { g.fillOval(bb.x, bb.y, bb.width, bb.height); } |
And here’s a method that draws Mickey Mouse:
public void mickey(Graphics g, Rectangle bb) { boxOval(g, bb); int dx = bb.width / 2; int dy = bb.height / 2; Rectangle half = new Rectangle(bb.x, bb.y, dx, dy); half.translate(-dx / 2, -dy / 2); boxOval(g, half); half.translate(dx * 2, 0); boxOval(g, half); } |
The first line draws the face.
The next three lines create a smaller rectangle for the ears.
We translate
the rectangle up and left for the first ear, then to the right for the second ear.
The result is shown in Figure B.3.
You can read more about Rectangle
and translate
in Chapter 10.
See the exercises at the end of this appendix for more example drawings.
B.4 Vocabulary
- AWT:
- The “Abstract Window Toolkit”, a Java package for creating graphical user interfaces.
- coordinate:
- A value that specifies a location in a two-dimensional graphical window.
- pixel:
- The unit in which coordinates are measured.
- bounding box:
- A common way to specify the coordinates of a rectangular area.
- RGB:
- A color model based on adding red, green, and blue light.
B.5 Exercises
The code for this chapter is in the ap02 directory of ThinkJavaCode. See page ?? for instructions on how to download the repository. Before you start the exercises, we recommend that you compile and run the examples.
The result should look like “Mickey Moose”, shown in Figure B.4. Hint: You should only have to add or modify a few lines of code.
- In the directory app02 in the repository for this book, you’ll find a file named Moire.java.
Open it and read the
paint
method. Draw a sketch of what you expect it to do. Now run it. Did you get what you expected? - Modify the program so that the space between the circles is larger or smaller. See what happens to the image.
- Modify the program so that the circles are drawn in the center of the screen and concentric, as in Figure B.5 (left).
The distance between the circles should be small enough that the Moiré interference is apparent.
- Write a method named
radial
that draws a radial set of line segments as shown in Figure B.5 (right), but they should be close enough together to create a Moiré pattern. - Just about any kind of graphical pattern can generate Moiré-like interference patterns. Play around and see what you can create.