分享
 
 
 

Draw2D 教程(四)

王朝other·作者佚名  2007-05-29
窄屏简体版  字體: |||超大  

4、使用Graphics来创建图形

在SWT中,graphic context(GC)可以单独创建为一个对象,也可以通过PaintEvent获得。但是在Draw2d中,Figure

可以从2.1节中讲述的那些paint方法中获得Graphics(方法参数)。Graphics的绝大多数方法都和CG中的相同,最大

的不同是Draw2d允许Graphics对象利用translate()方法移动。

然而,Draw2d提供了更为强大的功能来创建和操纵几何图形(Shapes)。它有好几个包、很多类用来处理几何图形。

4.1、使用Graphics类

如前所述,Graphics类的方法和SWT的GC基本一样,所以,在这一小节里,我们将创建图C.2种列出的那些组件,即

如下三种Figure:

1)DecisionFigure——即程序流程图中的分支结构,一个输入,两个输出(是/否)。

2)ProcessFigure——流程图中的某个处理,一个输入,一个输出。

3)TerminatorFigure——表示一个程序流程的开始或者结束,只有一个输入(结束)或输出(开始)。

对于我们的以上三种Figure,他们的大小由一个叫做size的变量来控制,他们上面显示的文字由一个叫做message

的String来设置。这些限制都来自于Figure对象的外部,所以暂时你还看不到。

这些类的代码如下:(列表C.3至C.5)

列表C.3:DecisionFigure.java

package com.swtjface.AppC;

import org.eclipse.draw2d.*;

import org.eclipse.draw2d.geometry.*;

public class DecisionFigure extends ActivityFigure

{

FixedAnchor inAnchor, yesAnchor, noAnchor;

public DecisionFigure()

{

inAnchor = new FixedAnchor(this);

inAnchor.place = new Point(1, 0);

targetAnchors.put("in_dec",inAnchor);

noAnchor = new FixedAnchor(this);

noAnchor.place = new Point(2, 1);

sourceAnchors.put("no",noAnchor);

yesAnchor = new FixedAnchor(this);

yesAnchor.place = new Point(1, 2);

sourceAnchors.put("yes",yesAnchor);

}

public void paintFigure(Graphics g)

{

Rectangle r = bounds;

PointList pl = new PointList(4);

pl.addPoint(r.x + r.width/2, r.y);

pl.addPoint(r.x, r.y + r.height/2);

pl.addPoint(r.x + r.width/2, r.y + r.height-1);

pl.addPoint(r.x + r.width, r.y + r.height/2);

g.drawPolygon(pl);

g.drawText(message, r.x+r.width/4+5, r.y+3*r.height/8);

g.drawText("N", r.x+7*r.width/8, r.y+3*r.height/8);

g.drawText("Y", r.x+r.width/2-2, r.y+3*r.height/4);

}

}

由于分支结构不是规则图形(它是个棱形),无法使用既有图形,所以我们需要指定一系列点来描绘它;谢天谢地,

ProcessFigure是一个矩形(Rectangle),所以容易创建地多。

列表C.4:ProcessFigure.java

package com.swtjface.AppC;

import org.eclipse.draw2d.*;

import org.eclipse.draw2d.geometry.*;

public class ProcessFigure extends ActivityFigure

{

FixedAnchor inAnchor, outAnchor;

public ProcessFigure()

{

inAnchor = new FixedAnchor(this);

inAnchor.place = new Point(1, 0);

targetAnchors.put("in_proc", inAnchor);

outAnchor = new FixedAnchor(this);

outAnchor.place = new Point(1, 2);

sourceAnchors.put("out_proc", outAnchor);

}

public void paintFigure(Graphics g)

{

Rectangle r = bounds;

g.drawText(message, r.x + r.width/4, r.y + r.height/4);

g.drawRectangle(r.x, r.y, r.width-1, r.height-1);

}

}

TerminatorFigure的左右两条边是圆弧,所以比ProcessFigure要麻烦点,但代码却是不难理解的。

列表C.5:TerminatorFigure.java

package com.swtjface.AppC;

import org.eclipse.draw2d.*;

import org.eclipse.draw2d.geometry.*;

public class TerminatorFigure extends ActivityFigure

{

FixedAnchor inAnchor, outAnchor;

public TerminatorFigure()

{

inAnchor = new FixedAnchor(this);

inAnchor.place = new Point(1, 0);

targetAnchors.put("in_term",inAnchor);

outAnchor = new FixedAnchor(this);

outAnchor.place = new Point(1, 2);

sourceAnchors.put("out_term",outAnchor);

}

public void paintFigure(Graphics g)

{

Rectangle r = bounds;

g.drawArc(r.x + r.width/8, r.y, r.width/4, r.height-1, 90, 180);

g.drawLine(r.x + r.width/4, r.y, r.x + 3*r.width/4, r.y);

g.drawLine(r.x + r.width/4, r.y + r.height-1, r.x + 3*r.width/4,

r.y + r.height-1);

g.drawArc(r.x + 5*r.width/8, r.y, r.width/4, r.height-1, 270, 180);

g.drawText(message, r.x+3*r.width/8, r.y+r.height/8);

}

}

