GWT小部件中的自定义事件无效

时间:2014-06-14 09:22:49

标签: java gwt vaadin7

我正在为Vaadin申请我的课程。 我必须在屏幕上绘制一些地图,所以我使用的是gwt-graphics lib。 我还有一些等待请求的servlet。 当一些特定的请求将来到地图的视图应该改变。 它引导我准备自定义事件:

// class NewModulePositionHandler
package com.example.locator;

import com.google.gwt.event.shared.EventHandler;

public interface NewModulePositionHandler extends EventHandler {
    void onNewModulePosition(NewModulePositionEvent event);
}

我的自定义事件的实现:

import com.google.gwt.event.shared.GwtEvent;

public class NewModulePositionEvent extends GwtEvent<NewModulePositionHandler> {
    private static final Type<NewModulePositionHandler> TYPE = new Type<NewModulePositionHandler>();
    private final String m_Color;

    public NewModulePositionEvent(String color) {
        m_Color = color;
    }

    public static Type<NewModulePositionHandler> getType() {
        return TYPE;
    }

    public String getColor() {
        return m_Color;
    }

    @Override
    public com.google.gwt.event.shared.GwtEvent.Type<NewModulePositionHandler> getAssociatedType() {
        // TODO Auto-generated method stub
        return TYPE;
    }

    @Override
    protected void dispatch(NewModulePositionHandler handler) {
        handler.onNewModulePosition(this);
    }

}

是时候实现我的自定义小部件了:

a)MyComp.java

import com.google.gwt.event.shared.GwtEvent;

public class NewModulePositionEvent extends GwtEvent<NewModulePositionHandler> {
    private static final Type<NewModulePositionHandler> TYPE = new Type<NewModulePositionHandler>();
    private final String m_Color;

    public NewModulePositionEvent(String color) {
        m_Color = color;
    }

    public static Type<NewModulePositionHandler> getType() {
        return TYPE;
    }

    public String getColor() {
        return m_Color;
    }

    @Override
    public com.google.gwt.event.shared.GwtEvent.Type<NewModulePositionHandler> getAssociatedType() {
        // TODO Auto-generated method stub
        return TYPE;
    }

    @Override
    protected void dispatch(NewModulePositionHandler handler) {
        handler.onNewModulePosition(this);
    }

}

b)MyCompClientRpc.java

import com.vaadin.shared.communication.ClientRpc;

public interface MyCompClientRpc extends ClientRpc {

    // TODO example API
    public void alert(String message);
    public void changeColor(String color);
}

c)MyCompConnector.java

package com.example.locator.widgetset.client.mycomp;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
import com.example.locator.MyComp;
import com.example.locator.NewModulePositionEvent;
import com.example.locator.NewModulePositionHandler;
import com.example.locator.widgetset.client.mycomp.MyCompWidget;
import com.example.locator.widgetset.client.mycomp.MyCompServerRpc;
import com.vaadin.client.communication.RpcProxy;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.client.MouseEventDetailsBuilder;
import com.example.locator.widgetset.client.mycomp.MyCompClientRpc;
import com.example.locator.widgetset.client.mycomp.MyCompState;
import com.vaadin.client.communication.StateChangeEvent;

@Connect(MyComp.class)
public class MyCompConnector extends AbstractComponentConnector {
MyCompServerRpc rpc = RpcProxy
        .create(MyCompServerRpc.class, this);

public MyCompConnector() {
    registerRpc(MyCompClientRpc.class, new MyCompClientRpc() {
        public void alert(String message) {
            // TODO Do something useful
            Window.alert(message);
        }
        public void changeColor(String color) {
            getWidget().InitMap(color);         
        }
    });

    // TODO ServerRpc usage example, do something useful instead
    getWidget().addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
                .buildMouseEventDetails(event.getNativeEvent(),
                            getWidget().getElement());
            rpc.clicked(mouseDetails);
        }
    });


    getWidget().addNewModulePositionHandler(new NewModulePositionHandler() {

        public void onNewModulePosition(NewModulePositionEvent event) {
            // TODO Auto-generated method stub
            rpc.newModulePosition(event.getColor());
        }

    });

}

@Override
protected Widget createWidget() {
    return GWT.create(MyCompWidget.class);
}

@Override
public MyCompWidget getWidget() {
    return (MyCompWidget) super.getWidget();
}

@Override
public MyCompState getState() {
    return (MyCompState) super.getState();
}

@Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
    super.onStateChanged(stateChangeEvent);

    // TODO do something useful
    final String color = getState().color;
    getWidget().InitMap(color);
}

}

d)MyCompServerRpc.java

package com.example.locator.widgetset.client.mycomp;

import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.communication.ServerRpc;

public interface MyCompServerRpc extends ServerRpc {

    // TODO example API
    public void clicked(MouseEventDetails mouseDetails);
    public void newModulePosition(String color);
}

e)MyCompState.java

package com.example.locator.widgetset.client.mycomp;

public class MyCompState extends com.vaadin.shared.AbstractComponentState {

    // TODO example state
    public String color = "#000000";

}

最后实现了小部件:

f)MyCompWidget.java

package com.example.locator.widgetset.client.mycomp;
import org.vaadin.gwtgraphics.client.DrawingArea;
import org.vaadin.gwtgraphics.client.Line;
import org.vaadin.gwtgraphics.client.shape.Circle;
import org.vaadin.gwtgraphics.client.shape.Rectangle;

import com.example.locator.HasNewModulePositionHandlers;
import com.example.locator.NewModulePositionEvent;
import com.example.locator.NewModulePositionHandler;
import com.google.gwt.dev.util.collect.HashMap;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.touch.client.Point;
import com.example.locator.Module;

// TODO extend any GWT Widget


public class MyCompWidget extends DrawingArea implements HasNewModulePositionHandlers {

    public static final String CLASSNAME = "mycomp";
    public static double m_AreaWidth = 64.355;
    public static double m_AreaHeight = 17.385;
    public static int m_PictureWidth;
    public static int m_PictureHeight;
    public static double m_AreaToMapRatio;
    public static double m_RouteWidth = 3.5;
    public static double m_MainRouteCoordinateY = 8.0828;
    public Circle circle;
    //public HashMap<Integer, Module> ModuleMap = new HashMap<Integer, Module>();

    public MyCompWidget(){
        super(640, 320);

        //ModuleMap.put(666, new Module(666, 30.0, 8.08, new Circle((int)TranslateCoordinate(30.0), (int)TranslateCoordinate(8.0), 7)));
        //ModuleMap.put(15, new Module(15, 27.0, 8.08, new Circle((int)TranslateCoordinate(30.0), (int)TranslateCoordinate(8.0), 7)));

        double xRatio = m_AreaWidth / 640;
        double yRatio = m_AreaHeight / 320;
        m_AreaToMapRatio = xRatio > yRatio ? xRatio : yRatio;

        InitMap("#919491");
        setStyleName(CLASSNAME);
    }

    public void InitMap(String color)
    {
        m_PictureWidth  = (int)TranslateCoordinate(m_AreaWidth);
        m_PictureHeight  = (int)TranslateCoordinate(m_AreaHeight);
        Rectangle rectangle = new Rectangle(0, 0, m_PictureWidth, m_PictureHeight);
        rectangle.setFillColor(color);
        add(rectangle);
        Point point1Beg = new Point(0.0, 8.0828);
        Point point1End = new Point(64.355, 8.0838);

        Point point2Beg = new Point(20.2825, 8.0828);
        Point point2End = new Point(20.2825, 17.385);

        Point point3Beg = new Point(59.325, 0.0);
        Point point3End = new Point(59.325, 8.0828);

        point1Beg = TranslatePoint(point1Beg);
        point1End = TranslatePoint(point1End);

        point2Beg = TranslatePoint(point2Beg);
        point2End = TranslatePoint(point2End);

        point3Beg = TranslatePoint(point3Beg);
        point3End = TranslatePoint(point3End);

        Line line1 = new Line((int)point1Beg.getX(), (int)point1Beg.getY(), (int)point1End.getX(), (int)point1End.getY());
        Line line2 = new Line((int)point2Beg.getX(), (int)point2Beg.getY(), (int)point2End.getX(), (int)point2End.getY());
        Line line3 = new Line((int)point3Beg.getX(), (int)point3Beg.getY(), (int)point3End.getX(), (int)point3End.getY());

        line1.setStrokeColor("#FFFFFF");
        line2.setStrokeColor("#FFFFFF");
        line3.setStrokeColor("#FFFFFF");

        line1.setStrokeWidth((int)TranslateCoordinate(m_RouteWidth));
        line2.setStrokeWidth((int)TranslateCoordinate(m_RouteWidth));
        line3.setStrokeWidth((int)TranslateCoordinate(m_RouteWidth));

        add(line1);
        add(line2);
        add(line3);

        DrawWall(TranslateCoordinate(10.0));
        DrawWall(TranslateCoordinate(20.0));
        DrawWall(TranslateCoordinate(30.0));
        DrawWall(TranslateCoordinate(40.0));
        DrawWall(TranslateCoordinate(50.0));
        DrawWall(TranslateCoordinate(60.0));

        DrawDoor(3.0, 3.0);
        DrawDoor(13.0, 3.0);
        DrawDoor(23.0, 3.0);
        DrawDoor(33.0, 3.0);
        DrawDoor(43.0, 3.0);
        DrawDoor(53.0, 3.0);
        circle = new Circle((int)TranslateCoordinate(25.0), (int)TranslateCoordinate(8.0), 15);
        add(circle);
    }

