Using Something Other Than HasClickHandlers in my GWT MVP
I am facing a similar issue to the problem faced by the similar StackOverflow question Way to specify multiple interfaces in Java but as it specifically applies to the GWT MVP example framework presented in http://code.google.com/webtoolkit/articles/mvp-architecture.html.
In this example, in the /Contacts/src/com/google/gwt/sample/contacts/client/presenter/ContactsPresenter.java file, the interface Display contains the following methods:
public interface Display
{
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getList();
...
}
Instead of these buttons, I would like to make a getSuggestBox() method here. In the bind() method in my Presenter file, I would like to invoke
getSuggestBox().addKeyDownHandler({...})
and
getSuggestBox().addSelectionHandler({...})
and create handlers for these.
To do this, my first solution was to create a HasSearchHandlers interface that looks like this:
public interface HasSearchHandlers extends HasKeyDownHandlers,
HasSelectionHandlers<SuggestOracle.Suggestion>{}
and then to try to use the method
HasSearchHandlers getSuggestBox()
This, however, has failed so far. I can't use polymorphism and say
private HasSearchHandlers box = new SuggestBox()
in my version of the ContactsView file to implement getSuggestBox(), and I can't cast a SuggestBox into a HasSearchHandlers either -- I get a ClassCastException. The JRE knows that HasSearchHandlers is an empty interface, so I don't get why SuggestBox has to explicitly implement HasSearchHandlers for this casting to work. The class SuggestBox implements everything present in the HasSearchHandlers interface; isn't this enough?开发者_运维知识库
The generic interface presented as the alternative in the first link in this post has given me similar difficulty, since it does the same thing without calling it "HasSearchHandlers". In light of this problem, what is the best design step to take? How should I implement and create a "getSuggestBox() - like" mechanism in the GWT MVP framework?
You could define getSuggestBox
as a generic method:
<T extends HasKeyDownHandlers, HasSelectionHandlers<SuggestOracle.Suggestion>> T getSuggestBox();
(with the T
being actually declared on the view interface, not on the method)
Which your view will implement using SuggestBox
for the T
. You unit tests would instead use a mock such as your HasSearchHandlers
. Your presenter would have to use the view interface with a ?
generic parameter.
(honestly, as I'm writing this, I'm not sure it'd work, but my main point is below, so...)
But, I'd rather recommend following the approach of the "Part II" article, where the view itself attaches the event handlers and delegates them to an interface implemented by the presenter. It makes the code easier to read and maintain (particularly with those cases where you want to expose the same component through several interfaces, but also because you have less anonymous handlers in your presenter, where the most important part of your code lives), makes it possible to use @UiHandler
in the view to bind the events (even less anonymous classes), and maybe even more importantly makes unit-testing much much easier! (you no longer need to mock HasXxxHandlers
interface that remember the values passed to their methods, and mock the returned HandlerRegistration
s, etc.)
The class SuggestBox implements everything present in the HasSearchHandlers interface; isn't this enough?
No, not enough, the class SuggestBox has to implement the HasSearchHandlers
interface itself (which it obviously doesn't).
In light of this problem, what is the best design step to take?
You can do two things -
1) Use (modify ur code) whatever interfaces are provided by the suggest box.
2) Create your own widget which extends the suggest box and implements your handlers.
I would go with number 1 as I don't believe you want to extend the suggest boxes functionality any further.
精彩评论