Chinaunix首页 | 论坛 | 博客
  • 博客访问: 508119
  • 博文数量: 95
  • 博客积分: 5168
  • 博客等级: 大校
  • 技术积分: 1271
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-28 23:31
文章分类

全部博文(95)

文章存档

2013年(2)

2012年(3)

2011年(1)

2010年(8)

2009年(81)

分类:

2009-10-11 18:34:23

-----------------------------------------------------------
本文系本站原创,欢迎转载!

转载请注明出处:http://sjj0412.cublog.cn/

-----------------------------------------------------------

事件处理在图形系统中起着十分重要的作用,gef的图形终归来说是属于swt中的一个控件,所以其事件(消息)来源都是swt系统。

GEF中,lightweightgef图形系统的”shell””display”,其在swt中的代理是canvas,所以所有的gef的事件来源于这个canvas,下面就看下gef事件处理的流程,首先肯定要监听canvas的事件,这个通过LightweightSystemaddListeners函数注册其内的canvas的各种事件监听器。

1.Swt层事件监听器安装:

Class ScrollingGraphicalViewer

 

public final Control createControl(Composite parent) {

FigureCanvas canvas = new FigureCanvas(parent, getLightweightSystem());

    setControl(canvas);

    installRootFigure();

    return canvas;

}

 

Class  FigureCanvas

 

public FigureCanvas(int style, Composite parent, LightweightSystem lws) {

    super(parent, checkStyle(style));

    getHorizontalBar().setVisible(false);

    getVerticalBar().setVisible(false);

    this.lws = lws;

    lws.setControl(this);

    hook();

}

 

 

Class LightweightSystem

 

public void setControl(Canvas c) {

    if (canvas == c)

       return;

    canvas = c;

    if ((c.getStyle() & SWT.DOUBLE_BUFFERED) != 0)

       getUpdateManager().setGraphicsSource(new NativeGraphicsSource(canvas));

    else

       getUpdateManager().setGraphicsSource(new BufferedGraphicsSource(canvas));

    getEventDispatcher().setControl(c);

    addListeners();

   

    //Size the root figure and contents to the current control's size

    Rectangle r = new Rectangle(canvas.getClientArea());

    r.setLocation(0, 0);

    root.setBounds(r);

    root.revalidate();

}

//下面这个就是添加canvas的各种事件监听器。

protected void addListeners() {

    EventHandler handler = createEventHandler();

    canvas.getAccessible().addAccessibleListener(handler);

    canvas.getAccessible().addAccessibleControlListener(handler);

    canvas.addMouseListener(handler);

    canvas.addMouseMoveListener(handler);

    canvas.addMouseTrackListener(handler);

    canvas.addKeyListener(handler);

    canvas.addTraverseListener(handler);

    canvas.addFocusListener(handler);

    canvas.addDisposeListener(handler);

    canvas.addListener(SWT.MouseWheel, handler);

 

    canvas.addControlListener(new ControlAdapter() {

       public void controlResized(ControlEvent e) {

           LightweightSystem.this.controlResized();

       }

    });

    canvas.addListener(SWT.Paint, new Listener() {

       public void handleEvent(Event e) {

           LightweightSystem.this.paint(e.gc);

       }

    });

}

上面的EventHandler LightweightSystem 的内部类,故下面的getEventDispatcher 都是LightweightSystem 的函数。

 

protected class EventHandler

        implements MouseMoveListener, MouseListener, AccessibleControlListener, KeyListener,

              TraverseListener, FocusListener, AccessibleListener, MouseTrackListener,

              Listener, DisposeListener

{

    public void handleEvent(Event event) {

       // Mouse wheel events

       if (event.type == SWT.MouseWheel)

           getEventDispatcher().dispatchMouseWheelScrolled(event);

    }

   

    /**@see MouseListener#mouseDown(MouseEvent)*/

    public void mouseDown(MouseEvent e) {

       getEventDispatcher().dispatchMousePressed(e);

    }

   

    /**@see MouseListener#mouseUp(MouseEvent)*/

    public void mouseUp(MouseEvent e) {

       getEventDispatcher().dispatchMouseReleased(e);

    }

   

    /**@see DisposeListener#widgetDisposed(DisposeEvent)*/

    public void widgetDisposed(DisposeEvent e) {

       getUpdateManager().dispose();

    }

}