    public void DrawWall(double a_Place)
    {
        Line line = new Line((int)a_Place, 0, (int)a_Place, (int)TranslateCoordinate(m_AreaHeight));
        line.setStrokeColor("#FFFFFF");
        add(line);
    }

    public void DrawDoor(double a_Position, double a_Width)
    {
        double realDoorPositionY = m_MainRouteCoordinateY - (m_RouteWidth / 2);
        int doorPositionYTop = (int)TranslateCoordinate(realDoorPositionY) - 1;
        int doorPositionYBottom = (int)TranslateCoordinate(realDoorPositionY + m_RouteWidth) + 1;

        Line line = new Line((int)TranslateCoordinate(a_Position), doorPositionYTop, (int)TranslateCoordinate(a_Position) + (int)TranslateCoordinate(a_Width), doorPositionYTop);
        line.setStrokeColor("#000000");
        line.setStrokeWidth(2);
        add(line);
        Line line2 = new Line((int)TranslateCoordinate(a_Position), doorPositionYBottom, (int)TranslateCoordinate(a_Position) + (int)TranslateCoordinate(a_Width), doorPositionYBottom);
        line2.setStrokeColor("#000000");
        line2.setStrokeWidth(2);
        add(line2);
    }

    public Point TranslatePoint(Point a_Point)
    {
        Point translatedPoint = new Point(TranslateCoordinate(a_Point.getX()), TranslateCoordinate(a_Point.getY()));
        return translatedPoint;
    }

    public double TranslateCoordinate(double a_Coordinate)
    {
        return (a_Coordinate) / (m_AreaToMapRatio);
    }

    public void Move(int id) {
        //ModuleMap.get(id).GetCircle().setX(10 + circle.getX());
    }


       public HandlerRegistration addNewModulePositionHandler(
                NewModulePositionHandler handler) {
            return addHandler(handler, NewModulePositionEvent.TYPE);
        }

        private void someMethod() {
            fireEvent(new NewModulePositionEvent("#000000"));
        }
        public void emulateEvent() {
            someMethod();
        }
}

g)HasNewModulesPositionHandlers.java

package com.example.locator;

import com.google.gwt.event.shared.HandlerRegistration;

public interface HasNewModulePositionHandlers {
    // Attention! method returns HandlerRegistration, so that handler can be cancelled
    public HandlerRegistration addNewModulePositionHandler(
            NewModulePositionHandler handler);
}

如果我编译包含MyCompWidget的小部件集然后在glassfish上运行我的应用程序,我会收到以下消息:

  

Widgetset'com.example.locator.widgetset.LocatorWidgetset'不包含com.example.locator.MyComp的实现。检查其组件连接器的@Connect映射,widgetsets GWT模块描述文件并重新编译您的widgetset。如果您下载了vaadin附加软件包,则可能需要参考附加说明。

如果我剪了

  public void addNewModulePositionHandler(
            NewModulePositionHandler handler) {
        handlerManager.addHandler(NewModulePositionEvent.getType(), handler);
        // TODO Auto-generated method stub
    }

小部件正常工作(当然我也必须从MyCompConnector中注释掉这些行):

    getWidget().addNewModulePositionHandler(new NewModulePositionHandler() {

        public void onNewModulePosition(NewModulePositionEvent event) {
            // TODO Auto-generated method stub
            rpc.newModulePosition(event.getColor());
        }

    });

谁能告诉我问题出在哪里?似乎小部件的编译失败但我找不到任何有关它的信息。 请帮我。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

