您的位置:首页 > 编程语言 > Java开发

[置顶] Eclipse GEF UMLClass(1)

2016-05-09 20:45 706 查看
通过两篇文章对GEF进行了介绍,为了自己加深对GEF的理解和学习,从网上找了一下开源的amaterasuml的uml工具,并把其中对内容转换提取成。

Figure:

第一篇文章其实是对amaterasuml中ClassFigure的简化,真实的UML类图如下:



EntityFigure:实体Figure,用于获取Label和获取矩形编辑域,代码如下:

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Rectangle;

public interface EntityFigure extends IFigure{

Label getLabel();

Rectangle getCellEditorRectangle();

}


PresentaionFigure:描述Figure,用于更新模型的描述

public interface PresentationFigure {

void updatePresentation(AbstractUMLModel model);
}


CompartmentFigure:用于分隔的Figure,用于分隔属性和方法

import org.eclipse.draw2d.AbstractBorder;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Insets;

public class CompartmentFigure extends Figure {

public CompartmentFigure() {
ToolbarLayout layout = new ToolbarLayout();
layout.setMinorAlignment(ToolbarLayout.ALIGN_TOPLEFT);
layout.setStretchMinorAxis(false);
layout.setSpacing(2);
setLayoutManager(layout);
setBorder(new CompartmentFigureBorder());
}

public class CompartmentFigureBorder extends AbstractBorder {

public Insets getInsets(IFigure figure) {
return new Insets(1, 0, 2, 0);
}

public void paint(IFigure figure, Graphics graphics, Insets insets) {
graphics.drawLine(getPaintRectangle(figure, insets).getTopLeft(),
tempRect.getTopRight());
}
}
}


UMLClassFigure:最终展示的Figure,主要的ClassFigure,包含所有相关方法

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LineBorder;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;

public class UMLClassFigure extends Figure implements EntityFigure, PresentationFigure {

public static Color classColor = new Color(null, 255, 255, 206);

private Label name;

private Label stereoType;

private Image icon;

private CompartmentFigure attributeFigure = new CompartmentFigure();
private CompartmentFigure methodFigure = new CompartmentFigure();
private Figure nameFigure;

public UMLClassFigure(Image icon, Figure nameFigure) {
this.nameFigure = nameFigure;
this.name = new Label();
this.name.setForegroundColor(ColorConstants.darkGray);
this.name.setBorder(new MarginBorder(5));
this.name.setIcon(icon);
this.icon = icon;
this.stereoType = new Label();
this.stereoType.setTextAlignment(PositionConstants.CENTER);
ToolbarLayout layout = new ToolbarLayout();
setLayoutManager(layout);
setBorder(new LineBorder(1));
setBackgroundColor(classColor);
setOpaque(true);

nameFigure.setLayoutManager(new ToolbarLayout());
//
//      nameFigure.add(this.stereoType);
nameFigure.add(this.name);
add(nameFigure);
add(attributeFigure);
add(methodFigure);
}

public void setFont(Font font){
this.name.setFont(font);
}

public void setClassName(String className){
this.name.setText(className);
}

public void add(IFigure figure, Object constraint, int index) {
if(figure instanceof AttributeLabel){
attributeFigure.add(figure);
} else if(figure instanceof OperationLabel){
methodFigure.add(figure);
} else {
super.add(figure,constraint,index);
}
}

public void moveAttribute(int index, boolean up){
@SuppressWarnings("rawtypes")
List children = attributeFigure.getChildren();
IFigure obj = (IFigure)children.get(index);
attributeFigure.remove(obj);
if(up){
attributeFigure.add(obj, index - 1);
} else {
attributeFigure.add(obj, index + 1);
}
}

public void moveOperation(int index, boolean up){
@SuppressWarnings("rawtypes")
List children = methodFigure.getChildren();
IFigure obj = (IFigure)children.get(index);
methodFigure.remove(obj);
if(up){
methodFigure.add(obj, index - 1);
} else {
methodFigure.add(obj, index + 1);
}
}

public void remove(IFigure figure) {
if(figure instanceof  AttributeLabel){
attributeFigure.remove(figure);
} else if(figure instanceof OperationLabel){
methodFigure.remove(figure);
} else {
super.remove(figure);
}
}

public Label getLabel(){
return name;
}

public Rectangle getCellEditorRectangle() {
Rectangle rect = name.getBounds().getCopy();
if (name.getIcon() != null) {
return new Rectangle(rect.x + 16, rect.y, rect.width - 16, rect.height);
}
return new Rectangle(rect.x, rect.y, rect.width, rect.height);
}

public void updatePresentation(AbstractUMLModel model) {
if (model.isShowIcon()) {
name.setIcon(icon);
} else {
name.setIcon(null);
}
}

public void setStereoType(String stereoType) {
if (stereoType == null || "".equals(stereoType)) {
if (nameFigure.getChildren().contains(this.stereoType)) {
nameFigure.remove(this.stereoType);
}
} else {
this.stereoType.setText("<<" + stereoType + ">>");
if (!nameFigure.getChildren().contains(this.stereoType)) {
nameFigure.add(this.stereoType, 0);
}
}
}
}


