An introduction to the Java 2D API
Complete Source Code
---Test2D.java--- import java.awt.*; import java.awt.event.*; import java.awt.geom.*; public class Test2D extends Canvas { int testNumber = 1; public Test2D(int num) { testNumber = num; setBackground(Color.lightGray); } GeneralPath makeLine(int x1, int y1, int x2, int y2) { GeneralPath p = new GeneralPath(); p.moveTo(x1, y1); p.lineTo(x2, y2); return p; } // makes a cross out of two lines centered at x,y GeneralPath makeCross(int x, int y, int width) { GeneralPath p = new GeneralPath(); p.moveTo(x + (width/2), y - (width/2)); p.lineTo(x - (width/2), y + (width/2)); p.moveTo(x - (width/2), y - (width/2)); p.lineTo(x + (width/2), y + (width/2)); return p; } // makes a box out of two rectangular pieces one inside the other GeneralPath makeBox(int x, int y, int width, int height) { GeneralPath p = new GeneralPath(); p.moveTo(x + (width/2), y - (height/2)); p.lineTo(x + (width/2), y + (height/2)); p.lineTo(x - (width/2), y + (height/2)); p.lineTo(x - (width/2), y - (height/2)); p.closePath(); p.moveTo(x + (width/4), y - (height/4)); p.lineTo(x + (width/4), y + (height/4)); p.lineTo(x - (width/4), y + (height/4)); p.lineTo(x - (width/4), y - (height/4)); p.closePath(); return p; } public void test1(Graphics g) { Dimension sz = getSize(); g.setColor(Color.red); g.drawRect(10, 10, sz.width-20, sz.height-20); // Illustrate 2d primitives Graphics2D g2; g2 = (Graphics2D) g; g2.setRenderingHints(Graphics2D.ANTIALIASING, Graphics2D.ANTIALIAS_ON); GeneralPath p = makeBox(sz.width/4, sz.height/4, 100, 100); p.setWindingRule(GeneralPath.NON_ZERO); g2.setColor(Color.blue); g2.fill(p); p = makeBox((3 * sz.width)/4, sz.height/4, 100, 100); p.setWindingRule(GeneralPath.EVEN_ODD); g2.setColor(Color.blue); g2.fill(p); } public void test2(Graphics g) { Dimension sz = getSize(); g.setColor(Color.red); g.drawRect(10, 10, sz.width-20, sz.height-20); // Illustrate 2d primitives Graphics2D g2; g2 = (Graphics2D) g; g2.setRenderingHints(Graphics2D.ANTIALIASING, Graphics2D.ANTIALIAS_ON); GeneralPath p = makeBox(sz.width/4, sz.height/4, 100, 100); p.setWindingRule(GeneralPath.NON_ZERO); g2.setColor(Color.blue); g2.setStroke(new BasicStroke(5.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, null, 0.0f)); g2.draw(p); p = makeBox((3 * sz.width)/4, sz.height/4, 100, 100); p.setWindingRule(GeneralPath.EVEN_ODD); g2.setColor(Color.blue); g2.setStroke(new BasicStroke(15.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, null, 0.0f)); g2.draw(p); } public void test3(Graphics g) { Dimension sz = getSize(); g.setColor(Color.red); g.drawRect(10, 10, sz.width-20, sz.height-20); // Illustrate 2d primitives Graphics2D g2; g2 = (Graphics2D) g; g2.setRenderingHints(Graphics2D.ANTIALIASING, Graphics2D.ANTIALIAS_ON); // make the box at 125, 125 that's 200 x 100 pixels GeneralPath p = makeBox(sz.width/4, sz.height/4, 200, 100); p.setWindingRule(GeneralPath.EVEN_ODD); AffineTransform tfm = new AffineTransform(); // now translate it by 125, 125 so it appears at the center tfm.translate(sz.width/4, sz.width/4); g2.setTransform(tfm); g2.setColor(Color.blue); g2.fill(p); tfm = new AffineTransform(); p = makeBox(sz.width/4, sz.height/4, 200, 100); // now translate it by -125, -125 so it appears centered at 0,0 tfm.translate(-sz.width/4, -sz.width/4); g2.setTransform(tfm); g2.setColor(Color.green); g2.draw(p); // transform the shape so now we have it centered at the origin Shape s = p.createTransformedShape(tfm); // now create a transform that's translated to the center of the // screen and rotated counter-clock-wise by 30 degrees tfm = new AffineTransform(); tfm.translate(sz.width/2, sz.width/2); tfm.rotate(-Math.PI/6); g2.setTransform(tfm); g2.setColor(Color.red); g2.draw(s); } public void test4(Graphics g) { Dimension sz = getSize(); g.setColor(Color.red); g.drawRect(10, 10, sz.width-20, sz.height-20); // Illustrate 2d primitives Graphics2D g2; g2 = (Graphics2D) g; g2.setRenderingHints(Graphics2D.ANTIALIASING, Graphics2D.ANTIALIAS_ON); // create the magic transform :) AffineTransform tfm = new AffineTransform(1.0, 0.0, 0.0, -1.0, (float)sz.width/2, (float)sz.height/2); AffineTransform tfm1 = new AffineTransform(); g2.setTransform(tfm); g2.setColor(Color.red); GeneralPath p = makeCross(25, 25, 8); g2.draw(p); p = makeCross(-100, 25, 8); g2.draw(p); p = makeLine(0, 0, 200, 0); g2.draw(p); p = makeLine(0, 0, 0, 200); g2.draw(p); Point2D pt1 = new Point2D.Double(30.0, 25.0); Point2D pttfm1 = tfm.transform(pt1, null); Point2D pt2 = new Point2D.Double(-105.0, 25.0); Point2D pttfm2 = tfm.transform(pt2, null); // If you comment out the following four lines, and uncomment // the lines below, you'll see slower and really funny drawString // operation. (i.e. since the original transform is in effect // you'll see the text drawn flipped along the y-axis as well!) g2.setTransform(tfm1); g2.setColor(Color.black); g.drawString("25,25", (int) pttfm1.getX(), (int) pttfm1.getY()); g.drawString("-100,25", (int) pttfm2.getX(), (int) pttfm2.getY()); // This is much slower // g2.drawString("25,25",(float) pttfm1.getX(), (float) pttfm1.getY()); // g2.drawString("-100,25",(float)pttfm2.getX(),(float) pttfm2.getY()); } public void paint(Graphics g) { switch (testNumber) { default: case 1: test1(g); break; case 2: test2(g); break; case 3: test3(g); break; case 4: test4(g); break; } } public void initialize(String args[]) { int testNum = 1; WindowListener l = new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} public void windowClosed(WindowEvent e) {System.exit(0);} }; if (args.length == 1) { try { testNum = Integer.valueOf(args[0]).intValue(); } catch (Exception e) { System.err.println(e.toString()); } } Frame f = new Frame("2D Demo ..."); f.addWindowListener(l); f.add("Center", new Test2D(testNum)); f.pack(); f.setSize(new Dimension(500,500)); f.show(); } public static void main(String args[]) { Test2D t = new Test2D(1); t.initialize(args); } }
Page 2 of 2
This article was originally published on February 5, 1998