RCP学习:GEF编辑器的鼠标的hover policy以及一个预览窗口效果

GEF编辑器遵循MVC模式。在这里Controller既是org.eclipse.gef.EditPart。它的行为是可以被一系列的策略(org.eclipse.gef.EditPolicy)确定的,见AbstractEditPolicy的方法:

    /**
     * Creates the initial EditPolicies and/or reserves slots for dynamic ones.
     * Should be implemented to install the inital EditPolicies based on the
     * model's initial state. <code>null</code> can be used to reserve a "slot",
     * should there be some desire to guarantee the ordering of EditPolcies.
     * 
     * @see EditPart#installEditPolicy(Object, EditPolicy)
     */
    protected abstract void createEditPolicies();

 

我们自己定义的Policy可以在这个位置添加。

下面来定义一个鼠标移动到节点上即可以做某些事情的Policy,该Policy要实现如下功能:

1、鼠标移动到节点上的时候,绘制handle

2、鼠标点击任何位置,handle消失

3、鼠标移动到其他节点,绘制新的handle,之前的handle消失。

先看下效果图:

1、这是一个普通的GEF节点,红色和绿色手型标示着连线的端点

2、当鼠标移动到节点上,并且停留数秒的时候,绘制一个橙色手型覆盖红色手型:

3、当鼠标点击该橙色手型,则出现可拖拽的连线提示(该部分功能由handle实现,暂不讨论):

 

先来看看Policy的实现:

/**
 * 
 * @author caiyu
 * 
 */
public abstract class CommonHoverEditPolicy extends GraphicalEditPolicy {
    public static final String ROLE = "CommonLineAssistantEditPolicy";

    protected IFigure handleLayer;
    /* the List of handles */
    protected List<Handle> handles;

    /* the Hover Listener */
    private MouseMotionListener hoverListener;

    /* listener for every handle */
    private MouseMotionListener handleListener;

    private LayoutListener removeListener;

    private Timer timer;

    private boolean hovering = false;

    protected int TIME_INTERVAL = 1000;

  
public void activate() { super.activate(); addHoverListener(); addHandleListener(); } private void addHandleListener() { handleListener = new MouseMotionListener() { public void mouseDragged(MouseEvent me) { } public void mouseEntered(MouseEvent me) { } public void mouseExited(MouseEvent me) { cancelTimer(); startTimer(); } public void mouseHover(MouseEvent me) { } public void mouseMoved(MouseEvent me) { } }; } protected void addHoverListener() { final IFigure figure = getHostFigure(); hoverListener = new MouseMotionListener() { public void mouseDragged(MouseEvent me) { } public void mouseEntered(MouseEvent me) { } public void mouseExited(MouseEvent me) { startTimer(); } public void mouseHover(MouseEvent me) { cancelTimer(); addHoverHandles(); hovering = true; } public void mouseMoved(MouseEvent me) { } }; /** * 被删除的时候清除监听 */ removeListener = new LayoutListener() { @Override public void invalidate(IFigure container) { } @Override public boolean layout(IFigure container) { return false; } @Override public void postLayout(IFigure container) { } @Override public void remove(IFigure child) { if (child == figure) { clearHoverHandles(); cancelTimer(); figure.getParent().removeLayoutListener(removeListener); } } @Override public void setConstraint(IFigure child, Object constraint) { } }; if (figure != null) { figure.addMouseMotionListener(hoverListener); if (figure.getParent() != null) figure.getParent().addLayoutListener(removeListener); } } /** * Adds the handles to the handle layer. */ protected void addHoverHandles() { clearHoverHandles(); handleLayer = getLayer(LayerConstants.HANDLE_LAYER); handles = createHoverHandles(); for (int i = 0; i < handles.size(); i++) { IFigure handle = (IFigure) handles.get(i); handleLayer.add(handle); handle.addMouseMotionListener(handleListener); } } protected void clearHoverHandles() { if (handles == null) return; if (handleLayer == null) handleLayer = getLayer(LayerConstants.HANDLE_LAYER); for (int i = 0; i < handles.size(); i++) { IFigure handle = (IFigure) handles.get(i); try { handleLayer.remove(handle); } catch (Exception e) { e.printStackTrace(); } if (handleListener != null) handle.removeMouseMotionListener(handleListener); } handles = null; } protected void cancelTimer() { if (timer != null) { timer.cancel(); } } protected void startTimer() { if (!hovering) return; if (timer != null) { timer.cancel(); } timer = new Timer(true); timer.schedule(new TimerTask() { public void run() { Display.getDefault().syncExec(new Runnable() { public void run() { clearHoverHandles(); } }); } }, TIME_INTERVAL); } protected abstract List<Handle> createHoverHandles(); }

 

