Java/2D Graphics GUI/Stroke

Материал из Java эксперт
Версия от 09:53, 1 июня 2010; Admin (обсуждение | вклад) (1 версия)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

A component for choosing a stroke from a list of available strokes.

<source lang="java"> /*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2009, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------
* StrokeChooserPanel.java
* -----------------------
* (C) Copyright 2000-2009, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   Dirk Zeitz;
*
* $Id: StrokeChooserPanel.java,v 1.8 2009/02/27 13:58:41 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
* 16-Mar-2004 : Fix for focus problems (DZ);
* 27-Feb-2009 : Fixed bug 2612649, NullPointerException (DG);
*
*/

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; /**

* A component for choosing a stroke from a list of available strokes.
*
* @author David Gilbert
*/

public class StrokeChooserPanel extends JPanel {

   /** A combo for selecting the stroke. */
   private JComboBox selector;
   /**
    * Creates a panel containing a combo-box that allows the user to select
    * one stroke from a list of available strokes.
    *
    * @param current  the current stroke sample.
    * @param available  an array of "available" stroke samples.
    */
   public StrokeChooserPanel(StrokeSample current, StrokeSample[] available) {
       setLayout(new BorderLayout());
       // we"ve changed the behaviour here to populate the combo box
       // with Stroke objects directly - ideally we"d change the signature
       // of the constructor too...maybe later.
       DefaultComboBoxModel model = new DefaultComboBoxModel();
       for (int i = 0; i < available.length; i++) {
           model.addElement(available[i].getStroke());
       }
       this.selector = new JComboBox(model);
       this.selector.setSelectedItem(current.getStroke());
       this.selector.setRenderer(new StrokeSample(null));
       add(this.selector);
       // Changes due to focus problems!! DZ
       this.selector.addActionListener(new ActionListener() {
           public void actionPerformed(final ActionEvent evt) {
               getSelector().transferFocus();
           }
       });
   }
   /**
    * Returns the selector component.
    *
    * @return Returns the selector.
    */
   protected final JComboBox getSelector() {
       return this.selector;
   }
   /**
    * Returns the selected stroke.
    *
    * @return The selected stroke (possibly null).
    */
   public Stroke getSelectedStroke() {
       return (Stroke) this.selector.getSelectedItem();
   }

} /*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2009, by Object Refinery Limited and Contributors.
*
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------
* StrokeSample.java
* -----------------
* (C) Copyright 2000-2009, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* $Id: StrokeSample.java,v 1.5 2009/02/27 13:58:41 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.ui.*;
* 14-Oct-2002 : Fixed errors reported by Checkstyle (DG);
* 21-Mar-2003 : Fixed null pointer exception, bug 705126 (DG);
*
*/

/**

* A panel that displays a stroke sample.
*
* @author David Gilbert
*/
class StrokeSample extends JComponent implements ListCellRenderer {
   /** The stroke being displayed (may be null). */
   private Stroke stroke;
   /** The preferred size of the component. */
   private Dimension preferredSize;
   /**
    * Creates a StrokeSample for the specified stroke.
    *
    * @param stroke  the sample stroke (null permitted).
    */
   public StrokeSample(final Stroke stroke) {
       this.stroke = stroke;
       this.preferredSize = new Dimension(80, 18);
       setPreferredSize(this.preferredSize);
   }
   /**
    * Returns the current Stroke object being displayed.
    *
    * @return The stroke (possibly null).
    */
   public Stroke getStroke() {
       return this.stroke;
   }
   /**
    * Sets the stroke object being displayed and repaints the component.
    *
    * @param stroke  the stroke (null permitted).
    */
   public void setStroke(final Stroke stroke) {
       this.stroke = stroke;
       repaint();
   }
   /**
    * Returns the preferred size of the component.
    *
    * @return the preferred size of the component.
    */
   public Dimension getPreferredSize() {
       return this.preferredSize;
   }
   /**
    * Draws a line using the sample stroke.
    *
    * @param g  the graphics device.
    */
   public void paintComponent(final Graphics g) {
       final Graphics2D g2 = (Graphics2D) g;
       g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
               RenderingHints.VALUE_ANTIALIAS_ON);
       final Dimension size = getSize();
       final Insets insets = getInsets();
       final double xx = insets.left;
       final double yy = insets.top;
       final double ww = size.getWidth() - insets.left - insets.right;
       final double hh = size.getHeight() - insets.top - insets.bottom;
       // calculate point one
       final Point2D one =  new Point2D.Double(xx + 6, yy + hh / 2);
       // calculate point two
       final Point2D two =  new Point2D.Double(xx + ww - 6, yy + hh / 2);
       // draw a circle at point one
       final Ellipse2D circle1 = new Ellipse2D.Double(one.getX() - 5,
               one.getY() - 5, 10, 10);
       final Ellipse2D circle2 = new Ellipse2D.Double(two.getX() - 6,
               two.getY() - 5, 10, 10);
       // draw a circle at point two
       g2.draw(circle1);
       g2.fill(circle1);
       g2.draw(circle2);
       g2.fill(circle2);
       // draw a line connecting the points
       final Line2D line = new Line2D.Double(one, two);
       if (this.stroke != null) {
           g2.setStroke(this.stroke);
           g2.draw(line);
       }
   }
   /**
    * Returns a list cell renderer for the stroke, so the sample can be
    * displayed in a list or combo.
    *
    * @param list  the list.
    * @param value  the value.
    * @param index  the index.
    * @param isSelected  selected?
    * @param cellHasFocus  focussed?
    *
    * @return the component for rendering.
    */
   public Component getListCellRendererComponent(JList list, Object value,
           int index, boolean isSelected, boolean cellHasFocus) {
       if (value instanceof Stroke) {
           setStroke((Stroke) value);
       }
       else {
           setStroke(null);
       }
       return this;
   }

}


 </source>   



