GWT ImageMap,如何将鼠标处理程序注册到区域元素?

GWT ImageMap,如何将鼠标处理程序注册到区域元素?,gwt,Gwt,典型的ImageMap应用程序: 我有一个SVG/PNG地图,上面有区域,例如美国和州。 我有区域的多边形坐标。 我想注册鼠标处理程序,并根据区域的不同进行操作。 我正在努力让区域元素的处理程序开火 当前状态: 我已加载图像,创建并将图像关联到MapElement,并添加了AreaElement,如中所示。 按照与相同的模式,我创建了一个与link中相同的ImageMap小部件和一个ImageMapArea widges,后者包装了一个AreaElement,请参见下面的示例代码。 我还添加了一

典型的ImageMap应用程序:

我有一个SVG/PNG地图,上面有区域,例如美国和州。 我有区域的多边形坐标。 我想注册鼠标处理程序,并根据区域的不同进行操作。 我正在努力让区域元素的处理程序开火

当前状态:

我已加载图像,创建并将图像关联到MapElement,并添加了AreaElement,如中所示。 按照与相同的模式,我创建了一个与link中相同的ImageMap小部件和一个ImageMapArea widges,后者包装了一个AreaElement,请参见下面的示例代码。 我还添加了一个表示其ID的area属性,以便可以轻松地对所有AreaElement小部件使用相同的处理程序。 我在ImageMapArea小部件上注册的处理程序不会启动。为什么不呢?根据每个AreaElement区域,实现这种动态行为的正确方法是什么? 在其他站点上,我看到了onmousedown=myJsOnMouseDownFunction、onmouseover等区域元素属性。我正在寻找一种GWT方法来实现相同的动态行为。我已经用java代码实现了这些处理程序,请参见下面的示例。如何将它们插入到Area元素或ImageMapArea小部件中? 以下是我的ImageMapArea包装区域元素:

public class ImageMapArea extends Widget implements HasMouseDownHandlers, HasMouseOverHandlers, HasMouseOutHandlers
{
  private AreaElement areaElement;

  public ImageMapArea() {
    areaElement = Document.get().createAreaElement();
    super.setElement(areaElement);
  }

  public AreaElement getAreaElement() { return areaElement; }

  @Override
  public HandlerRegistration addMouseDownHandler(final MouseDownHandler handler)
  {
    return super.addDomHandler(handler, MouseDownEvent.getType());
  }

  @Override
  public HandlerRegistration addMouseOutHandler(final MouseOutHandler handler)
  {
    return super.addDomHandler(handler, MouseOutEvent.getType());
  }

  @Override
  public HandlerRegistration addMouseOverHandler(final MouseOverHandler handler)
  {
    return super.addDomHandler(handler, MouseOverEvent.getType());
  }
}
以下是我如何将其编织在一起:

// Setup ImageMap.
Image map = new Image("MyMap.svg");
ImageMap imageMap = new ImageMap();
map.getElement().setAttribute("usemap", "#" + "dynmap");
imageMap.setName("dynmap");

// Add area.
ImageMapArea area = new ImageMapArea();
area.getAreaElement().setShape("poly");
area.getAreaElement().setCoords(<string representing the coordinates of area>);
area.getAreaElement().setPropertyInt("aid", 1); // ID to dynamically identify the area element.
area.getAreaElement().setAlt("This is region #1");
area.getAreaElement().setTitle("This is region #1"); // Tooltip works so above coordinates are good.
area.setStylePrimaryName("area");
area.addStyleDependentName("out");
// Add handlers -- those that do not fire.
area.addMouseDownHandler(handlerDown);
area.addMouseOutHandler(handlerOut);
area.addMouseOverHandler(handlerOver);

// Handler example.
final MouseDownHandler handlerDown = new MouseDownHandler()
{
  @Override
  public void onMouseDown(MouseDownEvent event)
  {
    final Object source = event.getSource();
    final ImageMapArea area = (ImageMapArea) source; // A breakpoint here never stopped.
    if (area != null)
    {
      final int areaIndex = area.getAreaElement().getPropertyInt("aid");
      if (areaIndex != areaSelectedIndex)
      {
        area.removeStyleDependentName("over");
        area.addStyleDependentName("selected");
        areaSelectedIndex = areaIndex;
        ... // Other dynamic actions that depend upon the area/region triggering this event.
      }
    }
  }
};

我不知道为什么我的问题中的处理程序不会启动,但从引导到中得到启发,我发现了一种有效的方法:诀窍是求助于本机javascript JSNI来设置onmouse回调-

如果有人发现它像我一样有用,下面是我的ImageMapArea更新版本,用于设置本机处理程序

public class ImageMapArea extends Widget
{
  private AreaElement areaElement;
  private ArrayList<Hook> onMouseDownHooks = null;
  private ArrayList<Hook> onMouseOutHooks = null;
  private ArrayList<Hook> onMouseOverHooks = null;

  public ImageMapArea() {
    areaElement = Document.get().createAreaElement();
    super.setElement(areaElement);
    this.setupNativeHandlers(areaElement);
  }

  public AreaElement getAreaElement() { return areaElement; }

  public void addMouseDownHandler(final Hook handler)
  {
    if (onMouseDownHooks == null)
      onMouseDownHooks = new ArrayList<Hook>(1);
    onMouseDownHooks.add(handler);
  }

  public void addMouseOutHandler(final Hook handler)
  {
    if (onMouseOutHooks == null)
      onMouseOutHooks = new ArrayList<Hook>(1);
    onMouseOutHooks.add(handler);
  }

  public void addMouseOverHandler(final Hook handler)
  {
    if (onMouseOverHooks == null)
      onMouseOverHooks = new ArrayList<Hook>(1);
    onMouseOverHooks.add(handler);
  }

  private void onMouseDown()
  {
    if (onMouseDownHooks != null && !onMouseDownHooks.isEmpty())
    {
      for (int i = 0; i < onMouseDownHooks.size(); ++i)
      {
        final Hook hook = onMouseDownHooks.get(i);
        hook.execute();
      }
    }
  }

  private void onMouseOut()
  {
    if (onMouseOutHooks != null && !onMouseOutHooks.isEmpty())
    {
      for (int i = 0; i < onMouseOutHooks.size(); ++i)
      {
        final Hook hook = onMouseOutHooks.get(i);
        hook.execute();
      }
    }
  }

  private void onMouseOver()
  {
    if (onMouseOverHooks != null && !onMouseOverHooks.isEmpty())
    {
      for (int i = 0; i < onMouseOverHooks.size(); ++i)
      {
        final Hook hook = onMouseOverHooks.get(i);
        hook.execute();
      }
    }
  }

  private native void setupNativeHandlers(final AreaElement elem) /*-{
    var self = this;
    elem.onmousedown = function(){
        self.@bkg.gwt.resources.client.widget.ImageMapArea::onMouseDown()();
    };
    elem.onmouseout = function(){
        self.@bkg.gwt.resources.client.widget.ImageMapArea::onMouseOut()();
    };
    elem.onmouseover = function(){
        self.@bkg.gwt.resources.client.widget.ImageMapArea::onMouseOver()();
    };
  }-*/;
}
上面的钩子就是Scheduler.ScheduledCommand

除了处理程序是在回调命令中而不是在GWT鼠标处理程序中实现外,所有操作都与以前相同;上面的ImageMapArea负责设置本机JSNI回调

一个改进是使用ImageMapArea参数定义Hook.execute,这样所有区域都可以共享同一个Hook回调对象