显然,这些类不会只负责将图形画出来就完事了,还有两个更复杂的方面:一是这些Figure需要连接到其他的Figure

上去,这需要使用ConnectionAnchors(叫做FixedAnchors)。第二,这些图形将来在讲述GEF的时候还要用到,很

多方法现在解释还为时过早(作者这里主要指拖拽、编辑上面的文字等功能)。

由于所有这三个类都继承了ActivityFigure,所以现在该它登场了。这个基类包含上述三个Figure的共性。如列表

C.6所示,他的大部分方法用来跟踪Connections以及Connections的anchors。

列表C.6:ActivityFigure.java

package com.swtjface.AppC;

import org.eclipse.draw2d.*;

import org.eclipse.draw2d.geometry.*;

import java.util.*;

abstract public class ActivityFigure

extends Figure

{

Rectangle r = new Rectangle();

Hashtable targetAnchors = new Hashtable();

Hashtable sourceAnchors = new Hashtable();

String message = new String();

public void setName(String msg)

{

message = msg;

repaint();

}

public ConnectionAnchor ConnectionAnchorAt(Point p)

{

ConnectionAnchor closest = null;

long min = Long.MAX_VALUE;

Hashtable conn = getSourceConnectionAnchors();

conn.putAll(getTargetConnectionAnchors());

Enumeration e = conn.elements();

while (e.hasMoreElements())

{

ConnectionAnchor c = (ConnectionAnchor) e.nextElement();

Point p2 = c.getLocation(null);

long d = p.getDistance2(p2);

if (d < min)

{

min = d;

closest = c;

}

}

return closest;

}

public ConnectionAnchor getSourceConnectionAnchor(String name)

{

return (ConnectionAnchor)sourceAnchors.get(name);

}

public ConnectionAnchor getTargetConnectionAnchor(String name)

{

return (ConnectionAnchor)targetAnchors.get(name);

}

public String getSourceAnchorName(ConnectionAnchor c)

{

Enumeration enum = sourceAnchors.keys();

String name;

while (enum.hasMoreElements())

{

name = (String)enum.nextElement();

if (sourceAnchors.get(name).equals(c))

return name;

}

return null;

}

public String getTargetAnchorName(ConnectionAnchor c)

{

Enumeration enum = targetAnchors.keys();

String name = null;

while (enum.hasMoreElements())

{

name = (String)enum.nextElement();

if (targetAnchors.get(name).equals(c))

return name;

}

return null;

}

public ConnectionAnchor getSourceConnectionAnchorAt(Point p)

{

ConnectionAnchor closest = null;

long min = Long.MAX_VALUE;

Enumeration e = getSourceConnectionAnchors().elements();

while (e.hasMoreElements())

{

ConnectionAnchor c = (ConnectionAnchor) e.nextElement();

Point p2 = c.getLocation(null);

long d = p.getDistance2(p2);

if (d < min)

{

min = d;

closest = c;

}

}

return closest;

}

public Hashtable getSourceConnectionAnchors()

{

return sourceAnchors;

}

public ConnectionAnchor getTargetConnectionAnchorAt(Point p)

{

ConnectionAnchor closest = null;

long min = Long.MAX_VALUE;

Enumeration e = getTargetConnectionAnchors().elements();

while (e.hasMoreElements())

{

ConnectionAnchor c = (ConnectionAnchor) e.nextElement();

Point p2 = c.getLocation(null);

long d = p.getDistance2(p2);

if (d < min)

{

min = d;

closest = c;

}

}

return closest;

}

public Hashtable getTargetConnectionAnchors()

{

return targetAnchors;

}

}

对于ConnectionAnchor和Connection,我们将稍后再讨论。现在让我们看一下Draw2d的几何包。

4.2、Draw2d中的几何和图论

你已经看过如何使用Point和Rectangle,但Draw2d还提供了其他更多的类来处理几何图形。例如更高精度的类

PrecisionPoint,PrecisionRectangle,以及PrecisionDimension。此外还有Ray对象,其作用就像数学中的向量

一样;以及Transform类,用来实现移动、旋转、缩放等功能。

包org.eclipse.draw2d.graph里面有一些用来创建和分析有向图的工具类,例如基本的Node和Edge,以及特有的

布局管理器DirectedGraphLayout。图论已远超本书范围,但如果你对此有兴趣,这个包应该是很有用的。

Draw2d的Figure之间并非是用Edge连接的,而是用Connection,下面来讨论这个类。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有