Concepts / Colors and Fonts in Java Graphics

Colors and Fonts in Java Graphics

A graphics context is an object that bundles drawing subroutines with data such as the current color, the current font, and the drawing surface.

  • Programming

The Drawing Problem Java Has to Solve

Suppose you want a Swing window to show a red outline of a square and a solid blue circle. You might expect Java to offer one built-in command that means put this shape on the screen. It does not. Instead, drawing is carried out through an object that knows how to paint and that remembers how it is currently configured. That object is called a graphics context.

Once you see the graphics context as a bundle of drawing tools plus a set of current settings, the rest of this topic becomes a matter of learning two things: which tools exist, and how the settings behave over time. The second question is the one that trips up most readers of drawing code, so this article spends most of its time on it.

Tracing the Current Color Through a Drawing

Before reading any definitions, trace a short sequence of calls and keep track of one question: what color is the context holding right now? Imagine the following fragment, where g is a graphics context.

java
Notes on the code
  • setColor stores RED in the context; the drawRect that follows uses it
  • The second setColor replaces the stored color with BLUE
  • fillOval and the final fillRect both use BLUE, because no setColor came between them

Read the diagram from left to right. The color is set once and then persists. The rectangle outline is red because RED was the current setting when drawRect ran. The setColor call in the middle changes the setting, and only operations after it use BLUE. Notice that the earlier outline is not repainted. The change affects what happens next, not what has already been drawn.

What a Graphics Context Holds

Definition

A graphics context is an object that bundles drawing subroutines with data such as the current color, the current font, and the drawing surface.

The subroutines are the things the context can do. They include drawing basic shapes such as lines, rectangles, and ovals, and they also include drawing text, because characters on the screen have to be drawn by the computer just as any other shape is. The data are the settings currently in force, such as the selected color and the selected font. A font determines the style and size of characters.

The third piece is easy to overlook: the drawing surface, which is the place where the drawing actually lands. Different graphics context objects can draw to different drawing surfaces. In this course the drawing surface is the content area of a window, which does not include the border or the title bar. When you call a drawing subroutine, you ask the context to put pixels onto that area, using whatever color and font it currently holds.

In a program the context is represented by a variable whose type is Graphics, just as a string variable has the type String. The variable is often named g, but the programmer may choose any name. Every numerical parameter passed to its subroutines is of type int, so coordinates and sizes are whole numbers.

The font works the same way as the color. The font is a setting stored in the context, so text drawn after the font is selected is affected by it. Coordinates on the drawing surface are measured in pixels from the top-left of the content area, so the point (10, 10) lies 10 pixels from the left edge and 10 pixels down from the top.

Filling Versus Outlining a Shape

Swing offers two ways to put a shape on the screen. Filling a shape sets the color of every pixel inside it. Drawing a shape sets the color of only those pixels that lie along its border. A helpful picture is dragging a pen around the edge of the shape. The pen's properties, such as its size or whether its line is solid or dashed, belong to the graphics context and not to the shape itself.

The core subroutines form a practical starter set. The rectangle and oval subroutines come in pairs: each has a draw version and a fill version, and both take the same four arguments. The only difference is whether the pixels inside the shape are colored. Lines are different, since they can only be drawn. For rectangles and ovals, the four parameters give the top-left corner (x, y) and the size (w, h). For lines, the parameters are the two endpoints.

java
Notes on the code
  • drawLine takes two endpoints, not a corner and a size
  • drawRect and fillRect take identical arguments and differ only in whether the interior is colored
  • drawOval and fillOval also pair up; because w and h are equal here, both shapes are circles
EASY

Using the same coordinate style as the examples above, write the calls that draw a solid green rectangle at top-left (20, 20) with width 50 and height 30, and then a red outline of a circle with diameter 40 whose top-left corner is at (100, 20).

Hints
  • Rectangles take x, y, w, h in that order, and the fill version uses the same arguments as the draw version.
  • A circle is an oval whose width and height are equal, so the diameter is used for both.
  • Remember to call setColor before each shape whose color you want to change.

Predicting the Color of Each Shape

Before revealing the answer, try this on your own. Given the fragment below, which shapes are drawn in red and which in blue? Remember that the color is a setting stored in the context and that calls take effect in the order they are written.

java
Notes on the code
  • Only two setColor calls appear, so only two colors are used
  • The second setColor takes over partway through the sequence

What do you think happens?

What color is each of the four shapes drawn in this sequence?

Reveal answer
Answer:

The filled rectangle and the outlined oval are red. The filled oval and the outlined rectangle are blue.

The first setColor sets RED, so fillRect and drawOval run in red. The second setColor(Color.BLUE) replaces that setting before fillOval and drawRect, so those two are blue. A later setColor never changes shapes drawn earlier, and each shape simply uses whatever color is current when its call runs.

Mistakes Beginners Make with Color and Order

  • Common mistake

    Assuming a setColor call recolors shapes that were already drawn

    What it looks like
    g.setColor(Color.RED); g.fillRect(0, 0, 40, 40); g.setColor(Color.BLUE);  // the rectangle stays red
    Why it fails

    setColor changes the setting that later operations will use. It does not repaint what was drawn earlier.

    Do this instead

    Read drawing code top to bottom and ask which color is current at the moment each shape is drawn.

  • Common mistake

    Expecting a color to apply only to the next shape

    What it looks like
    g.setColor(Color.GREEN); g.drawLine(0, 0, 10, 10); g.drawRect(20, 20, 30, 30);  // the rectangle is also green
    Why it fails

    The color set by setColor applies to all later drawing operations until setColor is called again.

    Do this instead

    Call setColor again whenever a later shape needs a different color.

  • Common mistake

    Confusing the fill and draw versions of a shape

    What it looks like
    g.fillRect(10, 10, 80, 40) when an outline was intended
    Why it fails

    Filling colors every pixel inside the shape, while drawing colors only the border.

    Do this instead

    Use drawRect for an outline and fillRect for a solid rectangle; the arguments are the same.

  • Common mistake

    Passing non-integer values for coordinates or sizes

    Why it fails

    All numerical parameters of these subroutines are of type int.

    Do this instead

    Use whole numbers for x, y, w, and h.

Putting the Rules Together

MEDIUM

A graphics context g currently holds the color Color.GREEN. Write the calls that draw a green outline of a rectangle at (5, 5) with size 60 by 30, then change the color to Color.BLACK and draw a solid oval at (100, 5) with width 40 and height 40. Then state which color each shape appears in, and why the rectangle is not affected by the later setColor call.

Hints
  • The rectangle is drawn before setColor(Color.BLACK), so it uses the color that was current at that point.
  • A solid oval is a fillOval call, and it takes the same four arguments as drawOval.

Key Takeaways

  • A graphics context is an object that bundles drawing subroutines with its current color, current font, and drawing surface, which is the content area of a window.
  • Filling a shape colors every pixel inside it, while drawing a shape colors only the pixels along its border; lines can only be drawn.
  • The color set by setColor applies to all later drawing operations until setColor is called again, so the order of calls determines which shapes get which colors.
  • Rectangle and oval subroutines come in draw and fill pairs that take the same int arguments: x, y, w, h, where an oval's values describe its bounding box.