/*Stroke01.java 12/12/99
 Copyright 1999, R.G.Baldwin
  
 Illustrates use of the Stroke interface.
  
 Draws a 4-inch by 4-inch Frame on the screen.
  
 Translates the origin to the center of the Frame.
  
 Draws a pair of X and Y-axes 
 centered on the new origin.
  
 Illustrates three types of end caps in upper-left
 quadrant.
  
 Illustrates connecting lines that 
 are not segments of a
 Shape in lower-left quadrant
  
 Illustrates three types of line joins, along with end 
 caps in upper-right quadrant.
  
 Illustrates dash pattern and miterlimit in lower-right
 quadrant.
  
 Illustrates application of several 
 attributes to a circle
 centered on the origin.
  
 Whether the dimensions in inches come out right 
 or not depends on whether the method 
 getScreenResolution() returns the correct 
 resolution for your screen.
  
 Tested using JDK 1.2.2,WinNT Workstation 4.0
 *****************************************/
 import java.awt.geom.*;
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.image.*;
  
 class Stroke01{
   publicstaticvoid main(String[] args){
     GUI guiObj = new GUI();
   }//end main
 }//end controlling class Stroke01
  
 class GUI extends Frame{
   int res;//store screen resolution here
   staticfinalint ds = 72;//default scale, 72 units/inch
   staticfinalint hSize = 4;//horizonal size = 4 inches
   staticfinalint vSize = 4;//vertical size = 4 inches
   
   GUI(){//constructor
     //Get screen resolution
     res = Toolkit.getDefaultToolkit().
                                      getScreenResolution();
     //Set Frame size
     this.setSize(hSize*res,vSize*res);
     this.setVisible(true);
     this.setTitle("Copyright 1999, R.G.Baldwin");
         
     //Window listener to terminate program.
     this.addWindowListener(new WindowAdapter(){
       publicvoid windowClosing(WindowEvent e){
         System.exit(0);}});
   }//end constructor
   //-----------------------------------------------------//
   
   //Override the paint() method
   publicvoid paint(Graphics g){
     //Downcast the Graphics object to a 
     // Graphics2D object
     Graphics2D g2 = (Graphics2D)g;
     
     //Scale device space to produce inches on the
     // screen based on actual screen resolution.
     g2.scale((double)res/72,(double)res/72);
  
     //Translate origin to center of Frame
     g2.translate((hSize/2)*ds,(vSize/2)*ds);
  
     //Draw x-axis
     g2.draw(new Line2D.Double(
                                       -1.5*ds,0.0,1.5*ds,0.0));
     //Draw y-axis
     g2.draw(new Line2D.Double(
                                       0.0,-1.5*ds,0.0,1.5*ds));
  
     
     //Display all three end cap types in upper-left 
     // quadrant Display red CAP_BUTT
     Stroke stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_BUTT,
               BasicStroke.JOIN_BEVEL);//don't care
     g2.setStroke(stroke);
     g2.setPaint(Color.red);
     g2.draw(new Line2D.Double(
                        -1.5*ds,-1.5*ds,-0.5*ds,-1.5*ds));
  
     //Display green CAP_ROUND
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_ROUND,
               BasicStroke.JOIN_BEVEL);//don't care
     g2.setStroke(stroke);
     g2.setPaint(Color.green);
     g2.draw(new Line2D.Double(
                        -1.5*ds,-1.0*ds,-0.5*ds,-1.0*ds));
  
     //Display blue CAP_SQUARE
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_BEVEL);//don't care
     g2.setStroke(stroke);
     g2.setPaint(Color.blue);
     g2.draw(new Line2D.Double(
                          -1.5*ds,-0.5*ds,-0.5*ds,-0.5*ds));
  
     //Display two lines that connect, but are not 
     // segments of a Shape in the lower left 
     // quadrant.  Illustrates the problems of creating
     // geometric figures with connecting lines that 
     // have width.
  
     //This illustrates the problem with 
     // CAP_SQUARE -- red
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_BEVEL);//don't care
     g2.setStroke(stroke);
     g2.setPaint(Color.red);
     g2.draw(new Line2D.Double(
                        -1.75*ds,1.5*ds,-1.50*ds,0.5*ds));
     g2.draw(new Line2D.Double(
                        -1.50*ds,0.5*ds,-1.25*ds,1.5*ds));
  
     //This illustrates the problem with 
     // CAP_BUTT -- green
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_BUTT,
               BasicStroke.JOIN_BEVEL);//don't care
     g2.setStroke(stroke);
     g2.setPaint(Color.green);
     g2.draw(new Line2D.Double(
                         -0.75*ds,1.5*ds,-0.5*ds,0.5*ds));
     g2.draw(new Line2D.Double(
                         -0.5*ds,0.5*ds,-0.25*ds,1.5*ds));
  
     //Display all three join types in upper-right 
     // quadrant
     
     //Display blue JOIN_BEVEL with CAP_SQUARE
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_SQUARE,
               BasicStroke.JOIN_BEVEL);
     g2.setStroke(stroke);
     GeneralPath gp1 = new GeneralPath();
     gp1.moveTo(0.25f*ds,-1.25f*ds);
     gp1.lineTo(0.50f*ds,-0.25f*ds);
     gp1.lineTo(0.75f*ds,-1.25f*ds);
     g2.setPaint(Color.blue);
     g2.draw(gp1);
  
     //Display green JOIN_MITER with CAP_ROUND
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_ROUND,
               BasicStroke.JOIN_MITER);
     g2.setStroke(stroke);
     
     GeneralPath gp2 = new GeneralPath();
     gp2.moveTo(0.75f*ds,-0.25f*ds);
     gp2.lineTo(1.00f*ds,-1.25f*ds);
     gp2.lineTo(1.25f*ds,-0.25f*ds);
     
     g2.setPaint(Color.green);
     g2.draw(gp2);
  
     //Display red JOIN_ROUND with CAP_BUTT
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_BUTT,
               BasicStroke.JOIN_ROUND);
     g2.setStroke(stroke);
     
     GeneralPath gp3 = new GeneralPath();
     gp3.moveTo(1.25f*ds,-1.25f*ds);
     gp3.lineTo(1.50f*ds,-0.25f*ds);
     gp3.lineTo(1.75f*ds,-1.25f*ds);
     
     g2.setPaint(Color.red);
     g2.draw(gp3);
  
     //Display dash pattern and miterlimit in 
     // bottom-right quadrant
     
     //Display blue JOIN_BEVEL with CAP_SQUARE
     //Dash pattern is one on, three off, but this is not
     // what it looks like with CAP_SQUARE
     stroke = new BasicStroke(
            0.2f*ds,//width
            BasicStroke.CAP_SQUARE,
            BasicStroke.JOIN_BEVEL,
            0.0f,//miterlimit doesn't matter
            newfloat[] {0.1f*ds,0.3f*ds},//Dash pattern
            0.0f);//Dash phase
     g2.setStroke(stroke);
     GeneralPath gp4 = new GeneralPath();
     gp4.moveTo(0.25f*ds,1.25f*ds);
     gp4.lineTo(0.50f*ds,0.25f*ds);
     gp4.lineTo(0.75f*ds,1.25f*ds);
     g2.setPaint(Color.blue);
     g2.draw(gp4);
  
     //Display green JOIN_MITER with CAP_ROUND
     // and miter limit. No dash pattern.
     stroke = new BasicStroke(
               0.2f*ds,//width
               BasicStroke.CAP_ROUND,
               BasicStroke.JOIN_MITER,
               .057f*ds);//miterlimit
     g2.setStroke(stroke);
     
     GeneralPath gp5 = new GeneralPath();
     gp5.moveTo(0.75f*ds,0.25f*ds);
     gp5.lineTo(1.00f*ds,1.25f*ds);
     gp5.lineTo(1.25f*ds,0.25f*ds);
     
     g2.setPaint(Color.green);
     g2.draw(gp5);
  
     //Display red JOIN_ROUND with CAP_BUTT
     //Dash pattern is one on, three off again.  Looks
     // like it with CAP_BUTT
     stroke = new BasicStroke(
            0.2f*ds,//width
            BasicStroke.CAP_BUTT,
            BasicStroke.JOIN_ROUND,
            0.0f,//miterlimit doesn't matter
            newfloat[] {0.1f*ds,0.3f*ds},//Dash pattern
            0.0f);//Dash phase
     g2.setStroke(stroke);
     
     GeneralPath gp6 = new GeneralPath();
     gp6.moveTo(1.25f*ds,1.25f*ds);
     gp6.lineTo(1.50f*ds,0.25f*ds);
     gp6.lineTo(1.75f*ds,1.25f*ds);
     
     g2.setPaint(Color.red);
     g2.draw(gp6);
     
     //Draw a circle with an orange outline centered
     // on the origin with a dash pattern and 
     // CAP_BUTT end caps.
     stroke = new BasicStroke(
            0.1f*ds,//width
            BasicStroke.CAP_BUTT,
            BasicStroke.JOIN_ROUND,//don't care
            0.0f,//miterlimit doesn't matter
            newfloat[] {0.2f*ds,0.1f*ds},//Dash pattern
            0.0f);//Dash phase
     g2.setStroke(stroke);
     
     Ellipse2D.Double theCircle = 
                                       new Ellipse2D.Double(
                           -0.4*ds,-0.4*ds,0.8*ds,0.8*ds);
     
     g2.setPaint(Color.orange);
     g2.draw(theCircle);
  
   }//end overridden paint()
     
 }//end class GUI
 //==============================//

Figure 16