`

实现GEF RulerComposite

    博客分类:
  • GEF
阅读更多
模型部分:
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即可
  • 大小: 31.8 KB
2
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics