以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 Java/Eclipse 』  (http://bbs.xml.org.cn/list.asp?boardid=41)
----  [转帖]GEF实践总结(三)简易数据库编辑器  (http://bbs.xml.org.cn/dispbbs.asp?boardid=41&rootid=&id=76632)


--  作者:hongjunli
--  发布时间:9/8/2009 12:19:00 PM

--  [转帖]GEF实践总结(三)简易数据库编辑器

关键字: gef实践 数据库编辑器
一. 目标

不基于GraphicalEditorWithPalette或GraphicalEditorWithFlyoutPalette,而是完全在ViewPart上,因为实际开发中用户很难接受GraphicalEditor呆板的界面风格。
实现了一个简易的DataBase->Table->TableColumn的图像编辑器。
在不停的增强功能的过程中,探索GEF。

二. 修改GraphicalViewer

Java代码
FigureCanvas canvas = (FigureCanvas) graphicalViewer.getControl();   
canvas.setBackground(ColorConstants.white);   
canvas.setScrollBarVisibility(FigureCanvas.ALWAYS);  

FigureCanvas canvas = (FigureCanvas) graphicalViewer.getControl();
canvas.setBackground(ColorConstants.white);
canvas.setScrollBarVisibility(FigureCanvas.ALWAYS);
GraphicalViewer的最底层控件是FigureCanvas
给FigureCanvas设置背景色,并一直显示滚动条

三. 修改模型、添加EditPart、增加Figure

四. Layout
在这步引入了Layout的概念,和SWT中的Layout作用是一样的。

Java代码
public class DataBaseFigure extends FreeformLayer implements IBaseFigure<DataBaseModel> {   
private DataBaseModel model;   
  
public DataBaseFigure() {   
this.setLayoutManager(new FreeformLayout());   
this.setBorder(new LineBorder(1));   
}  

public class DataBaseFigure extends FreeformLayer implements IBaseFigure<DataBaseModel> {
private DataBaseModel model;

public DataBaseFigure() {
this.setLayoutManager(new FreeformLayout());
this.setBorder(new LineBorder(1));
}
继承于FreeformLayer,FreeformLayer是一种上下左右四个方向都可以扩展的Figure。
使用的Layout是FreeformLayout,FreeformLayout实际上就是XYLayout,只是它在计算起始位置的时候都是(0,0)坐标

Java代码
public class TableFigure extends Figure implements IBaseFigure<TableModel> {   
private TableModel model;   
  
public TableFigure() {   
super();   
this.setBorder(new MarginBorder(20, 0, 0, 0));   
  
GridLayout layout = new GridLayout(1, true);   
this.setLayoutManager(layout);   
}  

public class TableFigure extends Figure implements IBaseFigure<TableModel> {
private TableModel model;

public TableFigure() {
super();
this.setBorder(new MarginBorder(20, 0, 0, 0));

GridLayout layout = new GridLayout(1, true);
this.setLayoutManager(layout);
}
为了代码简单,只继承于Figure,实际上可以继承于RectangleFigure。因为Table毕竟只显示是一个矩形。
TableFigure内部的Layout是GridLayout。GridLayout应该是3.4后才出现的。上面的代码表示内部的子Figure排成一个列且列宽相等(别扭,其实是因为只有一个列),和SWT内一样。
在GridLayout内创建子Figure在时设置坐标属性的时候,需要传递GridData对象,而不是Rectangle对象(XYLayout)。于是,我们修改了BaseEditPart的refreshVisual方法。代码如下:
Java代码
/**  
* @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()  
*/  
protected void refreshVisuals() {   
BaseModel model = (BaseModel) getModel();   
GraphicalEditPart parentEditPart = (GraphicalEditPart) getParent();   
IFigure parentFigure = parentEditPart.getFigure();   
LayoutManager parentLayout = parentFigure.getLayoutManager();   
  
if (parentLayout == null || parentLayout instanceof XYLayout) {   
// ...   
} else if (parentLayout instanceof GridLayout) {   
GridData constraint = new GridData(model.getW(), model.getH());   
parentEditPart.setLayoutConstraint(this, getFigure(), constraint);   
}   
}  

/**
* @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
*/
protected void refreshVisuals() {
BaseModel model = (BaseModel) getModel();
GraphicalEditPart parentEditPart = (GraphicalEditPart) getParent();
IFigure parentFigure = parentEditPart.getFigure();
LayoutManager parentLayout = parentFigure.getLayoutManager();

if (parentLayout == null || parentLayout instanceof XYLayout) {
// ...
} else if (parentLayout instanceof GridLayout) {
GridData constraint = new GridData(model.getW(), model.getH());
parentEditPart.setLayoutConstraint(this, getFigure(), constraint);
}
}


五. 分析Figure的关键方法
setBorder(new LineBorder(1));
表示有线条的边框,线条宽为1。其实LineBorder还可以设置颜色的。

setBorder(new MarginBorder(20, 0, 0, 0));
表示是一个空白的边框,上面20像素不会被子Figure占用,子Figure的坐标计算从20像素下面作为起始点进行计算。

Rectangle
Rectangle用来表示xywh值的类,同时封装了一些好用的计算方法。

Rectangle headerRect = bounds.getCopy();
从一个Rectangle获得拷贝后的新的Rectangle对象,注意,不要轻易去修改Figure.getBounds()得到的Rectangle,需要计算的时候应该从bounds.getCopy()获得新的Rectangle对象再去计算。

Rectangle的计算

headerRect.getTopLeft();  获得左上的坐标
bodyRect.crop(new Insets(21, 1, 1, 1)); crop 调整大小
Point
Point用来表示xy值的类,同时封装了一些好用的计算方法。

getCopy() 得到拷贝后的新对象
translate(1,1) 坐标移动
Graphics
Graphics就是在Draw2d中进行绘图的类。可以设置前景色setForegroundColor、背景色setBackgroundColor、画线drawLine、设置字体setFont、线条样式setLineStyle、填充一个矩形区域fillRectangle、画一个矩形drawRectangle、画文字drawText等操作。

六. 启动,查看运行效果

此主题相关图片如下:
按此在新窗口浏览图片
七. 总结

效果还不错。而且,代码也尽量做到简单,到此还没出现EditPolicy、Command等。
理解Layout
基本的使用Graphics进行绘图的技巧
懂得使用Rectangle和Point
源代码如下附件所示:

原文地址:http://lggege.javaeye.com/blog/464284



W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
78.125ms