Java Reference
In-Depth Information
Before you do this, let's cover what this does. To draw the line in the right place, we just have to apply a
translation to the coordinate system before the
draw()
operation. Saving a copy of the old transform is
most important, as that enables us to restore the original scheme after we've drawn the line. If we don't
do this, subsequent draw operations in the same graphics context will have more and more translations
applied cumulatively, so objects get further and further away from where they should be. Only one line
of code here involves the element itself, however:
g2D.draw(line); // Draw the line
All the rest will be common to most of the types of shapes - text being the exception. We could add an
overloaded
draw()
method to the base class,
Element
, that we can define like this:
protected void draw(Graphics2D g2D, Shape element) {
g2D.setPaint(highlighted ? Color.MAGENTA : color); // Set the element color
AffineTransform old = g2D.getTransform(); // Save the current transform
g2D.translate(position.x, position.y); // Translate to position
g2D.draw(element); // Draw the element
g2D.setTransform(old); // Restore original transform
}
You may need to add an import for
java.awt.geom.AffineTransform
. This will draw any
Shape
object after applying a translation to the point,
position
. We can now call this method from the
draw()
method in the
Element.Line
class:
public void draw(Graphics2D g2D) {
draw(g2D, line); // Call base draw method
}
You can now go ahead and implement the
draw()
method in exactly the same way for all the nested
classes to
Element
, with the exception of the
Element.Text
class. Just pass the underlying
Shape
reference for each class as the second argument to the overloaded
draw()
method. We can't use the
base class helper method in the
Element.Text
because text is not a
Shape
object. We will come back
to the class defining text as a special case.
We must think about the bounding rectangle for a line now. We don't want the bounding rectangle for a
line to be at (0, 0). We want it to be defined in terms of the coordinate system before it is translated.
This is because when we use it for highlighting, no transforms are in effect. For that to work the
bounding rectangle must be in the same reference frame.
This means that we must apply the translation to the bounding rectangle that corresponds to the
Line2D.Double
shape. A base class helper method will come in handy here too:
protected java.awt.Rectangle getBounds(java.awt.Rectangle bounds) {
AffineTransform at = AffineTransform.getTranslateInstance(position.x,
position.y);
return at.createTransformedShape(bounds).getBounds();
}
Just
add
this
method
to
the
code
for
the
Element
class.