Multiple Click handlers - gwt

I have different 3 Different Buttons with different onclick events :
add.addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
add();
}
});
set.addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
set();
}
});
get.addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
get();
}
});
So now if i extend this up to 10 Buttons my Script would be far to long,
is there a way to pass the Methode or do seperate the Handlers?

Suppose you have some view:
customview.ui.xml
<g:VerticalPanel>
<style:Button ui:field="addButton" text="Add"/>
<style:Button ui:field="setButton" text="Set"/>
<style:Button ui:field="getButton" text="Get"/>
</g:VerticalPanel>
In your View class define 3 fields and 3 handlers:
CustomView.java
public class CustomView extends ViewWithUiHandlers<CustomUiHandlers>
implements CustomPresenter.MyView {
#UiField
Button addButton;
#UiField
Button setButton;
#UiField
Button getButton;
// Here constructor and other code
#UiHandler("addButton")
void onAddButtonClicked(ClickEvent event) {
if (getUiHandlers() != null) {
getUiHandlers().onAddClicked();
}
}
#UiHandler("setButton")
void onSetButtonClicked(ClickEvent event) {
if (getUiHandlers() != null) {
getUiHandlers().onSetClicked();
}
}
#UiHandler("getButton")
void onGetButtonClicked(ClickEvent event) {
if (getUiHandlers() != null) {
getUiHandlers().onGetClicked();
}
}
}
CustomUiHandlers.java
public interface CustomUiHandlers extends UiHandlers {
void onAddClicked();
void onSetClicked();
void onGetClicked();
}
CustomPresenter.java
public class CustomPresenter extends
Presenter<CustomPresenter.MyView, CustomPresenter.MyProxy>
implements CustomUiHandlers {
// Some code
#Override
public void onAddClicked() {
// Here your code
}
#Override
public void onSetClicked() {
// Here your code
}
#Override
public void onGetClicked() {
// Here your code
}
}

You can bind event handler to a method by UiBinder, or alternatively wait for lambda support for GWT.

Related

How to add ValueChangeHandler to the customize DateBox?

I want to add the functionality of value change handler to my customize class that extends the DateBox. I had already added the key handler but I also want to implement the value change handler to the same class.
I want my DateBox to work properly when I take input from DatePicker or Keyboard.
Any other suggestion will also be helpful.
public class ValidationDateBoxInternal extends DateBox implements KeyUpHandler{
private List<String> regexList;
public ValidationDateBoxInternal(){
super();
this.getTextBox().addKeyUpHandler(this);
regexList = new ArrayList<String>();
}
public void setAsNotEmpty() {
regexList.add(DateValidation.isNotEmpty);
isValid();
}
public void setAsValidDate(){
regexList.add(DateValidation.isValidDate);
isValid();
}
public void onKeyUp(KeyUpEvent event) {
isValid();
}
public void setText(String text) {
super.getTextBox().setText(text);
isValid();
}
public void clearRegexList() {
regexList.clear();
}
public String getText() {
if (regexList.size() == 0) {
return super.getTextBox().getText();
}
if (isValid()) {
for (String regex: regexList) {
if (regex.equals(DateValidation.isValidDate)) {
return super.getTextBox().getText().toLowerCase().trim();
}
}
return super.getTextBox().getText().trim();
}
else {
return null;
}
}
public boolean isValid() {
for (String regex: regexList) {
if (!DateValidation.isValid(super.getTextBox().getText(), regex)) {
this.addStyleName("invalid");
return false;
}
}
this.removeStyleName("invalid");
return true;
}
}
Your class extends DateBox, which implements the HasValueChangeHandlers interface. So you can call:
DateBox.addValueChangeHandler(ValueChangeHandler<java.util.Date> handler)
For example:
public class MyDateBox extends DateBox implements ValueChangeHandler<Date> {
void foo() {
addValueChangeHandler(this);
}
void onValueChange(ValueChangeEvent<Date> event) {
// validate the value of the DateBox
}
}

Paste event on GWT

I found an example of how to catch the Paste event on a TextArea on GWT but it doesn't work.
public MyTextArea() {
super();
sinkEvents(Event.ONPASTE);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE:
System.out.println("Paste Detected");
Window.alert("Paste Works!!! Yippie!!!");
break;
}
}
The problem is that I never enter to onBrowserEvent ... Any suggestion ?
Thnx
Works for me as intended:
public class Starter implements EntryPoint {
#Override
public void onModuleLoad() {
RootPanel.get().add(new MyTextArea());
}
class MyTextArea extends TextArea {
public MyTextArea() {
super();
sinkEvents(Event.ONPASTE);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (event.getTypeInt()) {
case Event.ONPASTE:
System.out.println("Paste Detected");
Window.alert("Paste Works!!! Yippie!!!");
break;
}
}
}
}
On what browser are you testing it?

Activity handlers don't get removed

