Step By Step(Java 2D图形篇<一>) (一)

2014-11-24 03:21:36 · 作者: · 浏览: 0

本篇将主要为您介绍Java的2D图形编程技术,然而在示例代码中还将会涉及一些简单的Swing知识,我们会尽可能的将2D中的方法进行归类和抽取,以便使您的关注点始终保持在Java2D上。该篇还会和本系列中其他篇章的风格保持一致,只是介绍必要的关键概念,更多的技术点是通过已经良好分类的有代表性的示例代码来为您展示和说明。

1. 形状绘制:

在Java 2D中提供了下面几个基本形状:

1) Line2D

2) Rectangle2D

3) RoundRectangle2D

4) Ellipse2D

5) Arc2D

6) QuadCurve2D

7) CubicCurve2D

8) GeneralPath

上面列出的对象均实现了Shape接口,因此可以作为Graphics2D类的draw方法的参数来绘制不同的图形。在实际的应用中,我们都是通过构造他们的内部类(均继承自对应的外部类)并返回该外部类的方式获取一个形状对象的实例,如:

Rectangle2D floatRect = new Rectangle2D.Float(1F,10F,2.5F,2.5F);

Rectangle2D doubleRect = new Rectangle2D.Double(1,10,2.5,2.5);

1) 绘制Line2D和Rectangle2D:

这两个形状是所有形状中最为基本也最容易理解的两个形状,那么我们就从这里下手小试牛刀。

1 public class MyTest extends JPanel {

2 public static void main(String args[]) {

3 JFrame f = new JFrame("Rectangle And Line");

4 f.setSize(360, 300);

5 f.add(new MyTest());

6 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

7 f.setLocationRelativeTo(null);

8 f.setVisible(true);

9 }

10 public MyTest() {

11 setBackground(Color.white);

12 setForeground(Color.white);

13 }

14 //在Swing中,所有的自绘操作都是通过重载各个组件的paint和paintComponent方法

15 //来实现的,如果组件部分被遮盖或整个被隐藏,在重新bringToFront的时候,repaint

16 //方法会被Swing的EDT(Event Dispatching Thread)调用,从而导致该方法被调用。

17 @Override

18 public void paintComponent(Graphics g) {

19 super.paintComponent(g);

20 paintRectangle(g);

21 paintLine(g);

22 }

23 //绘制一条直线

24 private void paintLine(Graphics g) {

25 Graphics2D g2 = (Graphics2D) g;

26 g2.setPaint(Color.gray);

27 int x = 100;

28 int y = 75;

29 g2.draw(new Line2D.Double(x, y, 250, 195));

30 }

31 //绘制一个矩形边框,填充一个矩形

32 private void paintRectangle(Graphics g) {

33 Graphics2D g2d = (Graphics2D) g;

34 g2d.setColor(new Color(212, 212, 212));

35 g2d.draw(new Rectangle2D.Float(10, 15, 90, 60));

36 g2d.setColor(new Color(31, 21, 1));

37 g2d.fill(new Rectangle2D.Float(250, 195, 90, 60));

38 }

39 }

对于上例paintRectangle方法中的Graphics2D.draw和Graphics2D.fill方法,可以分别替换为g2d.drawRect(10,15,90,60) 和g2d.fillRect(250,195,90,60),他们的结果是完全一致的。然而在《Java极富客户端效果开发》中,推荐使用后者,原因是通用的draw方法会由于在绘制前需要做一些和类型判断相关的工作,因此会影响效率。而后者由于直接调用和形状相关的方法,如drawRect和fillRect,这样在绘制时已经非常清楚当前的形状为矩形,见如下比较代码:

1 private void paintTest(Graphics g) {

2 final int LINE_X = 100;

3 final int RECT_X = 200;

4 final int TEXT_X = 250;

5 final int BAD_Y = 60;

6 final int GOOD_Y = 160;

7 final int ITERATIONS = 1000;

8 Graphics2D g2d = (Graphics2D) g;

9 long startTime, endTime, totalTime;

10 g.setColor(Color.WHITE);

11 g.fillRect(0, 0, getWidth(), getHeight());

12 g.setColor(Color.BLACK);

13

14 g.drawString("Bad vs. Good Primitive Rendering", 50, 20);

15 g.drawString("(" + ITERATIONS + " iterations)", 100, 35);

16 g.drawString("Bad: ", 10, BAD_Y + 30);

17