0
votes

I want to create a GWT widget that has a rectangle div element (looks like a button) along with some text to the right of that. I want to be able to select this widget so that when I click on either the div/button or the text, the entire widget is selected.

Any suggestions on implementing this? If there was an easy way to nest multiple items, like a Button and a Label, inside of a GWT Button, that would probably work. I am thinking of creating a class that extends Composite and holds a Button and a Label, but I am not sure how to make both of those be selected when my entire new widget is selected.

1

1 Answers

1
votes

Do you know how to draw what you are trying to make in plain HTML?

If so, you can simply subclass Widget, and create the elements required, along with the specific styling - there is no need to build multiple other widgets. Then, just add a click handler on your new widget, and you'll know when anyone clicks on any of the content inside the widget.


Likewise, if you use a HTMLPanel (wrapped, as you say, in a Composite) or something to contain both a Label and a Button, you could add a click handler to the panel, and you would know when either of the other widgets were clicked on, since the click event will "bubble" - if nothing prevents it, it will keep firing on each element, then its parent, so that everything knows about the click. However, nesting widgets will make your new widget somewhat more expensive to create than simple creating the HTML, so be sure this is what you would prefer to do.


In either case, you'll use Widget.addDomHandler(...) to actually add the click handler. To make life easier, you can create a new method, implementing HasClickHandlers, and declaring the new method like this:

@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
  return addDomHandler(handler, ClickEvent.getType());
}

As requested, a very short (more comments than code) example widget that seems to do what is described:

public class ButtonWithText extends Widget implements HasClickHandlers {
  public ButtonWithText(String text, String buttonLabel) {
    // Start with a <div></div> wrapper
    setElement(Document.get().createDivElement());
    // Insert a <span> for the text, allowing us to change the text later
    Element textElement = Document.get().createSpanElement();
    textElement.setInnerText(text);

    // Create a button element as well
    Element buttonElement = Document.get().createButtonElement();
    buttonElement.setInnerText(buttonLabel);

    // Attach both to the div we already created
    getElement().appendChild(textElement);
    getElement().appendChild(buttonElement);

    // Note that we could have done all of the above with SafeHtmlTemplate
    // to let us write a string, or could do the escaping ourselves and just
    // make a simple HTML string in code. I find making DOM elements like
    // this easier to read, but many people prefer the template approach.
    // When considering a template tool, also look into the new library
    // Elemento to see what it offers.
  }

  @Override
  public HandlerRegistration addClickHandler(ClickHandler handler) {
    return addDomHandler(handler, ClickEvent.getType());
  }

}

Here is the project, running for you to see it https://viola.colinalworth.com/proj/54177c9456d1c4f777d17dc660005643/project/client/SampleEntryPoint.java - you can click either on the text, or on the button, and the popup appears as expected.