实现GEF RulerComposite

模型部分:
public class ElementBase extends AbstractModel implements IAdaptable {

/**
*
*/
private static final long serialVersionUID = 1L;

/**
* 布局
*/
private Rectangle layout;

/**
* 获得布局
*
* @return
*/
public Rectangle getLayout() {
return layout;
}

public void setLayout(Rectangle layout) {
this.layout = layout;
}

/**
* 垂直向导、水平向导
*/
private Guide verticalGuide, horizontalGuide;

public Guide getVerticalGuide() {

return verticalGuide;

}

/**
* 设置导航参数
*
* @param verticalGuide
*/
public void setVerticalGuide(Guide verticalGuide) {

this.verticalGuide = verticalGuide;

}

public Guide getHorizontalGuide() {

return horizontalGuide;

}

public void setHorizontalGuide(Guide horizontalGuide) {

this.horizontalGuide = horizontalGuide;

}

public Object getAdapter(Class adapter) {
return null;
}


/**
* 向导
*
* @author Ming.He
*
*/
public class Guide implements Serializable {

/**
*
*/
private static final long serialVersionUID = 1L;

/**
* 对于一个向导, 当附件部分被改变时,这个属性通常用来通知监听者
*/
public static final String PROPERTY_CHILDREN = "subparts changed";

/**
*
* Property used to notify listeners when the guide is re-positioned
*/

public static final String PROPERTY_POSITION = "position changed";

protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);

private Map map;

/**
* 定位
*/
private int position;

/**
* 是否水平
*/
private boolean horizontal;

/**
*
* Empty default constructor
*/

public Guide() {

// empty constructor

}

/**
*
* Constructor
*
*
*
* @param isHorizontal
*
* <code>true</code> if the guide is horizontal (i.e., placed on
*
* a vertical ruler)
*/

public Guide(boolean isHorizontal) {

setHorizontal(isHorizontal);

}

/**
*
* @see PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)
*/

public void addPropertyChangeListener(PropertyChangeListener listener) {

listeners.addPropertyChangeListener(listener);

}

/*
*
* @TODO:Pratik use PositionConstants here
*/

/**
*
* Attaches the given part along the given edge to this guide. The
*
* LogicSubpart is also updated to reflect this attachment.
*
*
*
* @param part
*
* The part that is to be attached to this guide; if the part is
*
* already attached, its alignment is updated
*
* @param alignment
*
* -1 is left or top; 0, center; 1, right or bottom
*/

public void attachElement(ElementBase element, int alignment) {

if (getMap().containsKey(element) && getAlignment(element) == alignment)

return;

getMap().put(element, alignment);

Guide parent = isHorizontal() ? element.getHorizontalGuide() : element

.getVerticalGuide();

if (parent != null && parent != this) {

parent.detachElement(element);

}

if (isHorizontal()) {

element.setHorizontalGuide(this);

} else {

element.setVerticalGuide(this);

}

listeners.firePropertyChange(PROPERTY_CHILDREN, null, element);

}

/**
*
* Detaches the given part from this guide. The LogicSubpart is also updated
*
* to reflect this change.
*
*
*
* @param part
*
* the part that is to be detached from this guide
*/

public void detachElement(ElementBase element) {

if (getMap().containsKey(element)) {

getMap().remove(element);

if (isHorizontal()) {

element.setHorizontalGuide(null);

} else {

element.setVerticalGuide(null);

}

listeners.firePropertyChange(PROPERTY_CHILDREN, null, element);

}

}

/**
*
* This methods returns the edge along which the given part is attached to
*
* this guide. This information is used by
*
* {@link org.eclipse.gef.examples.logicdesigner.edit.LogicXYLayoutEditPolicy
*
* LogicXYLayoutEditPolicy} to determine whether to attach or detach a part
*
* from a guide during resize operations.
*
*
*
* @param part
*
* The part whose alignment has to be found
*
* @return an int representing the edge along which the given part is
*
* attached to this guide; 1 is bottom or right; 0, center; -1, top
*
* or left; -2 if the part is not attached to this guide
*
* @see org.eclipse.gef.examples.logicdesigner.edit.LogicXYLayoutEditPolicy#createChangeConstraintCommand(ChangeBoundsRequest,
* EditPart, Object)
*/

public int getAlignment(ElementBase element) {

if (getMap().get(element) != null)

return ((Integer) getMap().get(element)).intValue();

return -2;

}

/**
*
* @return The Map containing all the parts attached to this guide, and
*
* their alignments; the keys are LogicSubparts and values are
*
* Integers
*/

public Map getMap() {

if (map == null) {

map = new Hashtable();

}

return map;

}

/**
*
* @return the set of all the parts attached to this guide; a set is used
*
* because a part can only be attached to a guide along one edge.
*/

public Set getParts() {

return getMap().keySet();

}

/**
*
* @return the position/location of the guide (in pixels)
*/

public int getPosition() {

return position;

}

/**
*
* @return <code>true</code> if the guide is horizontal (i.e., placed on a
*
* vertical ruler)
*/

public boolean isHorizontal() {

return horizontal;

}

/**
*
* @see PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)
*/

public void removePropertyChangeListener(PropertyChangeListener listener) {

listeners.removePropertyChangeListener(listener);

}

/**
*
* Sets the orientation of the guide
*
*
*
* @param isHorizontal
*
* <code>true</code> if this guide is to be placed on a vertical
*
* ruler
*/

public void setHorizontal(boolean isHorizontal) {

horizontal = isHorizontal;

}

/**
*
* Sets the location of the guide
*
*
*
* @param offset
*
* The location of the guide (in pixels)
*/

public void setPosition(int offset) {

if (position != offset) {

int oldValue = position;

position = offset;

listeners.firePropertyChange(PROPERTY_POSITION, new Integer(

oldValue), new Integer(position));

}

}

}


