6、集成
现在,我们几乎可以动手来写flowchart的主类代码了。但在此之前,我们先来了解一下在Draw2d中如何实现对Figure
的拖拽。另外,我们还会加入一个FigureFactory类,专门用来创建Figure。
6.1、Draw2d的拖拽
我们前面提到过一些Draw2d中比较重要的listener和event,但里面没有像SWT中的DragSource、DropTarget那样含义
直观的类。这是因为在写本文的时候,Draw2d尚未加入该特性,所以,我们下面要讲的Dnd类,将依赖Figure本身的特性,
将自己移动到合适的位置。
列表C.9:Dnd.java
package com.swtjface.AppC;
import org.eclipse.draw2d.*;
import org.eclipse.draw2d.geometry.*;
public class Dnd extends MouseMotionListener.Stub
implements MouseListener
{
public Dnd(IFigure figure)
{
figure.addMouseMotionListener(this);
figure.addMouseListener(this);
}
Point start;
public void mouseReleased(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
public void mouseDoubleClicked(MouseEvent e){}
public void mousePressed(MouseEvent e)
{
start = e.getLocation();
}
public void mouseDragged(MouseEvent e)
{
Point p = e.getLocation();
Dimension d = p.getDifference(start);
start = p;
Figure f = ((Figure)e.getSource());
f.setBounds(f.getBounds().getTranslated(d.width, d.height));
}
}
这个类继承了MouseMotionListener.Stub,这实际上是MouseMotionListener的一个空实现,使得你不必重写接口
MouseMotionListener内所有的方法。另外,由于我们需要在鼠标点击的时候做些事,所以实现了MouseListener接口。
6.2、使用FigureFactory创建Figure
我们将使用工厂模式来创建各个Figure,对应的类如下:
列表C.10:FigureFactory.java
package com.swtjface.AppC;
import org.eclipse.draw2d.IFigure;
public class FigureFactory
{
public static IFigure createTerminatorFigure()
{
return new TerminatorFigure();
}
public static IFigure createDecisionFigure()
{
return new DecisionFigure();
}
public static IFigure createProcessFigure()
{
return new ProcessFigure();
}
public static PathFigure createPathFigure()
{
return new PathFigure();
}
public static ChartFigure createChartFigure()
{
return new ChartFigure();
}
}
现在,我们已经创建了所有需要的Figure类以及生成它们的工厂,可以动手写可执行的主类了。
6.3、Flowchart类
最后的Flowchart如下:(译注:在这个类里,原作者并没有使用FigureFactory创建Figure,是疏漏)
列表C.11:Flowchart.java
package com.swtjface.AppC;
import org.eclipse.swt.widgets.*;
import org.eclipse.draw2d.*;
import org.eclipse.draw2d.geometry.*;
public class Flowchart
{
public static void main(String args[])
{
Shell shell = new Shell();
shell.setSize(200,300);
shell.open();
shell.setText("Flowchart");
LightweightSystem lws = new LightweightSystem(shell);
ChartFigure flowchart = new ChartFigure();
lws.setContents(flowchart);
TerminatorFigure start = new TerminatorFigure();
start.setName("Start");
start.setBounds(new Rectangle(40,20,80,20));
DecisionFigure dec = new DecisionFigure();
dec.setName("Should I?");
dec.setBounds(new Rectangle(30,60,100,60));
ProcessFigure proc = new ProcessFigure();
proc.setName("Do it!");
proc.setBounds(new Rectangle(40,140,80,40));
TerminatorFigure stop = new TerminatorFigure();
stop.setName("End");
stop.setBounds(new Rectangle(40,200,80,20));
PathFigure path1 = new PathFigure();
path1.setSourceAnchor(start.outAnchor);
path1.setTargetAnchor(dec.inAnchor);
PathFigure path2 = new PathFigure();
path2.setSourceAnchor(dec.yesAnchor);
path2.setTargetAnchor(proc.inAnchor);
PathFigure path3 = new PathFigure();
path3.setSourceAnchor(dec.noAnchor);
path3.setTargetAnchor(stop.inAnchor);
PathFigure path4 = new PathFigure();
path4.setSourceAnchor(proc.outAnchor);
path4.setTargetAnchor(stop.inAnchor);
flowchart.add(start);
flowchart.add(dec);
flowchart.add(proc);
flowchart.add(stop);
flowchart.add(path1);
flowchart.add(path2);
flowchart.add(path3);
flowchart.add(path4);
new Dnd(start);
new Dnd(proc);
new Dnd(dec);
new Dnd(stop);
Display display = Display.getDefault();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
}
}
虽然这个类的代码较长,但很容易理解。首先,将ChartFigure加到LightweightSystem上,然后创建并初始化四个Figure,
它们通过PathFigure相连接。当所有的Figure都加到图上后,每个Figure都和一个Dnd对相关联,以提供鼠标拖拽功能。