Modal :

在GEF框架中,Modal是非常简单的一部分,用户可以把Modal理解成一个简单的可持久化的实体。但为了能让控制器知道模型的变化,应该控制器作为事件监听者注册到Modal中,当模型发生变化时,就触发相应的事件给控制器,后者负责通知各个视图进行更新。

典型的模型对象包含PropertyChangeSupport类型的成员变量,用来添加监听器和通知监听器(控制器),一般来说,模型会实现一个基类,用来封装事件机制,主要包括添加监听器,删除监听器,以及模型属性改变触发的相应事件。另外,当用户希望通过属性视图编辑模型属性时,模型要实现IPropertySource接口,该接口的方法解释如下:

//得到在属性页中能编辑的值,可以返回this表示当前模型

public Object getEditableValue();

//得到IPropertyDescriptor的数组,其中每一项是属性页中能编辑的项

public IPropertyDescriptor[] getPropertyDescriptors();

//通过id得到某个属性值,在添加每一项IPropertyDescriptor都会指定id

public Object getPropertyValue(Object id);

//表示特定属性id值是否改变

public boolean isPropertySet(Object id);

public void resetPropertyValue(Object id);//通过id重置属性

public void setPropertyValue(Object id, Object value);//通过id和值设置某一项属性的值

类图如下:



我们定义一个AbstractUMLModel 封装事件机制和属性编辑

public abstract class AbstractUMLModel implements Serializable, IPropertySource {

//定义属性的常量ID
public static final String P_BACKGROUND_COLOR = "_background";

public static final String P_FOREGROUND_COLOR = "_foreground";

public static final String P_SHOW_ICON = "_showicon";

private RGB backgroundColor;

private RGB foregroundColor;

private boolean showIcon = true;

private AbstractUMLEntityModel parent;

private PropertyChangeSupport listeners = new PropertyChangeSupport(this);

public void addPropertyChangeListener(PropertyChangeListener listener) {
listeners.addPropertyChangeListener(listener);
}

public void firePropertyChange(String propName, Object oldValue,Object newValue) {
listeners.firePropertyChange(propName, oldValue, newValue);
}

public void removePropertyChangeListener(PropertyChangeListener listener) {
listeners.removePropertyChangeListener(listener);
}

public Object getEditableValue() {
return this;
}

public void setParent(AbstractUMLEntityModel parent) {
this.parent = parent;
}

public AbstractUMLEntityModel getParent() {
return parent;
}

public IPropertyDescriptor[] getPropertyDescriptors() {
//定义属性的编辑项
return new IPropertyDescriptor[] {
new ColorPropertyDescriptor(P_BACKGROUND_COLOR, "Background Color"),
new ColorPropertyDescriptor(P_FOREGROUND_COLOR, "Foreground Color"),
//自定义的PropertyDescriptor
new BooleanPropertyDescriptor(P_SHOW_ICON, "Show Icon") };

}

public Object getPropertyValue(Object id) {
if (id.equals(P_BACKGROUND_COLOR)) {
return backgroundColor;
} else if (P_FOREGROUND_COLOR.equals(id)) {
return foregroundColor;
} else if (P_SHOW_ICON.equals(id)) {
return new Boolean(isShowIcon());
}
return null;
}

public boolean isPropertySet(Object id) {
return P_BACKGROUND_COLOR.equals(id) || P_FOREGROUND_COLOR.equals(id)
|| P_SHOW_ICON.equals(id);
}

//设置属性的值
public void setPropertyValue(Object id, Object value) {
if (P_BACKGROUND_COLOR.equals(id)) {
setBackgroundColor((RGB) value);
} else if (P_FOREGROUND_COLOR.equals(id)) {
setForegroundColor((RGB) value);
} else if (P_SHOW_ICON.equals(id)) {
setShowIcon(((Boolean) value).booleanValue());
}
}

public void resetPropertyValue(Object id) {
}

public Color getBackgroundColor() {
//调用自定义生成颜色对象
return UMLColorRegistry.getColor(backgroundColor);
}

public void setBackgroundColor(RGB backgroundColor) {
this.backgroundColor = backgroundColor;
//当backgroundColor改变后,触发属性改变的事件
firePropertyChange(P_BACKGROUND_COLOR, null, backgroundColor);
}

public Color getForegroundColor() {
return UMLColorRegistry.getColor(foregroundColor);
}

public void setForegroundColor(RGB foregroundColor) {
this.foregroundColor = foregroundColor;
//当foregroundColor改变后,触发属性改变的事件
firePropertyChange(P_FOREGROUND_COLOR, null, foregroundColor);
}

public boolean isShowIcon() {
return showIcon;
}

public void setShowIcon(boolean showIcon) {
this.showIcon = showIcon;
//当SHOW_ICON改变后,触发属性改变的事件
firePropertyChange(P_SHOW_ICON, null, new Boolean(showIcon));
}

public void copyPresentation(AbstractUMLModel model) {
if (backgroundColor != null) {
model.setBackgroundColor(backgroundColor);
}
if (foregroundColor != null) {
model.setForegroundColor(foregroundColor);
}
model.setShowIcon(showIcon);
}
}