/**
* 标尺
*
* @author Ming.He
*
*/
public class Ruler implements Serializable {

public static final String PROPERTY_CHILDREN = "children changed";

public static final String PROPERTY_UNIT = "units changed";

static final long serialVersionUID = 1;

protected PropertyChangeSupport listeners = new PropertyChangeSupport(this);

private int unit;

private boolean horizontal;

private List<Guide> guides = new ArrayList<Guide>();

public Ruler(boolean isHorizontal) {

this(isHorizontal, RulerProvider.UNIT_PIXELS);

}

public Ruler(boolean isHorizontal, int unit) {

horizontal = isHorizontal;

setUnit(unit);

}

public void addGuide(Guide guide) {

if (!guides.contains(guide)) {

guide.setHorizontal(!isHorizontal());

guides.add(guide);

listeners.firePropertyChange(PROPERTY_CHILDREN, null, guide);

}

}

public void addPropertyChangeListener(PropertyChangeListener listener) {

listeners.addPropertyChangeListener(listener);

}

// the returned list should not be modified

public List<Guide> getGuides() {

return guides;

}

public int getUnit() {

return unit;

}

public boolean isHidden() {

return false;

}

public boolean isHorizontal() {

return horizontal;

}

public void removeGuide(Guide guide) {

if (guides.remove(guide)) {

listeners.firePropertyChange(PROPERTY_CHILDREN, null, guide);

}

}

public void removePropertyChangeListener(PropertyChangeListener listener) {

listeners.removePropertyChangeListener(listener);

}

public void setHidden(boolean isHidden) {

}

public void setUnit(int newUnit) {

if (unit != newUnit) {

int oldUnit = unit;

unit = newUnit;

listeners.firePropertyChange(PROPERTY_UNIT, oldUnit, newUnit);

}

}

}


标尺提供者:
/**
* 编辑器标尺提供者
*
* @author Ming.He
*
*/
public class EditorRulerProvider extends RulerProvider {

/** 标尺 */
private Ruler ruler;

/** 标尺监听 */
private PropertyChangeListener rulerListener = new PropertyChangeListener() {

public void propertyChange(PropertyChangeEvent evt) {

if (evt.getPropertyName().equals(Ruler.PROPERTY_CHILDREN)) {

Guide guide = (Guide) evt.getNewValue();

if (getGuides().contains(guide)) {

guide.addPropertyChangeListener(guideListener);

} else {

guide.removePropertyChangeListener(guideListener);

}

for (int i = 0; i < listeners.size(); i++) {

((RulerChangeListener) listeners.get(i))

.notifyGuideReparented(guide);

}

} else {

for (int i = 0; i < listeners.size(); i++) {

((RulerChangeListener) listeners.get(i))

.notifyUnitsChanged(ruler.getUnit());

}

}

}

};

private PropertyChangeListener guideListener = new PropertyChangeListener() {

public void propertyChange(PropertyChangeEvent evt) {

if (evt.getPropertyName().equals(Guide.PROPERTY_CHILDREN)) {

for (int i = 0; i < listeners.size(); i++) {

((RulerChangeListener) listeners.get(i))

.notifyPartAttachmentChanged(evt.getNewValue(), evt

.getSource());

}

} else {

for (int i = 0; i < listeners.size(); i++) {

((RulerChangeListener) listeners.get(i))

.notifyGuideMoved(evt.getSource());

}

}

}

};

public EditorRulerProvider(Ruler ruler) {

this.ruler = ruler;

this.ruler.addPropertyChangeListener(rulerListener);

List guides = getGuides();

for (int i = 0; i < guides.size(); i++) {

((Guide) guides.get(i))

.addPropertyChangeListener(guideListener);

}

}

public List getAttachedModelObjects(Object guide) {

return new ArrayList(((Guide) guide).getParts());

}

public Command getCreateGuideCommand(int position) {

return new CreateGuideCommand(ruler, position);

}

public Command getDeleteGuideCommand(Object guide) {

return new DeleteGuideCommand((Guide) guide, ruler);

}

public Command getMoveGuideCommand(Object guide, int pDelta) {

return new MoveGuideCommand((Guide) guide, pDelta);
}

public int[] getGuidePositions() {

List guides = getGuides();

int[] result = new int[guides.size()];

for (int i = 0; i < guides.size(); i++) {

result[i] = ((Guide) guides.get(i)).getPosition();

}

return result;

}

public Object getRuler() {

return ruler;

}

public int getUnit() {

return ruler.getUnit();

}

public void setUnit(int newUnit) {

ruler.setUnit(newUnit);

}

public int getGuidePosition(Object guide) {

return ((Guide) guide).getPosition();

}

public List getGuides() {

return ruler.getGuides();

}
}