代码有点多,不熟悉Policy的话,可以先从activate()方法读起。这个Policy的作用是为hostFigure(就是MVC中的Viewer部分,也是该policy的宿主)添加监听,通过一个Timer来控制handle的展示和消失。

该类为abstract类型,其实现子类需要提供createHoverHandles()的实现,该方法返回一个List<Handle>。

如此,就可以把handle的效果和这个Policy结合起来了。

 

 

下面再提供一个利用CommonHoverEditPolicy实现预览效果的例子。

先看效果图:

1、这是一个普通的GEF编辑器:

 

 

2、其中的每一个节点内容是被另一个表格编辑器所确定的:

 

3、当鼠标移动到节点上,稍作停留,便会弹出一个预览框:

 

该预览框具备之前的表格编辑器的所有浏览功能,可以点击,可以切换子页。

实现方式:

1、重写CommonHoverEditPolicy的createHoverHandles()方法。

TablePreviewDialog dialog = null;

    @Override
    protected List<Handle> createHoverHandles() {
        if (dialog != null && !dialog.close()) {
            dialog.close();
        }
        try {
            BtdFormEditor editor = new BtdFormEditor(false);
            ModelEditorInput input = new ModelEditorInput(
                    (IBaseModel) getHost().getModel());
            IWorkbenchWindow dw = PlatformUI.getWorkbench()
                    .getActiveWorkbenchWindow();
            editor.init(new MultiPageEditorSite((MultiPageEditorPart) dw
                    .getActivePage().getActiveEditor(), editor), input);
            dialog = TablePreviewDialog.getTablePreviewDialog(editor);
            dialog.open();
        } catch (PartInitException e) {
            e.printStackTrace();
        }
        return new ArrayList<Handle>();
    }

可以看到,这里并没有提供可用的Handle(List<Handle>的内容是空的)。但是我们提供了一个Dialog,该Dialog为单例模式,通过对它的close和open控制,来实现handle一样的效果。使用dialog而非handle的主要原因是,handle是基于draw2d的,内容需要绘制,但是我们需要的内容是一个SWT\Jface构成的表格编辑器。所以使用dialog比较合适。

 

TablePreviewDialog定义如下:
/**
 * 表格内容预览
 * 
 * @author caiyu
 * @date 2012-8-17
 */
public class TablePreviewDialog extends Dialog {
    private static TablePreviewDialog INSTANCE = null;

    public static TablePreviewDialog getTablePreviewDialog(FormEditor editor) {
        if (INSTANCE != null) {
            INSTANCE.setEditor(editor);
            return INSTANCE;
        }
        INSTANCE = new TablePreviewDialog(editor);
        return INSTANCE;
    }

    private int x;
    private int y;
    private int width = 560;
    private int height = 420;

    private FormEditor editor;

    private TablePreviewDialog(FormEditor editor) {
        super(Display.getDefault().getActiveShell());
        this.editor = editor;
        setRectangle(getRectangle());
    }

    protected Control createContents(Composite parent) {
        // create the top level composite for the dialog
        Composite composite = new Composite(parent, 0);
        GridLayout layout = new GridLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.verticalSpacing = 0;
        composite.setLayout(layout);
        composite.setLayoutData(new GridData(GridData.FILL_BOTH));
        applyDialogFont(composite);
        // initialize the dialog units
        initializeDialogUnits(composite);
        // create the dialog area and button bar
        dialogArea = createDialogArea(composite);

        getShell().addShellListener(new ShellAdapter() {
            public void shellDeactivated(ShellEvent e) {
                close();
            }
        });
        return composite;
    }

