【问题标题】:GWT - Reference to a global variable set by callback methodGWT - 引用由回调方法设置的全局变量
【发布时间】:2012-12-19 14:31:31
【问题描述】:

请帮助我,因为我很快就会为此发疯:

当我运行代码时,第一次执行 loadNewPoint() 并显示来自全局变量 - allPointsAndPlaces 的一些数据

但是,当我单击一个按钮(来自子类)时,相同的方法 loadNewPoint() 为我提供了 allPointsAndPlaces 的空指针。

为了解决这个问题,我对原来的代码结构进行了很多更改,并将这个方法 (loadNewPoint()) 移到父类中,看看它是否能解决问题。

父类:

public class CabbieApp implements EntryPoint {

  private GetLocationsServiceAsync getAllLocationsService = GWT.create(GetLocationsService.class);
  CabbiePoint[] allPointsAndPlaces;
  PointsQuiz quiz;

  /**
   * Entry point method.
   */
  public void onModuleLoad() {

      //Get all the required data from DB
      getAllPointsAndLocations();

  }

  private void loadAppPages(){
      // Associate the Main panel with the HTML host page.
      RootPanel rootPanel = RootPanel.get("pointsList");    

      quiz = new PointsQuiz();

      rootPanel.setStyleName("GWTapp");
      rootPanel.add(quiz.getMainPanel());

      loadNewPoint();

  }


    private void getAllPointsAndLocations() {
        // Initialize the service proxy.
        if (getAllLocationsService == null) {
            getAllLocationsService = GWT.create(GetLocationsService.class);
        }

        // Set up the callback object.
        AsyncCallback<CabbiePoint[]> callback = new AsyncCallback<CabbiePoint[]>() {
          public void onFailure(Throwable caught) {
              System.out.println(caught.getMessage());
          }

          public void onSuccess(CabbiePoint[] result) {
            //allPointsAndPlaces = result;
            System.out.println(result.length);
            allPointsAndPlaces = result;
            loadAppPages();


          }
        };

        // Make the call to the service.
        getAllLocationsService.getLocations(callback);

    }


    void loadNewPoint(){
        int r = Random.nextInt(allPointsAndPlaces.length);
        quiz.CurrentPlace = allPointsAndPlaces[r].getPlaceName();
        quiz.CurrentLocation = allPointsAndPlaces[r].getPlaceLocation();

        quiz.point.setText(quiz.CurrentPlace);
        quiz.location.setText(quiz.CurrentLocation);
        quiz.location.setStyleName("invisibleText");
    }

  }

儿童班:

public class PointsQuiz extends CabbieApp{

       VerticalPanel mainPanel = new VerticalPanel();
       HorizontalPanel navigation = new HorizontalPanel();
       TextBox point = new TextBox();
       TextBox location = new TextBox();
       Button showLocation = new Button("Show Location");
       Button nextPoint = new Button("Next Point");
       String CurrentPlace, CurrentLocation;


      public PointsQuiz() {

          // Assemble Add Stock panel.
              navigation.add(showLocation);
              navigation.add(nextPoint);
              navigation.setCellHorizontalAlignment(nextPoint, HasHorizontalAlignment.ALIGN_RIGHT);
              navigation.addStyleName("addPanel");
              mainPanel.setSpacing(5);
              mainPanel.setStyleName("body");
              mainPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
              mainPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);

            // Assemble Main panel.
            mainPanel.add(point);
            point.setWidth("200px");
            mainPanel.add(location);
            location.setWidth("200px");
            mainPanel.add(navigation);
            navigation.setWidth("200px");

         // Move cursor focus to the input box.
            showLocation.setFocus(true);

         // Listen for mouse events on the show location button.
            showLocation.addClickHandler(new ClickHandler() {
              public void onClick(ClickEvent event) {
                showCurrentLocation();}
              });


             // Listen for mouse events on the next point button.
            nextPoint.addClickHandler(new ClickHandler() {
              public void onClick(ClickEvent event) {
                loadNewPoint();
                  }
            });       
      }



        private void showCurrentLocation(){
            location.setStyleName("visibleText");
        }

        public VerticalPanel getMainPanel() {
            return mainPanel;
        }


}

【问题讨论】:

    标签: gwt variables methods callback scope


    【解决方案1】:

    在 Bhumika 的帮助下,我设法找到了解决这个问题的方法。

    为了完成这项工作,我必须将 CabbiePoint[] allPointsAndPlaces 更改为静态。

    这将以一种方式解决引用问题 - 从孩子到父母。

    我也设法通过调试找出了这个参考

    quiz = new PointsQuiz(); 
    

    在第二次运行 loadNewPoint() 时也为空。所以这个子引用 (PointsQuiz quiz;) 和任何其他对子的引用也设置为静态。

    【讨论】:

      【解决方案2】:

      由于allPointsAndPlaces 为空,您收到空指针错误。根据您的编码 allPointsAndPlaces 的值是在 getAllPointsAndLocations() 方法中的 RPC 调用完成后分配的。所以allPointsAndPlaces 有一些赋值。

      这里你尝试直接访问子类中的loadNewPoint() 方法。一次,allPointsAndPlaces 未分配。

      【讨论】:

      • 非常感谢您的回答。我明白这个问题。
      • 但是有时候,当我尝试通过单击按钮从子类运行 loadNewPoint() 时,RPC 已经完成,并且 loadNewPoint() 已经运行了一次。这怎么可能,当一个方法已经被调用一次并且已经使用了 allPointsAndPlaces 时,它不会再看到相同的引用?以及如何更改代码以避免这种情况并使 allPointsAndPlaces 可以通过其他方法访问?
      • allPointsAndPlaces 是对象,因此其默认值为空。当您创建 PointsQuiz 的实例时,因此间接地将 CabbieApp 作为其创建的超类。并且 allPointsAndPlaces 将分配 null.if 你想管理allPointsAndPlaces 状态所以你必须作为一个静态对象。 static CabbiePoint[] allPointsAndPlaces; 你的问题也会解决的。
      • 非常感谢您的帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      • 1970-01-01
      相关资源
      最近更新 更多