Reputation: 388
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
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
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