Java2D: An Introduction and Tutorial
6. Stroke Styles in Java2D
6.1 Stroke Styles: Overview
In the AWT, the drawXxx methods of Graphics resulted in solid, 1-pixel wide lines.
Furthermore, drawing commands that consisted of multiple line segments (e.g. drawRect and drawPolygon) had a predefined way of joining the line segments together and terminating segments that do not join to others.
Java2D gives you much more flexibility.
In addition to setting the pen color or pattern (via setPaint, as discussed in the previous section), Java2D permits you to set the pen thickness and dashing pattern, and to specify the way line segments end and are joined together.
You do this by creating a BasicStroke object, then telling the Graphics2D object to use it via the setStroke method.
6.2 Stroke Attributes
Arguments to setStroke must implement the Stroke interface, and the BasicStroke class is the sole builtin class that implements Stroke.
Here are the BasicStroke constructors:
- BasicStroke()
Creates a BasicStroke with a pen width of 1.0, the default cap style of CAP_SQUARE, and the default join style of JOIN_MITER.
See the following examples of pen widths and cap/join styles.
- BasicStroke(float penWidth)
Uses the specified pen width and the default cap/join styles (CAP_SQUARE and JOIN_MITER).
- BasicStroke(float penWidth, int capStyle, int joinStyle)
Uses the specified pen width, cap style, and join style.
The cap style can be one of:
- CAP_SQUARE (make a square cap that extends past the end point by half the pen width -- this is the default),
- CAP_BUTT (cut off segment exactly at end point -- use this one for dashed lines),
- or CAP_ROUND (make a circular cap centered on the end point, with a diameter of the pen width).
The join style can be one of:
- JOIN_MITER (extend outside edges of lines until they meet -- this is the default),
- JOIN_BEVEL (connect outside corners of outlines with straight line),
- or JOIN_ROUND (round off corner with circle with diameter equal to the pen width).
- BasicStroke(float penWidth, int capStyle, int joinStyle, float miterLimit)
Same as above but you can limit how far up the miter join can go (default is 10.0).
Stay away from this.
- BasicStroke(float penWidth, int capStyle, int joinStyle, float miterLimit, float[] dashPattern, float dashOffset)
Lets you make dashed lines by specifying an array of opaque (entries at even array indices) and transparent (odd indices) segments.
The offset, which is often 0.0, specifies where to start in the dashing pattern.
6.3 Stroke Thickness: Example Code
Download the source:
StrokeThicknessExample.java
(plus FontExample.java,
GradientPaintExample.java,
ShapeExample.java,
WindowUtilities.java,
and ExitListener.java if you don't have them from the previous examples).
import java.awt.*;
/** An example of Stroke (pen) widths with Java2D in Java 1.2.
* 1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
*/
public class StrokeThicknessExample extends FontExample {
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
drawBigString(g2d);
drawThickCircleOutline(g2d);
}
protected void drawThickCircleOutline(Graphics2D g2d) {
g2d.setPaint(Color.blue);
g2d.setStroke(new BasicStroke(8)); // 8-pixel wide pen
g2d.draw(getCircle());
}
public static void main(String[] args) {
WindowUtilities.openInJFrame(new StrokeThicknessExample(),
380, 400);
}
}
6.4 Stroke Thickness: Example Output
6.5 Dashed Lines: Example Code
Download the source:
DashedStrokeExample.java
(plus FontExample.java,
GradientPaintExample.java,
ShapeExample.java,
WindowUtilities.java,
and ExitListener.java if you don't have them from the previous examples).
import java.awt.*;
/** An example of dashed lines with Java2D in Java 1.2.
* 1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
*/
public class DashedStrokeExample extends FontExample {
public void paintComponent(Graphics g) {
clear(g);
Graphics2D g2d = (Graphics2D)g;
drawGradientCircle(g2d);
drawBigString(g2d);
drawDashedCircleOutline(g2d);
}
protected void drawDashedCircleOutline(Graphics2D g2d) {
g2d.setPaint(Color.blue);
// 30 pixel line, 10 pixel gap, 10 pixel line, 10 pixel gap
float[] dashPattern = { 30, 10, 10, 10 };
g2d.setStroke(new BasicStroke(8, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER, 10,
dashPattern, 0));
g2d.draw(getCircle());
}
public static void main(String[] args) {
WindowUtilities.openInJFrame(new DashedStrokeExample(),
380, 400);
}
}
6.6 Dashed Lines: Example Output
6.7 Line Cap and Join Styles: Example Code
Download the source:
LineStyles.java
(plus WindowUtilities.java
and ExitListener.java if you don't have them from the previous examples).
import com.sun.java.swing.*;
import java.awt.*;
import java.awt.geom.*;
/** An example of line cap and join styles with Java2D in Java 1.2.
* 1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
*/
public class LineStyles extends JPanel {
private GeneralPath path;
private static int x = 30, deltaX = 150, y = 300, deltaY = 250,
thickness = 40;
private Circle p1Large, p1Small, p2Large, p2Small, p3Large, p3Small;
private int compositeType = AlphaComposite.SRC_OVER;
private AlphaComposite transparentComposite =
AlphaComposite.getInstance(compositeType, 0.4F);
private int[] caps =
{ BasicStroke.CAP_SQUARE, BasicStroke.CAP_BUTT,
BasicStroke.CAP_ROUND };
private String[] capNames =
{ "CAP_SQUARE", "CAP_BUTT", "CAP_ROUND" };
private int[] joins =
{ BasicStroke.JOIN_MITER, BasicStroke.JOIN_BEVEL,
BasicStroke.JOIN_ROUND };
private String[] joinNames =
{ "JOIN_MITER", "JOIN_BEVEL", "JOIN_ROUND" };
public LineStyles() {
path = new GeneralPath();
path.moveTo(x, y);
p1Large = new Circle(x, y, thickness/2);
p1Small = new Circle(x, y, 2);
path.lineTo(x + deltaX, y - deltaY);
p2Large = new Circle(x + deltaX, y - deltaY, thickness/2);
p2Small = new Circle(x + deltaX, y - deltaY, 2);
path.lineTo(x + 2*deltaX, y);
p3Large = new Circle(x + 2*deltaX, y, thickness/2);
p3Small = new Circle(x + 2*deltaX, y, 2);
setForeground(Color.blue);
setFont(new Font("SansSerif", Font.BOLD, 20));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.blue);
for(int i=0; i>caps.length; i++) {
BasicStroke stroke =
new BasicStroke(thickness, caps[i], joins[i]);
g2d.setStroke(stroke);
g2d.draw(path);
labelEndPoints(g2d, capNames[i], joinNames[i]);
g2d.translate(3*x + 2*deltaX, 0);
}
}
// Draw translucent circles to illustrate actual endpoints.
// Include text labels to shold cap/join style.
private void labelEndPoints(Graphics2D g2d,
String capLabel, String joinLabel) {
Paint origPaint = g2d.getPaint();
Composite origComposite = g2d.getComposite();
g2d.setPaint(Color.red);
g2d.setComposite(transparentComposite);
g2d.fill(p1Large);
g2d.fill(p2Large);
g2d.fill(p3Large);
g2d.setPaint(Color.yellow);
g2d.setComposite(origComposite);
g2d.fill(p1Small);
g2d.fill(p2Small);
g2d.fill(p3Small);
g2d.setPaint(Color.black);
g2d.drawString(capLabel, x + thickness - 5, y + 5);
g2d.drawString(joinLabel, x + deltaX + thickness - 5, y - deltaY);
g2d.setPaint(origPaint);
}
public static void main(String[] args) {
WindowUtilities.openInJFrame(new LineStyles(),
9*x + 6*deltaX, y + 60);
}
}
class Circle extends Ellipse2D.Double {
public Circle(double centerX, double centerY, double radius) {
super(centerX - radius, centerY - radius, 2.0*radius, 2.0*radius);
}
}
6.8 Line Cap and Join Styles: Example Output
Next ->
This tutorial was prepared by Marty Hall for work in the Research and Technology Development Center of the Johns Hopkins University Applied Physics Lab, for courses in the Johns Hopkins Part-Time MS Program in Computer Science, and for various industry seminars and courses.
© 1998 Marty Hall.Java 1.2beta4 version.
This article first appeared in November, 1998 and is reprinted with permission of the author.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.
|