A dashed stroke

<source lang="java">

import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {

 public static void main(String[] args) {
   JFrame frame = new JFrame();
   frame.add(new MyComponent());
   frame.setSize(300, 300);
   frame.setVisible(true);
 }

} class MyComponent extends JComponent {

 public void paint(Graphics g) {
   Graphics2D g2d = (Graphics2D) g;
   float strokeThickness = 5.0f;
   float miterLimit = 10f;
   float[] dashPattern = { 10f };
   float dashPhase = 5f;
   BasicStroke stroke = new BasicStroke(strokeThickness, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
       miterLimit, dashPattern, dashPhase);
   g2d.setStroke(stroke);
   g2d.draw(new Rectangle(20,20,200,200));
 }

}



 </source>   



Basic stroke

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class BasicStrokeDemo extends JPanel {

 public void init() {
   setBackground(Color.white);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   g2.setStroke(new BasicStroke(3.0f));
   g2.setPaint(Color.blue);
   
   Rectangle r = new Rectangle(5,5,200,200);
   
   g2.draw(r);
 }
 public static void main(String s[]) {
   JFrame f = new JFrame();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   BasicStrokeDemo p = new BasicStrokeDemo();
   f.getContentPane().add("Center", p);
   p.init();
   f.pack();
   f.setSize(new Dimension(250, 250));
   f.show();
 }

}




 </source>   



Cancel the effects of the zoom on a particular Stroke

<source lang="java"> /*

* Java2DUtils.java
* 
* Created on Aug 30, 2007, 11:40:18 AM
* 
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

//Revised from jaspersoft ireport designer import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.AffineTransform; import java.util.Stack; /**

*
* @author gtoffoli
*/

public class Java2DUtils {

 /**
  * This function provides a way to cancel the effects of the zoom on a particular Stroke.
  * All the stroke values (as line width, dashes, etc...) are divided by the zoom factor.
  * This allow to have essentially a fixed Stroke independent by the zoom.
  * The returned Stroke is a copy.
  * Remember to restore the right stroke in the graphics when done.
  * 
  * It works only with instances of BasicStroke
  * 
  * zoom is the zoom factor.
  */
 public static Stroke getInvertedZoomedStroke(Stroke stroke, double zoom)
 {
           if (stroke == null || !(stroke instanceof BasicStroke )) return stroke;
           
           BasicStroke bs = (BasicStroke)stroke;
           float[] dashArray = bs.getDashArray();
           
           float[] newDashArray = null;
           if (dashArray != null)
           {
               newDashArray = new float[dashArray.length];
               for (int i=0; i<newDashArray.length; ++i)
               {
                   newDashArray[i] = (float)(dashArray[i] / zoom);
               }
           }
           
           BasicStroke newStroke = new BasicStroke(       
                           (float)(bs.getLineWidth() / zoom),
                           bs.getEndCap(),
                           bs.getLineJoin(),
                           bs.getMiterLimit(),
                           //(float)(bs.getMiterLimit() / zoom),
                           newDashArray,
                           (float)(bs.getDashPhase() / zoom)
                   );
           return newStroke;
 }

}



 </source>   



Changing the Thickness of the Stroking Pen

<source lang="java"> import java.awt.BasicStroke; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {

 public static void main(String[] args) {
   new BasicDraw();
 }
 BasicDraw() {
   JFrame frame = new JFrame();
   frame.add(new MyComponent());
   frame.setSize(300, 300);
   frame.setVisible(true);
 }

} class MyComponent extends JComponent {

 public void paint(Graphics g) {
   Graphics2D g2d = (Graphics2D) g;
   float strokeThickness = 5.0f;
   BasicStroke stroke = new BasicStroke(strokeThickness);
   g2d.setStroke(stroke);
   g2d.draw(new Rectangle(20,20,200,200));
 }

}



 </source>   