I'm trying to get up to speed on using GWT Activities and Places. I'm testing with some source code originally found on this good blog post.
I'm finding the Handlers that get added during bind() never seem to removed. My little understanding of the Activity javadoc had me thinking they should get automagically removed by the time the Activity's onStop() method is invoked.
All event handlers it registered will have been removed before this
method is called.
But each time I click a button the corresponding handler is called n+1 times.
What am I missing? Please let me know if there is more info I can provide.
Here's a relevant snippet from the code:
public class ContactsActivity extends AbstractActivity {
private List<ContactDetails> contactDetails;
private final ContactsServiceAsync rpcService;
private final EventBus eventBus;
private final IContactsViewDisplay display;
private PlaceController placeController;
public interface IContactsViewDisplay {
HasClickHandlers getAddButton();
HasClickHandlers getDeleteButton();
HasClickHandlers getList();
void setData(List<String> data);
int getClickedRow(ClickEvent event);
List<Integer> getSelectedRows();
Widget asWidget();
}
public ContactsActivity(ClientFactory factory) {
GWT.log("ContactActivity: constructor");
this.rpcService = factory.getContactServiceRPC();
this.eventBus = factory.getEventBus();
this.display = factory.getContactsView();
this.placeController = factory.getPlaceController();
}
#Override
public void start(AcceptsOneWidget container, EventBus eventBus) {
GWT.log("ContactActivity: start()");
bind();
container.setWidget(display.asWidget());
fetchContactDetails();
}
public void bind() {
GWT.log("ContactActivity: bind()");
display.getAddButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("Add button clicked");
ContactsActivity.this.placeController.goTo(new NewContactPlace(""));
}
});
display.getDeleteButton().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("ContactActivity: Delete button clicked");
deleteSelectedContacts();
}
});
display.getList().addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
GWT.log("ContactActivity: List clicked");
int selectedRow = display.getClickedRow(event);
if (selectedRow >= 0) {
String id = contactDetails.get(selectedRow).getId();
ContactsActivity.this.placeController.goTo(new EditContactPlace(id));
}
}
});
}
Events registered via. the EventBus passed to AbstractActivity#start() will be unregistered by the time onStop() is called. The event handlers registered in the above bind() method, however, are not registered via the EventBus and are not visible to the abstract base class. You need to unregister them yourself:
public class ContactsActivity extends AbstractActivity {
private List<HandlerRegistration> registrations = new ArrayList();
private void bind() {
registrations.add(display.getAddButton().
addClickHandler(new ClickHandler() { ... }));
registrations.add(display.getDeleteButton().
addClickHandler(new ClickHandler() { ... }));
registrations.add(display.getList().
addClickHandler(new ClickHandler() { ... }));
}
#Override
public void onStop() {
for (HandlerRegistration registration : registrations) {
registration.removeHandler();
}
registrations.clear();
}
}
I found it best to handle registration in the view - make it responsible for only keeping one click hander active for each button.
Instead of:
class View {
Button commitButton;
public HasClickHandlers getCommit () {return commitButton;}
}
..and link to this in the Activity:
view.getCommit.addClickHandler(new Clickhandler()...
Do this in the View:
class View {
private Button commitButton;
private HandlerRegistration commitRegistration = null;
public void setCommitHandler (ClickHandler c) {
commitRegistraion != null ? commitRegistration.removeRegistration ();
commitRegistration = commitButton.addClickHandler (c);
}
}
And the Activity:
view.setCommitHandler (new ClickHandler () ...
Hope that helps.

PlaceRequest with parameters to Popup Presenter

I trying to pass a parameter in the placerequest to a presenter that will be a popup, but, the i receive empty parameters in the popup presenter.. am i forgot anything?
AddProjetoPresenter
public class AddProjetoPresenter extends Presenter<AddProjetoPresenter.AddProjetoView, AddProjetoPresenter.AddProjetoProxy>
{
#ProxyCodeSplit
#NameToken(NameTokens.addproj)
public interface AddProjetoProxy extends ProxyPlace<AddProjetoPresenter>
{
}
public interface AddProjetoView extends View
{
HasValue<String> getNome();
HasValue<Date> getDtInicio();
HasValue<Date> getDtFim();
HasClickHandlers getAddRequisitos();
HasClickHandlers getAddStakeholders();
HasClickHandlers getBtCancelar();
HasClickHandlers getBtSalvar();
}
private final DispatchAsync dispatch;
private final PlaceManager placeManager;
private Projeto projeto;
#Inject
public AddProjetoPresenter(final EventBus eventBus, final AddProjetoView view, final AddProjetoProxy proxy, final DispatchAsync dispatch,
final PlaceManager placeManager)
{
super(eventBus, view, proxy);
this.dispatch = dispatch;
this.placeManager = placeManager;
}
#Override
protected void revealInParent()
{
RevealContentEvent.fire(this, MainPresenter.TYPE_SetMainContent, this);
}
#Override
protected void onBind()
{
super.onBind();
getView().getBtSalvar().addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
}
});
getView().getAddRequisitos().addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
PlaceRequest pr = new PlaceRequest(NameTokens.addreq);
pr.with("oi", "oiiiii"); // HERE
placeManager.revealPlace(pr, false);
}
});
}
}
AddRequisitoPresenter
public class AddRequisitoPresenter extends Presenter<AddRequisitoPresenter.AddRequisitoView, AddRequisitoPresenter.AddRequisitoProxy>
{
#ProxyCodeSplit
#NameToken(NameTokens.addreq)
public interface AddRequisitoProxy extends ProxyPlace<AddRequisitoPresenter>
{
}
public interface AddRequisitoView extends PopupView
{
DialogBox getDialog();
}
private final DispatchAsync dispatcher;
private Projeto projeto;
#Inject
public AddRequisitoPresenter(final EventBus eventBus, final AddRequisitoView view, final AddRequisitoProxy proxy, final DispatchAsync dispatcher)
{
super(eventBus, view, proxy);
this.dispatcher = dispatcher;
}
#Override
public void prepareFromRequest(PlaceRequest request)
{
super.prepareFromRequest(request);
getView().getDialog().setText(request.getParameterNames().size() + ""); //SIZE IS ZERO!!
}
#Override
protected void onBind()
{
super.onBind();
}
#Override
protected void revealInParent()
{
RevealRootPopupContentEvent.fire(this, this);
}
}
I think ai doing something wrong...
thanks in advance.
From what I understood in the wiki, a popup can't be a place, and it needs a parent presenter.
I see two obvious problems here :
Your second presenter (the popup) should implement PresenterWidget, not Presenter
You can't display a popup by calling placeManager.revealPlace(), because a popup is not a place. Instead, you have to apply one of the two methods explained in the wiki (addToPopupSlot() or RevealRootPopupContentEvent.fire(), both called from the parent).

