自定义画笔 : 画笔 « 图形用户界面 « Java

En
Java
1. 图形用户界面
2. 三维图形动画
3. 高级图形
4. 蚂蚁编译
5. Apache类库
6. 统计图
7. 
8. 集合数据结构
9. 数据类型
10. 数据库JDBC
11. 设计模式
12. 开发相关类
13. EJB3
14. 电子邮件
15. 事件
16. 文件输入输出
17. 游戏
18. 泛型
19. GWT
20. Hibernate
21. 本地化
22. J2EE平台
23. 基于J2ME
24. JDK-6
25. JNDI的LDAP
26. JPA
27. JSP技术
28. JSTL
29. 语言基础知识
30. 网络协议
31. PDF格式RTF格式
32. 映射
33. 常规表达式
34. 脚本
35. 安全
36. Servlets
37. Spring
38. Swing组件
39. 图形用户界面
40. SWT-JFace-Eclipse
41. 线程
42. 应用程序
43. Velocity
44. Web服务SOA
45. 可扩展标记语言
Java 教程
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.com/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.0f2.0f)// A Stroke that strokes twice
      new ControlPointsStroke(2.0f)// Shows the vertices & control
      // points
      new SloppyStroke(2.0f3.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(10175);

    // 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(1400)// 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() 1.0* sloppiness);
  }
}

           
         
    
  
Related examples in the same category
1. 虚线矩形虚线矩形
2. 一种虚线画笔
3. 画笔或与纹理填充
4. 基本画笔基本画笔
5. 厚画笔演示厚画笔演示
6. 虚线画笔虚线画笔
7. 画笔铁效果画笔铁效果
8. 烟效果烟效果
9. Stroke Test Stroke Test
10. 改变厚度的笔
www.java2java.com | Contact Us
Copyright 2010 - 2030 Java Source and Support. All rights reserved.
All other trademarks are property of their respective owners.