向导操作命令:
/**
* 创建向导命令
*
* @author Ming.He
*
*/
public class CreateGuideCommand extends Command {

/** 向导 */
private Guide guide;

/** 标尺 */
private Ruler parent;

/** 位置 */
private int position;

public CreateGuideCommand(Ruler parent, int position) {

super("Create guide");

this.parent = parent;

this.position = position;

}

public boolean canUndo() {

return true;

}

public void execute() {

if (guide == null)

guide = new Guide(!parent.isHorizontal());

guide.setPosition(position);

parent.addGuide(guide);

}

public void undo() {

parent.removeGuide(guide);

}

}


/**
* 删除向导命令
* @author Ming.He
*
*/
public class DeleteGuideCommand extends Command {

/**
* 标尺
*/
private Ruler parent;
/**
* 向导
*/
private Guide guide;
/**
* 已创建的控制器
*/
private Map oldParts;

public DeleteGuideCommand(Guide guide, Ruler parent) {
super("Delete guide");
this.guide = guide;
this.parent = parent;
}

public boolean canUndo() {
return true;
}

public void execute() {
oldParts = new HashMap(guide.getMap());
Iterator iter = oldParts.keySet().iterator();
while (iter.hasNext()) {
guide.detachElement((ElementBase) iter.next());
}
parent.removeGuide(guide);
}

public void undo() {
parent.addGuide(guide);
Iterator iter = oldParts.keySet().iterator();
while (iter.hasNext()) {
ElementBase element = (ElementBase) iter.next();
guide.attachElement(element, ((Integer) oldParts.get(element)).intValue());
}
}
}


/**
* 移动向导命令
* @author Ming.He
*
*/
public class MoveGuideCommand extends Command {

/**三角定位*/
private int pDelta;
/**向导*/
private Guide guide;

public MoveGuideCommand(Guide guide, int positionDelta) {
super("Move guide");
this.guide = guide;
pDelta = positionDelta;
}

public void execute() {
guide.setPosition(guide.getPosition() + pDelta);
Iterator iter = guide.getParts().iterator();
while (iter.hasNext()) {
ElementBase element = (ElementBase) iter.next();
Rectangle layout = element.getLayout().getCopy();
if (guide.isHorizontal()) {
layout.y += pDelta;
} else {
layout.x += pDelta;
}
element.setLayout(layout);
}
}

public void undo() {
guide.setPosition(guide.getPosition() - pDelta);
Iterator iter = guide.getParts().iterator();
while (iter.hasNext()) {
ElementBase element = (ElementBase) iter.next();
Rectangle layout = element.getLayout().getCopy();
if (guide.isHorizontal()) {
layout.y -= pDelta;
} else {
layout.x -= pDelta;
}
element.setLayout(layout);
}
}

}


最后在编辑器中配置RulerComposite(因为GEF是支持RulerComposite的,所以配置就可以了)
/** 标尺容器 */
private RulerComposite rulerComp;// Override
protected void createGraphicalViewer(Composite parent) {
rulerComp = new RulerComposite(parent, SWT.NONE);

super.createGraphicalViewer(rulerComp);

rulerComp.setGraphicalViewer((ScrollingGraphicalViewer) getGraphicalViewer());

}


/**
* 配置标尺
*/
private void configureRuler() {

GraphicalViewer viewer = getGraphicalViewer();

viewer.setProperty(RulerProvider.PROPERTY_VERTICAL_RULER,

new EditorRulerProvider(new Ruler(false)));

viewer.setProperty(RulerProvider.PROPERTY_HORIZONTAL_RULER,

new EditorRulerProvider(new Ruler(true)));

viewer.setProperty(RulerProvider.PROPERTY_RULER_VISIBILITY, true);

IAction action = new ToggleRulerVisibilityAction(getGraphicalViewer());

getActionRegistry().registerAction(action);

}


最后在configureGraphicalViewer方法中调用configureRuler即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值