Custom Strokes

<source lang="java"> /*

* Copyright (c) 2000 David Flanagan.  All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/

import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.font.GlyphVector; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; /** A demonstration of writing custom Stroke classes */ public class CustomStrokes extends JPanel{

 static final int WIDTH = 750, HEIGHT = 200; // Size of our example
 public String getName() {
   return "Custom Strokes";
 }
 public int getWidth() {
   return WIDTH;
 }
 public int getHeight() {
   return HEIGHT;
 }
 // These are the various stroke objects we"ll demonstrate
 Stroke[] strokes = new Stroke[] { new BasicStroke(4.0f), // The standard,
     // predefined
     // stroke
     new NullStroke(), // A Stroke that does nothing
     new DoubleStroke(8.0f, 2.0f), // A Stroke that strokes twice
     new ControlPointsStroke(2.0f), // Shows the vertices & control
     // points
     new SloppyStroke(2.0f, 3.0f) // Perturbs the shape before stroking
 };
 /** Draw the example */
 public void paint(Graphics g1) {
   Graphics2D g = (Graphics2D)g1;
   // Get a shape to work with. Here we"ll use the letter B
   Font f = new Font("Serif", Font.BOLD, 200);
   GlyphVector gv = f.createGlyphVector(g.getFontRenderContext(), "B");
   Shape shape = gv.getOutline();
   // Set drawing attributes and starting position
   g.setColor(Color.black);
   g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
   g.translate(10, 175);
   // Draw the shape once with each stroke
   for (int i = 0; i < strokes.length; i++) {
     g.setStroke(strokes[i]); // set the stroke
     g.draw(shape); // draw the shape
     g.translate(140, 0); // move to the right
   }
 }
 public static void main(String[] a) {
   JFrame f = new JFrame();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   f.setContentPane(new CustomStrokes());
   f.setSize(750,200);
   f.setVisible(true);
 }

} /**

* This Stroke implementation does nothing. Its createStrokedShape() method
* returns an unmodified shape. Thus, drawing a shape with this Stroke is the
* same as filling that shape!
*/

class NullStroke implements Stroke {

 public Shape createStrokedShape(Shape s) {
   return s;
 }

} /**

* This Stroke implementation applies a BasicStroke to a shape twice. If you
* draw with this Stroke, then instead of outlining the shape, you"re outlining
* the outline of the shape.
*/

class DoubleStroke implements Stroke {

 BasicStroke stroke1, stroke2; // the two strokes to use
 public DoubleStroke(float width1, float width2) {
   stroke1 = new BasicStroke(width1); // Constructor arguments specify
   stroke2 = new BasicStroke(width2); // the line widths for the strokes
 }
 public Shape createStrokedShape(Shape s) {
   // Use the first stroke to create an outline of the shape
   Shape outline = stroke1.createStrokedShape(s);
   // Use the second stroke to create an outline of that outline.
   // It is this outline of the outline that will be filled in
   return stroke2.createStrokedShape(outline);
 }

} /**

* This Stroke implementation strokes the shape using a thin line, and also
* displays the end points and Bezier curve control points of all the line and
* curve segments that make up the shape. The radius argument to the constructor
* specifies the size of the control point markers. Note the use of PathIterator
* to break the shape down into its segments, and of GeneralPath to build up the
* stroked shape.
*/

class ControlPointsStroke implements Stroke {

 float radius; // how big the control point markers should be
 public ControlPointsStroke(float radius) {
   this.radius = radius;
 }
 public Shape createStrokedShape(Shape shape) {
   // Start off by stroking the shape with a thin line. Store the
   // resulting shape in a GeneralPath object so we can add to it.
   GeneralPath strokedShape = new GeneralPath(new BasicStroke(1.0f)
       .createStrokedShape(shape));
   // Use a PathIterator object to iterate through each of the line and
   // curve segments of the shape. For each one, mark the endpoint and
   // control points (if any) by adding a rectangle to the GeneralPath
   float[] coords = new float[6];
   for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i
       .next()) {
     int type = i.currentSegment(coords);
     Shape s = null, s2 = null, s3 = null;
     switch (type) {
     case PathIterator.SEG_CUBICTO:
       markPoint(strokedShape, coords[4], coords[5]); // falls through
     case PathIterator.SEG_QUADTO:
       markPoint(strokedShape, coords[2], coords[3]); // falls through
     case PathIterator.SEG_MOVETO:
     case PathIterator.SEG_LINETO:
       markPoint(strokedShape, coords[0], coords[1]); // falls through
     case PathIterator.SEG_CLOSE:
       break;
     }
   }
   return strokedShape;
 }
 /** Add a small square centered at (x,y) to the specified path */
 void markPoint(GeneralPath path, float x, float y) {
   path.moveTo(x - radius, y - radius); // Begin a new sub-path
   path.lineTo(x + radius, y - radius); // Add a line segment to it
   path.lineTo(x + radius, y + radius); // Add a second line segment
   path.lineTo(x - radius, y + radius); // And a third
   path.closePath(); // Go back to last moveTo position
 }

} /**

* This Stroke implementation randomly perturbs the line and curve segments that
* make up a Shape, and then strokes that perturbed shape. It uses PathIterator
* to loop through the Shape and GeneralPath to build up the modified shape.
* Finally, it uses a BasicStroke to stroke the modified shape. The result is a
* "sloppy" looking shape.
*/