AbstractUMLEntityModel代码如下:

public abstract class AbstractUMLEntityModel extends AbstractUMLModel {

private Rectangle constraint;
//定义模型连线的列表
private List<AbstractUMLConnectionModel> sourceConnections = new ArrayList<AbstractUMLConnectionModel>();
private List<AbstractUMLConnectionModel> targetConnections = new ArrayList<AbstractUMLConnectionModel>();

private List<AbstractUMLModel> children = new ArrayList<AbstractUMLModel>();
private Map<String, Boolean> filterProperty = new HashMap<String, Boolean>();

//定义属性的常量ID
public static final String P_CONSTRAINT = "_constraint";
public static final String P_SOURCE_CONNECTION = "_source_connection";
public static final String P_TARGET_CONNECTION = "_target_connection";
public static final String P_CHILDREN = "_children";
public static final String P_FILTER = "_filter";
public static final String P_FORCE_UPDATE = "_force_update";

public Map<String, Boolean> getFilterProperty() {
return filterProperty;
}

public void setFilterProperty(Map<String, Boolean> filterProperty) {
this.filterProperty = filterProperty;
firePropertyChange(P_FILTER, null, filterProperty);
}

public Rectangle getConstraint() {
return constraint;
}

public void addChild(AbstractUMLModel model) {
children.add(model);
model.setParent(this);
//当增加子模型时,触发属性改变的事件
firePropertyChange(P_CHILDREN,null,model);
}

public void removeChild(AbstractUMLModel model) {
children.remove(model);
model.setParent(this);
//当删除子模型时,触发属性改变的事件
firePropertyChange(P_CHILDREN,null,model);
}

public void forceUpdate() {
firePropertyChange(P_FORCE_UPDATE, null ,null);
}

public List<AbstractUMLModel> getChildren(){
return this.children;
}

public void setConstraint(Rectangle constraint) {
if(constraint.x < 0){
constraint.x = 0;
}
if(constraint.y < 0){
constraint.y = 0;
}
this.constraint = constraint;
firePropertyChange(P_CONSTRAINT, null, constraint);
}

public void addSourceConnection(AbstractUMLConnectionModel connx) {
sourceConnections.add(connx);
//当输入的连线改变后,触发属性改变的事件
firePropertyChange(P_SOURCE_CONNECTION, null, connx);
}

public void addTargetConnection(AbstractUMLConnectionModel connx) {
targetConnections.add(connx);
//当输入的连线改变后,触发属性改变的事件
firePropertyChange(P_TARGET_CONNECTION, null, connx);
}

public List<AbstractUMLConnectionModel> getModelSourceConnections() {
return sourceConnections;
}

public List<AbstractUMLConnectionModel> getModelTargetConnections() {
return targetConnections;
}

public void removeSourceConnection(AbstractUMLConnectionModel connx) {
sourceConnections.remove(connx);
//当输入的连线改变后,触发属性改变的事件
firePropertyChange(P_SOURCE_CONNECTION, connx, null);
}

public void removeTargetConnection(AbstractUMLConnectionModel connx) {
targetConnections.remove(connx);
//当输入的连线改变后,触发属性改变的事件
firePropertyChange(P_TARGET_CONNECTION, connx, null);
}

public void setBackgroundColor(RGB backgroundColor) {
for (Iterator<AbstractUMLModel> iter = children.iterator(); iter.hasNext();) {
AbstractUMLModel element = (AbstractUMLModel) iter.next();
element.setBackgroundColor(backgroundColor);
}
super.setBackgroundColor(backgroundColor);
}

public void setForegroundColor(RGB foregroundColor) {
for (Iterator<AbstractUMLModel> iter = children.iterator(); iter.hasNext();) {
AbstractUMLModel element = (AbstractUMLModel) iter.next();
element.setForegroundColor(foregroundColor);
}
super.setForegroundColor(foregroundColor);
}

public void setShowIcon(boolean showIcon) {
for (Iterator<AbstractUMLModel> iter = children.iterator(); iter.hasNext();) {
AbstractUMLModel element = (AbstractUMLModel) iter.next();
element.setShowIcon(showIcon);
}
super.setShowIcon(showIcon);
}
}


