Jorge Lazo
Jorge Lazo

Reputation: 388

Using a button to refresh a panel in GWT

I have a small web application project using GWT, where a button handles an event: populating a panel with widgets. Currently, clicking the button a second time will duplicate the panel, i want it so it clears the panel, and re adds the widgets.

So far I have:

final Button b = new Button("get schools near me");
    final HorizontalPanel panel = new HorizontalPanel();
    panel.getElement().setId("distanceTable");
    RootPanel.get("core").add(b);
    RootPanel.get("core").add(panel);
    b.addClickHandler(new ClickHandler(){
        @Override
        public void onClick(ClickEvent event) {
            Timer t = new Timer(){
                @Override
                public void run() {
                    //how do you clear the panel here first? before you
                    // do a bunch of things along the lines of:
                    panel.add(widget);
                    panel.add(widget2);
                }
            };
            t.schedule(1400); // wait 1.4 seconds for callback
        }
    });

I get that anything you pass to the run function has to be as a final declaration, so how do I get around this?

Upvotes: 1

Views: 2563

Answers (3)

subrunner
subrunner

Reputation: 404

Continued from the comments to the question -- using a timer to wait for a callback result is not recommended.

I assume you are working with a strict Model-View-Controller separation, and that the code you printed is the View part with the callback happening in a separate Controller class.

Now, if it is not a lot of things being added to the panel, I would use following construct:

/*
 * contains all the display parts of the appliation
 */
class View{

  private HorizontalPanel panel = new HorizontalPanel(); // panel as a field

  /*
   * Getter for panel
   */
  public HorizontalPanel getPanel(){
    return this.panel;
  }

  /**
    * Method to create the display part for 'Schools Near Me'
    *
    * @param schoolsNearMeHandler Clickhandler that decides what happens
    *                             when the 'near me' button is clicked
    *                             Contains code to request from server
    *                             and display server result
    */
  public void createSchoolsNearMeSection(ClickHandler schoolsNearMeHandler){
    final Button b = new Button("get schools near me");
    panel.getElement().setId("distanceTable");
    RootPanel.get("core").add(b);
    RootPanel.get("core").add(panel);
    b.addClickHandler(schoolsNearMeHandler);
  }

}

/*
 * Creates and operates the View and makes sure the correct things get displayed
 */
class Controller{

  private View view;

  public Controller(){
     // since the Controller drives the Model-View-Controller part,
     // the view is being created here
     view = new View();

     // TODO more code to set up the view to perfection

     // Create the 'schools near me' section
     view.createSchoolsNearMeSection(new ClickHandler(){
      @Override
      public void onClick(ClickEvent event) {
          loadSchoolsNearMe(); // send request to server
      }
    }
  }

  /**
    * Loads schools near me from the server
    */
  private void loadSchoolsNearMe(){

    // generic callback -- use whatever callback interface is required for your way of requesting data from server
    Callback callback = new Callback(){

      public void onSuccess(ServerResult result){

         // retrieve the panel where you want to display your data
         HorizontalPanel panel = view.getPanel();
         panel.clear();

         // TODO execute whatever code necessary to create
         // widget and widget2 from the ServerResult

         // display the newly generated widgets
         panel.add(widget);
         panel.add(widget2);
      }

      public void onError(...){
         // handle errors
      }

    }

    // Create request
    Request request = new Request(...);

    // Execute request
    RequestBuilder.execute(request, callback);
  }


}

Of course, if there is a lot of complicated code and view-building to be done with the server result, you could once again put the display-part into the View object, keep the logic in the Controller, and just call the corresponding View functions to display whatever necessary.

Upvotes: 1

vvs
vvs

Reputation: 1076

Change final HorizontalPanel panel = new HorizontalPanel(); to a class level attribute. Then it can be easily passed on to the inner anonymous classes. And you can use the clear method inside Timer method as suggested by @philfr49 e.g

private HorizontalPanel panel = new HorizontalPanel();
.....
// Elsewhere
.....
final Button b = new Button("get schools near me");
panel.getElement().setId("distanceTable");
RootPanel.get("core").add(b);
RootPanel.get("core").add(panel);
b.addClickHandler(new ClickHandler(){
    @Override
    public void onClick(ClickEvent event) {
        Timer t = new Timer(){
            @Override
            public void run() {
                panel.clear();
                panel.add(widget);
                panel.add(widget2);
            }
        };
        t.schedule(1400); // wait 1.4 seconds for callback
    }
});

Upvotes: 2

Philippe Gonday
Philippe Gonday

Reputation: 1766

You can use the clear method:

panel.clear();

Upvotes: 2

Related Questions