class SloppyStroke implements Stroke {

 BasicStroke stroke;
 float sloppiness;
 public SloppyStroke(float width, float sloppiness) {
   this.stroke = new BasicStroke(width); // Used to stroke modified shape
   this.sloppiness = sloppiness; // How sloppy should we be?
 }
 public Shape createStrokedShape(Shape shape) {
   GeneralPath newshape = new GeneralPath(); // Start with an empty shape
   // Iterate through the specified shape, perturb its coordinates, and
   // use them to build up the new shape.
   float[] coords = new float[6];
   for (PathIterator i = shape.getPathIterator(null); !i.isDone(); i
       .next()) {
     int type = i.currentSegment(coords);
     switch (type) {
     case PathIterator.SEG_MOVETO:
       perturb(coords, 2);
       newshape.moveTo(coords[0], coords[1]);
       break;
     case PathIterator.SEG_LINETO:
       perturb(coords, 2);
       newshape.lineTo(coords[0], coords[1]);
       break;
     case PathIterator.SEG_QUADTO:
       perturb(coords, 4);
       newshape.quadTo(coords[0], coords[1], coords[2], coords[3]);
       break;
     case PathIterator.SEG_CUBICTO:
       perturb(coords, 6);
       newshape.curveTo(coords[0], coords[1], coords[2], coords[3],
           coords[4], coords[5]);
       break;
     case PathIterator.SEG_CLOSE:
       newshape.closePath();
       break;
     }
   }
   // Finally, stroke the perturbed shape and return the result
   return stroke.createStrokedShape(newshape);
 }
 // Randomly modify the specified number of coordinates, by an amount
 // specified by the sloppiness field.
 void perturb(float[] coords, int numCoords) {
   for (int i = 0; i < numCoords; i++)
     coords[i] += (float) ((Math.random() * 2 - 1.0) * sloppiness);
 }

}




 </source>   



Dashed rectangle

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.geom.Arc2D; import java.awt.geom.Ellipse2D; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import javax.swing.JApplet; import javax.swing.JFrame; public class DashedRectangleDemo2D extends JApplet {

 final static float dash1[] = { 10.0f };
 final static BasicStroke dashed = new BasicStroke(1.0f,
     BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
 
 public void init() {
   setBackground(Color.white);
   setForeground(Color.white);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
       RenderingHints.VALUE_ANTIALIAS_ON);
   g2.setPaint(Color.gray);
   int x = 5;
   int y = 7;
   g2.setStroke(dashed);
   g2.draw(new RoundRectangle2D.Double(x, y, 200, 200,
           10, 10));
   g2.drawString("RoundRectangle2D", x, 250);
   
 }
 public static void main(String s[]) {
   JFrame f = new JFrame("");
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   JApplet applet = new DashedRectangleDemo2D();
   f.getContentPane().add("Center", applet);
   applet.init();
   f.pack();
   f.setSize(new Dimension(300, 300));
   f.show();
 }

}




 </source>   



Dashed stroke

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class DashedStrokeDemo extends JPanel {

 public void init() {
   setBackground(Color.white);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   float dash[] = { 10.0f };
   g2.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_BUTT,
       BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
   g2.setPaint(Color.blue);
   
   Rectangle r = new Rectangle(5,5,200,200);
   
   g2.draw(r);
 }
 public static void main(String s[]) {
   JFrame f = new JFrame();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   DashedStrokeDemo p = new DashedStrokeDemo();
   f.getContentPane().add("Center", p);
   p.init();
   f.pack();
   f.setSize(new Dimension(250, 250));
   f.show();
 }

}




 </source>   



Serialises a Stroke object

<source lang="java">

import java.awt.BasicStroke; import java.awt.Stroke; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* ------------
* IOUtils.java
* ------------
* (C)opyright 2002-2004, by Thomas Morgner and Contributors.
*
* Original Author:  Thomas Morgner;
* Contributor(s):   David Gilbert (for Object Refinery Limited);
*
* $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
*
* Changes
* -------
* 26-Jan-2003 : Initial version
* 23-Feb-2003 : Documentation
* 25-Feb-2003 : Fixed Checkstyle issues (DG);
* 29-Apr-2003 : Moved to jcommon
* 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
*               added support for query strings within these urls (TM);
*/

public class Main {

 /**
  * Returns true if a class implements Serializable
  * and false otherwise.
  *
  * @param c  the class.
  *
  * @return A boolean.
  */
 public static boolean isSerializable(final Class c) {
     /**
     final Class[] interfaces = c.getInterfaces();
     for (int i = 0; i < interfaces.length; i++) {
         if (interfaces[i].equals(Serializable.class)) {
             return true;
         }
     }
     Class cc = c.getSuperclass();
     if (cc != null) {
         return isSerializable(cc);
     }
      */
     return (Serializable.class.isAssignableFrom(c));
 }
 /**
  * Reads a Stroke object that has been serialised by the
  * {@link SerialUtilities#writeStroke(Stroke, ObjectOutputStream)} method.
  *
  * @param stream  the input stream (null not permitted).
  *
  * @return The stroke object (possibly null).
  *
  * @throws IOException  if there is an I/O problem.
  * @throws ClassNotFoundException  if there is a problem loading a class.
  */
 public static Stroke readStroke(final ObjectInputStream stream)
     throws IOException, ClassNotFoundException {
     if (stream == null) {
         throw new IllegalArgumentException("Null "stream" argument.");
     }
     Stroke result = null;
     final boolean isNull = stream.readBoolean();
     if (!isNull) {
         final Class c = (Class) stream.readObject();
         if (c.equals(BasicStroke.class)) {
             final float width = stream.readFloat();
             final int cap = stream.readInt();
             final int join = stream.readInt();
             final float miterLimit = stream.readFloat();
             final float[] dash = (float[]) stream.readObject();
             final float dashPhase = stream.readFloat();
             result = new BasicStroke(
                 width, cap, join, miterLimit, dash, dashPhase
             );
         }
         else {
             result = (Stroke) stream.readObject();
         }
     }
     return result;
 }
 /**
  * Serialises a Stroke object.  This code handles the
  * BasicStroke class which is the only Stroke
  * implementation provided by the JDK (and isn"t directly
  * Serializable).
  *
  * @param stroke  the stroke object (null permitted).
  * @param stream  the output stream (null not permitted).
  *
  * @throws IOException if there is an I/O error.
  */
 public static void writeStroke(final Stroke stroke,
                                final ObjectOutputStream stream)
     throws IOException {
     if (stream == null) {
         throw new IllegalArgumentException("Null "stream" argument.");
     }
     if (stroke != null) {
         stream.writeBoolean(false);
         if (stroke instanceof BasicStroke) {
             final BasicStroke s = (BasicStroke) stroke;
             stream.writeObject(BasicStroke.class);
             stream.writeFloat(s.getLineWidth());
             stream.writeInt(s.getEndCap());
             stream.writeInt(s.getLineJoin());
             stream.writeFloat(s.getMiterLimit());
             stream.writeObject(s.getDashArray());
             stream.writeFloat(s.getDashPhase());
         }
         else {
             stream.writeObject(stroke.getClass());
             stream.writeObject(stroke);
         }
     }
     else {
         stream.writeBoolean(true);
     }
 }

}

 </source>   



Smokey effect

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import javax.swing.JFrame; import javax.swing.JPanel; public class Overlap extends JPanel {

 public static void main(String[] args) {
   JFrame f = new JFrame();
   f.getContentPane().add(new Overlap());
   f.setSize(300, 200);
   f.setVisible(true);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   double x = 15, y = 50, w = 70, h = 70;
   Ellipse2D e = new Ellipse2D.Double(x, y, w, h);
   g2.setStroke(new BasicStroke(8));
   Color smokeyColor = new Color(128, 128, 128, 128);
   g2.setPaint(smokeyColor);
   g2.fill(e);
   g2.draw(e);
   e.setFrame(x + 100, y, w, h);
   g2.setPaint(Color.black);
   g2.draw(e);
   g2.setPaint(Color.gray);
   g2.fill(e);
   e.setFrame(x + 200, y, w, h);
   g2.setPaint(Color.gray);
   g2.fill(e);
   g2.setPaint(Color.black);
   g2.draw(e);
 }

}




 </source>   