AbstractUMLConnectionModel,分析方法跟上面的都类似:

public abstract class AbstractUMLConnectionModel extends AbstractUMLModel {

private AbstractUMLEntityModel source;

private AbstractUMLEntityModel target;

private List<ConnectionBendpoint> bendpoints = new ArrayList<ConnectionBendpoint>();

public static final String P_BEND_POINT = "_bend_point";

public void addBendpoint(int index, ConnectionBendpoint point) {
bendpoints.add(index, point);
firePropertyChange(P_BEND_POINT, null, null);
}

public List<ConnectionBendpoint> getBendpoints() {
if (bendpoints == null) {
bendpoints = new ArrayList<ConnectionBendpoint>();
}
return bendpoints;
}

public void removeBendpoint(int index) {
bendpoints.remove(index);
firePropertyChange(P_BEND_POINT, null, null);
}

public void removeBendpoint(ConnectionBendpoint point) {
bendpoints.remove(point);
firePropertyChange(P_BEND_POINT, null, null);
}

public void replaceBendpoint(int index, ConnectionBendpoint point) {
bendpoints.set(index, point);
firePropertyChange(P_BEND_POINT, null, null);
}

public void attachSource() {

if (!source.getModelSourceConnections().contains(this)) {
source.addSourceConnection(this);
}
}

public void attachTarget() {
if (!target.getModelTargetConnections().contains(this)) {
target.addTargetConnection(this);
}
}

public void detachSource() {
if (source != null) {
source.removeSourceConnection(this);
}
}

public void detachTarget() {
if (target != null) {
target.removeTargetConnection(this);
}
}

public AbstractUMLEntityModel getSource() {
return source;
}

public AbstractUMLEntityModel getTarget() {
return target;
}

public void setSource(AbstractUMLEntityModel model) {
source = model;
}

public void setTarget(AbstractUMLEntityModel model) {
target = model;
}

public IPropertyDescriptor[] getPropertyDescriptors() {
return new IPropertyDescriptor[] {
new ColorPropertyDescriptor(P_FOREGROUND_COLOR, "Foreground Color")
};
}

}


ConnectionBendpoint类如下:

public class ConnectionBendpoint implements Serializable, Bendpoint {

private float weight = 0.5f;

private Dimension d1 = null;

private Dimension d2 = null;

public ConnectionBendpoint() {
// ignore
}

public ConnectionBendpoint(Dimension dim1, Dimension dim2) {
d1 = dim1;
d2 = dim2;
}

public Dimension getFirstRelativeDimension() {
return d1;
}

public Point getLocation() {
return null;
}

public Dimension getSecondRelativeDimension() {
return d2;
}

public float getWeight() {
return weight;
}

public void setRelativeDimensions(Dimension dim1, Dimension dim2) {
d1 = dim1;
d2 = dim2;
}

public void setWeight(float w) {
weight = w;
}
}


UMLColorRegistry类如下:

public class UMLColorRegistry {

private ColorRegistry registry;

private static UMLColorRegistry instance;

private UMLColorRegistry() {
registry = new ColorRegistry();
}
//单例
public static final Color getColor(RGB rgb) {
if (instance == null) {
instance = new UMLColorRegistry();
}
if (rgb == null) {
return null;
}
return instance.createColor(rgb);
}

//获取颜色对象
private Color createColor(RGB rgb) {
registry.put(rgb.toString(), rgb);
return registry.get(rgb.toString());
}

}


BooleanPropertyDescriptor类如下:

public class BooleanPropertyDescriptor extends PropertyDescriptor {

public BooleanPropertyDescriptor(Object id,String displayName){
super(id,displayName);
}

public CellEditor createPropertyEditor(Composite parent) {
CellEditor editor = new ComboBoxCellEditor(
parent, new String[]{"true","false"},SWT.READ_ONLY){
public void doSetValue(Object value){
if(((Boolean)value).booleanValue()){
super.doSetValue(new Integer(0));
} else {
super.doSetValue(new Integer(1));
}
}
public Object doGetValue(){
int selection = ((Integer)super.doGetValue()).intValue();
if(selection==0){
return new Boolean(true);
} else {
return new Boolean(false);
}
}
};

if (getValidator() != null)
editor.setValidator(getValidator());

return editor;
}
}


现在对于UML的抽象类已经大致看到了外貌,主要是把Figure与Model做了较详细的介绍,以及详细的代码,但是还是停留在抽象层面,下一篇文章主要针对UMLClass类图的具体类进行分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: