Working with Graphics |
The Graphics class defines methods for drawing the following kinds of shapes:Except for polygons and lines, all shapes are specified using their bounding rectangle. Once you understand rectangles, drawing other shapes is relatively easy. For this reason, this page will concentrate on rectangle drawing.
- Lines (
drawLine()
)- Rectangles (
drawRect()
andfillRect()
)- Raised or lowered rectangles (
draw3DRect()
andfill3DRect()
)- Round-edged rectangles (
drawRoundRect()
andfillRoundRect()
)- Ovals (
drawOval()
andfillOval()
)- Arcs (
drawArc()
andfillArc()
)- Polygons (
drawPolygon()
andfillPolygon()
)Example 1: Simple Rectangle Drawing
The applet on the previous page used thedraw3DRect()
andfillRect()
methods to draw its interface. Here's the applet again:
Here's its code. Below is just the drawing code:
The applet creates (and contains) a FramedArea object, which in turn creates (and contains) a CoordinateArea object. The first call to//In FramedArea (a Panel subclass): public void paint(Graphics g) { Dimension d = size(); Color bg = getBackground(); //Draw a fancy frame around the applet. g.setColor(bg); g.draw3DRect(0, 0, d.width - 1, d.height - 1, true); g.draw3DRect(3, 3, d.width - 7, d.height - 7, false); } //In CoordinateArea (a Canvas subclass): public void paint(Graphics g) { //If user has clicked, paint a tiny rectangle where click occurred if (point != null) { g.fillRect(point.x - 1, point.y - 1, 2, 2); } }draw3DRect()
creates a rectangle as big as the FramedArea's drawing area. Thetrue
argument specifies that the rectangle should appear to be raised. The second call todraw3DRect()
creates a second rectangle just a bit smaller, withfalse
specifying that the rectangle should appear to be sunken. Together, the two calls produce the effect of a raised frame that contains the CoordinateArea. (FramedArea implements theinsets()
method so that the CoordinateArea's drawing area is a few pixels inside of the FramedArea.)The CoordinateArea uses
fillRect()
to draw a two-by-two-pixel rectangle at the point that the user clicks.Example 2: Using a Rectangle to Indicate a Selected Area
Here's an applet that you could use as a basis for implementing [marquee?] selection in a drawing program. When the user drags the mouse, the applet continuously displays a rectangle that starts at the cursor position where the user first pressed the mouse button and ends at the current cursor position.
Here's the applet's code. Below is the significant new code:
As you can see, the SelectionArea (which is like the CoordinateArea in the previous applet) keeps track of the currently selected rectangle, using a Rectangle object calledclass SelectionArea extends Canvas { . . . public boolean mouseDown(Event event, int x, int y) { currentRect = new Rectangle(x, y, 0, 0); repaint(); return false; } public boolean mouseDrag(Event event, int x, int y) { currentRect.resize(x - currentRect.x, y - currentRect.y); repaint(); return false; } public boolean mouseUp(Event event, int x, int y) { currentRect.resize(x - currentRect.x, y - currentRect.y); repaint(); return false; } public void paint(Graphics g) { Dimension d = size(); //If currentRect exists, paint a rectangle on top. if (currentRect != null) { Rectangle box = getDrawableRect(currentRect, d); controller.rectChanged(box); //Draw the box outline. g.drawRect(box.x, box.y, box.width - 1, box.height - 1); } } Rectangle getDrawableRect(Rectangle originalRect, Dimension drawingArea) { . . . //Make sure rectangle width and height are positive. . . . //The rectangle shouldn't extend past the drawing area. . . . } }currentRect
. As implemented, thecurrentRect
keeps the same origin (currentRect.x
,currentRect.y
) for as long as the user drags the mouse. This means that the height and width of the rectangle can be negative.However, the
drawXxx()
andfillXxx()
methods don't draw anything if either the height or width is negative. For this reason, when the SelectionArea draws the rectangle, it must specify the upper left vertex of the rectangle so that the width and height are positive. The SelectionArea class defines agetDrawableRect()
method to perform the necessary calculations to find the upper left vertex. ThegetDrawableRect()
method also makes sure that the rectangle doesn't extend beyond the boundaries of its drawing area. (Here, again is a link to the source code. You'll find the definition ofgetDrawableRect()
at the bottom of the file.)Note: It's perfectly legal to specify x, y, height, or width values that are negative or cause a result larger than the drawing area. Values outside the drawing area don't matter too much because they're clipped to the drawing area. You just won't see part of the shape. Negative height or width results in the shape not being drawn at all.
Example 3: A Shape Sampler
The following applet demonstrates all the shapes you can draw and fill. Here's the code.
Unless your applet viewer's default font is very small, the text displayed in the above applet probably looks ugly in places, with words drawn on top of each other. The next page will improve on this example, teaching you how to make sure text fits within a given space.
Working with Graphics |