Stroke with iron effect

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Ellipse2D; import javax.swing.JFrame; import javax.swing.JPanel; public class PaintingAndStroking extends JPanel{

 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   double x = 15, y = 50, w = 70, h = 70;
   Ellipse2D e = new Ellipse2D.Double(x, y, w, h);
   GradientPaint gp = new GradientPaint(75, 75, Color.white, 95, 95,
       Color.gray, true);
   // Fill with a gradient.
   g2.setPaint(gp);
   g2.fill(e);
   // Stroke with a solid color.
   e.setFrame(x + 100, y, w, h);
   g2.setPaint(Color.black);
   g2.setStroke(new BasicStroke(8));
   g2.draw(e);
   // Stroke with a gradient.
   e.setFrame(x + 200, y, w, h);
   g2.setPaint(gp);
   g2.draw(e);
 }
 public static void main(String[] args) {
   JFrame f = new JFrame();
   f.getContentPane().add(new PaintingAndStroking());
   f.setSize(350, 250);
   f.show();
 }

}




 </source>   



Stroking or Filling with a Texture

<source lang="java"> import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.TexturePaint; import java.awt.image.BufferedImage; import javax.swing.JComponent; import javax.swing.JFrame; public class BasicDraw {

 public static void main(String[] args) {
   JFrame frame = new JFrame();
   frame.add(new MyComponent());
   frame.setSize(300, 300);
   frame.setVisible(true);
 }

} class MyComponent extends JComponent {

 public void paint(Graphics g) {
   Graphics2D g2d = (Graphics2D) g;
   int x = 10;
   int y = 10;
   int width = 50;
   int height = 25;
   BufferedImage bi = new BufferedImage(20,20,BufferedImage.TYPE_INT_RGB);
   
   TexturePaint texture = new TexturePaint(bi, new Rectangle(x, y, width, height));
   g2d.setPaint(texture);
 }

}



 </source>   



Thick stroke demo

<source lang="java"> import java.awt.BasicStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; public class ThickStrokeDemo extends JPanel {

 public void init() {
   setBackground(Color.white);
 }
 public void paint(Graphics g) {
   Graphics2D g2 = (Graphics2D) g;
   g2.setStroke(new BasicStroke(8.0f));
   g2.setPaint(Color.blue);
   
   Rectangle r = new Rectangle(5,5,200,200);
   
   g2.draw(r);
 }
 public static void main(String s[]) {
   JFrame f = new JFrame();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   ThickStrokeDemo p = new ThickStrokeDemo();
   f.getContentPane().add("Center", p);
   p.init();
   f.pack();
   f.setSize(new Dimension(250, 250));
   f.show();
 }

}




 </source>   



Tries to deduct the stroke-type from the given stroke object.

<source lang="java"> /**

* 
* JFreeReport : a free Java reporting library
* 
*
* Project Info:  http://reporting.pentaho.org/
*
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* StrokeUtility.java
* ------------
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*/

import java.awt.BasicStroke; import java.awt.Stroke; import java.util.Arrays; /**

* This class provides helper methods to work with Strokes and line-styles.
* 
* @author Thomas Morgner
*/

public class StrokeUtility {