protected EventDispatcher getEventDispatcher() {

    if (dispatcher == null)

       setEventDispatcher(new SWTEventDispatcher());

    return dispatcher;

}

protected EventDispatcher getEventDispatcher() {

    if (dispatcher == null)

       setEventDispatcher(new SWTEventDispatcher());

    return dispatcher;

}

从上面可以看出,swt控件层的事件其实会调用dispatcher的相关处理函数,dispatcher可以看成是消息分发器,只不过是LightweightSystem里的

那这个dispatcher是怎么赋值的呢?

 


 

2  LightweightSystem层消息分发器安装:

gef里是如下过程:

class GraphicalEditor

public void createPartControl(Composite parent) {

createGraphicalViewer(parent);

}

protected void createGraphicalViewer(Composite parent) {

GraphicalViewer viewer = new ScrollingGraphicalViewer();

viewer.createControl(parent);

setGraphicalViewer(viewer);

configureGraphicalViewer();

hookGraphicalViewer();

initializeGraphicalViewer();

}

protected void setGraphicalViewer(GraphicalViewer viewer) {

getEditDomain().addViewer(viewer);

this.graphicalViewer = viewer;

}

class EditDomain

public void addViewer(EditPartViewer viewer) {

viewer.setEditDomain(this);

if (!viewers.contains(viewer))

viewers.add(viewer);

}

//下面 这个函数添加了LightweightSystem添加了EventDispatcher

class GraphicalViewerImpl

public void setEditDomain(EditDomain domain) {

super.setEditDomain(domain);

// Set the new event dispatcher, even if the new domain is null.  This will dispose

// the old event dispatcher.

getLightweightSystem()

.setEventDispatcher(eventDispatcher = new DomainEventDispatcher(domain, this));

}

 

class LightweightSystem

public void setEventDispatcher(EventDispatcher dispatcher) {

this.dispatcher = dispatcher;  //在此Shapes例子中是DomainEventDispatcher

dispatcher.setRoot(root);

dispatcher.setControl(canvas);

}

 

2  LightweightSystem消息分发器处理流程:

下面就看下DomainEventDispatcher的分发流程,我们以键盘消息为例:

 

Class  DomainEventDispatcher

 

public void dispatchMousePressed(org.eclipse.swt.events.MouseEvent me) {

    if (!editorCaptured) {

       super.dispatchMousePressed(me);

       if (draw2dBusy())

           return;

    }

    if (okToDispatch()) {

       setFocus(null);

       control.forceFocus();

       setRouteEventsToEditor(true);

       domain.mouseDown(me, viewer);

    }

}

然后就执行domainmouseDown;

     这个domain是在具体GEF编辑器赋值的

 

 

Class PracticeEditor extends GraphicalEditorWithPalette

 

public PracticeEditor() {

             setEditDomain(new DefaultEditDomain(this));

}

故上面会调用DefaultEditDomainkeydown;

 

public class DefaultEditDomain

    extends EditDomain

{

 

private IEditorPart editorPart;

 

public DefaultEditDomain(IEditorPart editorPart) {

    setEditorPart(editorPart);

}

public IEditorPart getEditorPart() {

    return editorPart;

}

protected void setEditorPart(IEditorPart editorPart) {

    this.editorPart = editorPart;

}

 

所以应该是editdomainkeydown;

Class Editdomain

 

public void mouseDown(MouseEvent mouseEvent, EditPartViewer viewer) {

    Tool tool = getActiveTool();

    if (tool != null)

       tool.mouseDown(mouseEvent, viewer);

}

 

ActiveTool是在创建EditDomain就赋值了的

 

public EditDomain() {

    loadDefaultTool();

}

public void loadDefaultTool() {

    setActiveTool(null);

    PaletteViewer paletteViewer = getPaletteViewer();

    if (paletteRoot != null && paletteViewer != null) {

       if (paletteRoot.getDefaultEntry() != null) {

           paletteViewer.setActiveTool(paletteRoot.getDefaultEntry());

           return;

       } else

           paletteViewer.setActiveTool(null);

    }

    setActiveTool(getDefaultTool());

}

public Tool getDefaultTool() {

    if (defaultTool == null)

       defaultTool = new SelectionTool();

    return defaultTool;

}

从上可见ActiveTool默认是SelectionTool

现在就真正进入gef的事件核心了,对于Tool层的事件处理流程,我将在下面几篇文章里针对不同Tool,分别进行讲解。

 

阅读(1966) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~