Register KeyDownHandler on GWT VerticalPanel

I have a gwt VerticalPanel class that i need to handel KeyDown events for it.
the method i used to implement keyboard handler in my class is:
i add :
this.sinkEvents(Event.ONKEYDOWN);
to constructor
then i override method onBrowserEvent() to handle key down event.
#Override
public void onBrowserEvent(Event event) {
// TODO Auto-generated method stub
super.onBrowserEvent(event);
int type = DOM.eventGetType(event);
switch (type) {
case Event.ONKEYDOWN:
//call method to handle this keydown event
onKeyDownEvent(event);
break;
default:
return;
}
}
however this method doesn’t work for this VerticalPanel class.no KeyDown Event is fired when i press a key!
there are specific gwt widgets that support KeyDownHandler like Button etc..VerticalPanel is not one of them..so we need a work around to register a KeyDownHandler on a class extending VerticalPanel.
can you suggest an idea or hint?
thanks
You could create a Composite that wrappes a FocusPanel and a VerticalPanel. This way you can catch all key events provided the FocusPanel is focused. Simply delegate the needed methods to the panels:
public void onModuleLoad() {
ExtendedVerticalPanel panel = new ExtendedVerticalPanel();
panel.add(new Label("some content"));
panel.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
Window.alert("enter hit");
}
}
});
RootPanel.get().add(panel);
}
private class ExtendedVerticalPanel extends Composite implements HasWidgets, HasAllKeyHandlers {
private VerticalPanel fVerticalPanel;
private FocusPanel fFocusPanel;
public ExtendedVerticalPanel() {
fVerticalPanel = new VerticalPanel();
fFocusPanel = new FocusPanel();
fFocusPanel.setWidget(fVerticalPanel);
initWidget(fFocusPanel);
}
#Override
public void add(Widget w) {
fVerticalPanel.add(w);
}
#Override
public void clear() {
fVerticalPanel.clear();
}
#Override
public Iterator<Widget> iterator() {
return fVerticalPanel.iterator();
}
#Override
public boolean remove(Widget w) {
return fVerticalPanel.remove(w);
}
#Override
public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
return fFocusPanel.addKeyUpHandler(handler);
}
#Override
public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
return fFocusPanel.addKeyDownHandler(handler);
}
#Override
public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
return fFocusPanel.addKeyPressHandler(handler);
}
}
UPDATE
Your question on how to prevent the browser from scrolling when the arrow keys are pressed. Here a small example that works for me:
public void onModuleLoad() {
ExtendedVerticalPanel panel = new ExtendedVerticalPanel();
// make panel reeeeaally big
panel.setHeight("3000px");
panel.add(new TextBox());
panel.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_DOWN) {
Window.alert("down hit");
event.preventDefault();
}
}
});
RootPanel.get().add(panel);
}
Add the handlers you need and call preventDefault() on the events the browser must not take care of.