 /** A constant defining a stroke-type. */
 public static final int STROKE_SOLID = 0;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DASHED = 1;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOTTED = 2;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOT_DASH = 3;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOT_DOT_DASH = 4;
 /** A constant defining a stroke-type. */
 public static final int STROKE_NONE = 5;
 /**
  * Default Constructor. Private to prevent Object-creation.
  */
 private StrokeUtility() {
 }
 /**
  * Creates a new Stroke-Object for the given type and with.
  * 
  * @param type
  *          the stroke-type. (Must be one of the constants defined in this
  *          class.)
  * @param width
  *          the stroke"s width.
  * @return the stroke, never null.
  */
 public static Stroke createStroke(final int type, final float width) {
   final boolean useWidthForStrokes = true;
   final float effectiveWidth;
   if (useWidthForStrokes) {
     effectiveWidth = width;
   } else {
     effectiveWidth = 1;
   }
   switch (type) {
   case STROKE_DASHED:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 6 * effectiveWidth, 6 * effectiveWidth }, 0.0f);
   case STROKE_DOTTED:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 5.0f,
         new float[] { 0.0f, 2 * effectiveWidth }, 0.0f);
   case STROKE_DOT_DASH:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 0, 2 * effectiveWidth, 6 * effectiveWidth, 2 * effectiveWidth }, 0.0f);
   case STROKE_DOT_DOT_DASH:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 0, 2 * effectiveWidth, 0, 2 * effectiveWidth, 6 * effectiveWidth,
             2 * effectiveWidth }, 0.0f);
   default:
     return new BasicStroke(width);
   }
 }
 /**
  * Tries to extract the stroke-width from the given stroke object.
  * 
  * @param s
  *          the stroke.
  * @return the stroke"s width.
  */
 public static float getStrokeWidth(final Stroke s) {
   if (s instanceof BasicStroke) {
     final BasicStroke bs = (BasicStroke) s;
     return bs.getLineWidth();
   }
   return 1;
 }
 /**
  * Tries to deduct the stroke-type from the given stroke object. This will
  * result in funny return values if the stroke was not created by the
  * {@link #createStroke(int, float)} method.
  * 
  * @param s
  *          the stroke.
  * @return the stroke"s width.
  */
 public static int getStrokeType(final Stroke s) {
   if (s instanceof BasicStroke == false) {
     return STROKE_SOLID;
   }
   final BasicStroke bs = (BasicStroke) s;
   if (bs.getLineWidth() <= 0) {
     return STROKE_NONE;
   }
   final float[] dashes = bs.getDashArray();
   if (dashes == null) {
     return STROKE_SOLID;
   }
   if (dashes.length < 2) {
     return STROKE_SOLID;
   }
   if (dashes.length == 3 || dashes.length == 5) {
     return STROKE_SOLID;
   }
   if (dashes.length == 2) {
     // maybe dashed or dotted ...
     // if (dashes[0] < 2 && dashes[1] < 2) {
     // return STROKE_DOTTED;
     // }
     final float factor = dashes[0] / dashes[1];
     if (factor > 0.9 && factor < 1.1) {
       return STROKE_DASHED;
     } else if (factor < 0.1) {
       return STROKE_DOTTED;
     }
     // else ... not recognized ...
     return STROKE_SOLID;
   } else if (dashes.length == 4) {
     // maybe a dot-dashed stroke ...
     final float[] copyDashes = (float[]) dashes.clone();
     Arrays.sort(copyDashes);
     // the first value should be near zero ..
     if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     // test that the first two values have the same size
     final float factor1 = (2 * bs.getLineWidth()) / copyDashes[1];
     final float factor2 = (2 * bs.getLineWidth()) / copyDashes[2];
     final float factorBig = (2 * bs.getLineWidth()) / copyDashes[3];
     if ((factor1 < 0.9 || factor1 > 1.1) || (factor2 < 0.9 || factor2 > 1.1)) {
       // not recognized ...
       return STROKE_SOLID;
     }
     if (factorBig < 0.4 || factorBig > 2.5) {
       return STROKE_DOT_DASH;
     }
     if (factorBig < 0.9 || factorBig > 1.1) {
       return STROKE_DOTTED;
     }
     return STROKE_DASHED;
   } else if (dashes.length == 6) {
     // maybe a dot-dashed stroke ...
     final float[] copyDashes = (float[]) dashes.clone();
     Arrays.sort(copyDashes);
     // test that the first three values have the same size
     // the first two values should be near zero ..
     if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     if (Math.abs(copyDashes[1] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     final float factor2 = (2 * bs.getLineWidth()) / copyDashes[2];
     final float factor3 = (2 * bs.getLineWidth()) / copyDashes[3];
     final float factor4 = (2 * bs.getLineWidth()) / copyDashes[4];
     final float factorBig = (2 * bs.getLineWidth()) / copyDashes[5];
     if ((factor2 < 0.9 || factor2 > 1.1) || (factor3 < 0.9 || factor3 > 1.1)
         || (factor4 < 0.9 || factor4 > 1.1)) {
       return STROKE_SOLID;
     }
     if (factorBig < 0.4 || factorBig > 2.5) {
       return STROKE_DOT_DOT_DASH;
     }
     if ((factorBig < 0.9 || factorBig > 1.1)) {
       return STROKE_DOTTED;
     }
     return STROKE_DASHED;
   }
   // not recognized ...
   return STROKE_SOLID;
 }

}


 </source>   



Tries to extract the stroke-width from the given stroke object.

<source lang="java"> /**

* 
* JFreeReport : a free Java reporting library
* 
*
* Project Info:  http://reporting.pentaho.org/
*
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* StrokeUtility.java
* ------------
* (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
*/

import java.awt.BasicStroke; import java.awt.Stroke; import java.util.Arrays; /**

* This class provides helper methods to work with Strokes and line-styles.
* 
* @author Thomas Morgner
*/

public class StrokeUtility {

 /** A constant defining a stroke-type. */
 public static final int STROKE_SOLID = 0;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DASHED = 1;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOTTED = 2;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOT_DASH = 3;
 /** A constant defining a stroke-type. */
 public static final int STROKE_DOT_DOT_DASH = 4;
 /** A constant defining a stroke-type. */
 public static final int STROKE_NONE = 5;
 /**
  * Default Constructor. Private to prevent Object-creation.
  */
 private StrokeUtility() {
 }
 /**
  * Creates a new Stroke-Object for the given type and with.
  * 
  * @param type
  *          the stroke-type. (Must be one of the constants defined in this
  *          class.)
  * @param width
  *          the stroke"s width.
  * @return the stroke, never null.
  */
 public static Stroke createStroke(final int type, final float width) {
   final boolean useWidthForStrokes = true;
   final float effectiveWidth;
   if (useWidthForStrokes) {
     effectiveWidth = width;
   } else {
     effectiveWidth = 1;
   }
   switch (type) {
   case STROKE_DASHED:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 6 * effectiveWidth, 6 * effectiveWidth }, 0.0f);
   case STROKE_DOTTED:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 5.0f,
         new float[] { 0.0f, 2 * effectiveWidth }, 0.0f);
   case STROKE_DOT_DASH:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 0, 2 * effectiveWidth, 6 * effectiveWidth, 2 * effectiveWidth }, 0.0f);
   case STROKE_DOT_DOT_DASH:
     return new BasicStroke(width, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f,
         new float[] { 0, 2 * effectiveWidth, 0, 2 * effectiveWidth, 6 * effectiveWidth,
             2 * effectiveWidth }, 0.0f);
   default:
     return new BasicStroke(width);
   }
 }
 /**
  * Tries to extract the stroke-width from the given stroke object.
  * 
  * @param s
  *          the stroke.
  * @return the stroke"s width.
  */
 public static float getStrokeWidth(final Stroke s) {
   if (s instanceof BasicStroke) {
     final BasicStroke bs = (BasicStroke) s;
     return bs.getLineWidth();
   }
   return 1;
 }
 /**
  * Tries to deduct the stroke-type from the given stroke object. This will
  * result in funny return values if the stroke was not created by the
  * {@link #createStroke(int, float)} method.
  * 
  * @param s
  *          the stroke.
  * @return the stroke"s width.
  */
 public static int getStrokeType(final Stroke s) {
   if (s instanceof BasicStroke == false) {
     return STROKE_SOLID;
   }
   final BasicStroke bs = (BasicStroke) s;
   if (bs.getLineWidth() <= 0) {
     return STROKE_NONE;
   }
   final float[] dashes = bs.getDashArray();
   if (dashes == null) {
     return STROKE_SOLID;
   }
   if (dashes.length < 2) {
     return STROKE_SOLID;
   }
   if (dashes.length == 3 || dashes.length == 5) {
     return STROKE_SOLID;
   }
   if (dashes.length == 2) {
     // maybe dashed or dotted ...
     // if (dashes[0] < 2 && dashes[1] < 2) {
     // return STROKE_DOTTED;
     // }
     final float factor = dashes[0] / dashes[1];
     if (factor > 0.9 && factor < 1.1) {
       return STROKE_DASHED;
     } else if (factor < 0.1) {
       return STROKE_DOTTED;
     }
     // else ... not recognized ...
     return STROKE_SOLID;
   } else if (dashes.length == 4) {
     // maybe a dot-dashed stroke ...
     final float[] copyDashes = (float[]) dashes.clone();
     Arrays.sort(copyDashes);
     // the first value should be near zero ..
     if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     // test that the first two values have the same size
     final float factor1 = (2 * bs.getLineWidth()) / copyDashes[1];
     final float factor2 = (2 * bs.getLineWidth()) / copyDashes[2];
     final float factorBig = (2 * bs.getLineWidth()) / copyDashes[3];
     if ((factor1 < 0.9 || factor1 > 1.1) || (factor2 < 0.9 || factor2 > 1.1)) {
       // not recognized ...
       return STROKE_SOLID;
     }
     if (factorBig < 0.4 || factorBig > 2.5) {
       return STROKE_DOT_DASH;
     }
     if (factorBig < 0.9 || factorBig > 1.1) {
       return STROKE_DOTTED;
     }
     return STROKE_DASHED;
   } else if (dashes.length == 6) {
     // maybe a dot-dashed stroke ...
     final float[] copyDashes = (float[]) dashes.clone();
     Arrays.sort(copyDashes);
     // test that the first three values have the same size
     // the first two values should be near zero ..
     if (Math.abs(copyDashes[0] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     if (Math.abs(copyDashes[1] / bs.getLineWidth()) > 0.5) {
       // not recognized ..
       return STROKE_SOLID;
     }
     final float factor2 = (2 * bs.getLineWidth()) / copyDashes[2];
     final float factor3 = (2 * bs.getLineWidth()) / copyDashes[3];
     final float factor4 = (2 * bs.getLineWidth()) / copyDashes[4];
     final float factorBig = (2 * bs.getLineWidth()) / copyDashes[5];
     if ((factor2 < 0.9 || factor2 > 1.1) || (factor3 < 0.9 || factor3 > 1.1)
         || (factor4 < 0.9 || factor4 > 1.1)) {
       return STROKE_SOLID;
     }
     if (factorBig < 0.4 || factorBig > 2.5) {
       return STROKE_DOT_DOT_DASH;
     }
     if ((factorBig < 0.9 || factorBig > 1.1)) {
       return STROKE_DOTTED;
     }
     return STROKE_DASHED;
   }
   // not recognized ...
   return STROKE_SOLID;
 }

}


 </source>