编译问题非常明确:GWT编译器无法为指定的java类提供源代码。您可以通过两个步骤将源文件添加到GWT编译器范围:

  1. *。必须可以通过classpath访问java文件(eclipse gwt编译器会自动将所有源文件夹包含到classpath中)
  2. 您需要告诉GWT它应该在编译期间考虑您的包
    • 使用以下内容在PARENT包中创建.gwt.xml文件(相对于您的源文件)(如果您的包是pkg1.pkg2.pkg3,那么您应该在包pkg1.pkg2中创建文件&#34; Pkg3。 gwt.xml&#34;,pkg =&#34; pkg3&#34;,按惯例,pkg3通常命名为&#34; client&#34;)
  3. <module>
        <source path="pkg3" />
    </module>
    

    !!!注意字母大小写,按照惯例,这些是正确的名称。

    • 添加到您的widgetset.gwt.xml文件&#34;继承&#34;这样的指令
    <inherits name="pkg1.pkg2.Pkg3" />
    

    !!!注意字母案例(P是Pkg3中的大写,文件名Pkg3.gwt.xml之后),这里省略.gwt.xml

    然后,首先,Vaadin使用GWT有一定的扭曲。我建议浏览自定义widgetset示例。您可能需要了解如何在Vaadin特定组件之间传播事件。下面我将解释如何实现和使用GWT事件。我不是Vaadin的专家,特别是在自定义widgetset等高级主题中。

    所以,谈到GWT。

    基本上,你需要理解两件事(非DOM,也知道无用)事件在GWT中有效。

    1. 代码支持
      • 活动课程。在你的情况下NewModulePositionEvent。
      • 事件处理程序界面。在你的情况下NewModulePositionHandler。
      • 功能界面(可选但建议)。在你的情况下HasNewModulePositionHandlers。
    2. 使用模式
      • 基本上,应该触发事件的组件应创建相关的Event对象并将其传递给fireEvent方法。调用必要的habdler的所有逻辑都是由EventBus(内部)
      • 提供的
      • 如果您需要提供外部触发事件的API(例如Button的click()方法),则应该通过提供特殊方法来完成(不要公开内部资料如何触发事件)
    3. DOM事件特别详细地说明了它们是如何创建的(通过浏览器)和调度的(它们需要显式启用)。无论如何,所有的浏览器事件都已经在GWT中实现了开箱即用。

      所以,上述项目的典型实现:为了清楚起见,我提供了生产代码的摘录。

      1)事件类

      public class QuestionClickEvent extends GwtEvent<QuestionClickHandler> {
      
          public QuestionClickEvent(SScript script, SQuestion question) {
              super();
              this.script = script;
              this.question = question;
          }
      
          public static final Type<QuestionClickHandler> TYPE = new Type<QuestionClickHandler>();
      
          // internal event state
          private final SScript script;
          private final SQuestion question;
      
          @Override
          public Type<QuestionClickHandler> getAssociatedType() {
               return TYPE;
          }
      
          @Override
          protected void dispatch(QuestionClickHandler handler) {
              handler.onQuestionClicked(this);
          }
      
      
          // provide access to internal event state
      
          public SScript getScript() {
              return script;
          }
      
          public SQuestion getQuestion() {
              return question;
          }
      }
      

      2)处理程序界面

      public interface QuestionClickHandler extends EventHandler {
          public void onQuestionClicked(QuestionClickEvent event);
      }
      

      3)功能界面

      public interface HasQuestionClickHandlers {
          // Attention! method returns HandlerRegistration, so that handler can be cancelled
          public HandlerRegistration addQuestionClickHandler(
                  QuestionClickHandler handler);
      }
      

      4)您的小部件/组件

      public class SummaryPanel extends Widget implements HasQuestionClickHandlers {
      // blah-blah-blah
      
              // implement your handler registration method
          @Override
          public HandlerRegistration addQuestionClickHandler(
                  QuestionClickHandler handler) {
              return addHandler(handler, QuestionClickEvent.TYPE);
          }
      
      // blah-blah-blah
      
          private someMethod() {
              // suddenly you realized that you need to to fire your event
              fireEvent(new QuestionClickEvent(script, question));
          }
      
      // sample external API method
      
          public void emulateEvent() {
              someMethod();
          }
      }
      

      最后用法示例:

          SummaryPanel summary = new SummaryPanel();
          summary.addQuestionClickHandler(new QuestionClickHandler() {
      
              @Override
              public void onQuestionClicked(QuestionClickEvent event) {
                  // your reaction goes here
              }
          });