一. 目标
- 不基于GraphicalEditorWithPalette或GraphicalEditorWithFlyoutPalette,而是完全在ViewPart上,因为实际开发中用户很难接受GraphicalEditor呆板的界面风格。
- 实现了一个简易的DataBase->Table->TableColumn的图像编辑器。
- 在不停的增强功能的过程中,探索GEF。
二. 修改GraphicalViewer
FigureCanvas canvas = (FigureCanvas) graphicalViewer.getControl();
canvas.setBackground(ColorConstants.white);
canvas.setScrollBarVisibility(FigureCanvas.ALWAYS);
- GraphicalViewer的最底层控件是FigureCanvas
- 给FigureCanvas设置背景色,并一直显示滚动条
三. 修改模型、添加EditPart、增加Figure
略
四. Layout
在这步引入了Layout的概念,和SWT中的Layout作用是一样的。
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)坐标
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方法。代码如下:
/**
* @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