    protected Rectangle getRectangle() {
        Rectangle rectangle = Display.getCurrent().getBounds();
        rectangle.x = Display.getCurrent().getCursorLocation().x;
        rectangle.y = Display.getCurrent().getCursorLocation().y;
        return rectangle;
    }

    public void setEditor(FormEditor editor) {
        this.editor = editor;
        setRectangle(getRectangle());
    }

    public void setRectangle(Rectangle rectangle) {
        this.x = rectangle.x;
        this.y = rectangle.y;
        int max_width = rectangle.width;
        int max_height = rectangle.height;
        if (x + width > max_width) {
            x = x - width;
        }
        if (y + height > max_height) {
            y = y - height;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets
     * .Composite)
     */
    protected Control createDialogArea(Composite parent) {
        parent.setLayout(new GridLayout(1, false));

        parent.addMouseListener(new MouseAdapter() {
            public void mouseUp(MouseEvent e) {
                // okPressed();
            }
        });
        parent.addKeyListener(new KeyAdapter() {
            public void keyReleased(KeyEvent e) {
                if (e.keyCode == SWT.ESC)
                    okPressed();
            }
        });

        Composite client = new Composite(parent, SWT.NONE);
        client.setLayout(new FillLayout());
        client.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        editor.createPartControl(client);
        return parent;
    }

    protected Point getInitialLocation(Point initialSize) {
        return new Point(x, y);
    }

    protected Point getInitialSize() {
        return new Point(width, height);
    }

    protected int getShellStyle() {
        return SWT.NO_TRIM;
    }

    protected void createButtonsForButtonBar(Composite parent) {

    }

    protected void okPressed() {
        // toolkit.dispose();
        super.okPressed();
    }

    public void dispose() {
        okPressed();
    }
}

 

以上,即完成了为GEF添加一个预览策略及内容。

 

转载于:https://www.cnblogs.com/anrainie/archive/2012/08/23/2651978.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,您需要创建一个 Eclipse RCP 项目。然后,您可以使用 SWT 绘制一个长方形,并使用 Tooltip 类显示长方形的信息。以下是一个示例代码: ```java import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseMoveListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Region; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.ToolTip; public class RectangleToolTip { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Rectangle rectangle = new Rectangle(50, 50, 100, 50); Region region = new Region(); region.add(rectangle); Color red = display.getSystemColor(SWT.COLOR_RED); Color white = display.getSystemColor(SWT.COLOR_WHITE); shell.addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { GC gc = e.gc; gc.setForeground(red); gc.setBackground(white); gc.setClipping(region); gc.fillRectangle(rectangle); gc.drawRectangle(rectangle); } }); ToolTip toolTip = new ToolTip(shell, SWT.BALLOON | SWT.ICON_INFORMATION); toolTip.setMessage("This is a rectangle."); shell.setToolTipText(""); shell.addMouseMoveListener(new MouseMoveListener() { ToolTip currentToolTip = null; @Override public void mouseMove(MouseEvent e) { if (region.contains(e.x, e.y)) { if (currentToolTip == null) { currentToolTip = toolTip; currentToolTip.setVisible(true); } currentToolTip.setLocation(e.x + 20, e.y + 20); } else { if (currentToolTip != null) { currentToolTip.setVisible(false); currentToolTip = null; } } } }); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } } ``` 在这个示例中,我们创建了一个长方形并绘制在 Shell 上。我们还创建了一个 ToolTip 对象,并将其附加到 Shell 上。当鼠标移动到长方形上时,我们使用 MouseMoveListener 检查鼠标位置是否在长方形内,如果是,则显示 ToolTip 对象,并将其位置设置为鼠标位置 +20。如果鼠标不在长方形内,则隐藏 ToolTip 对象。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值