Событие GWT SelectBox ChangeHandler не работает

Образец:

private Widget getSelectBox() {
  HorizontalPanel hPanel = new HorizontalPanel();
  hPanel.setSpacing(20);
  final ListBox dropBox = new ListBox(false);
  String[] listTypes = {"1", "2", "3"};
  for (int i = 0; i < listTypes.length; i++) {
    dropBox.addItem(listTypes[i]);
  }
  dropBox.ensureDebugId("cwListBox-dropBox");
  dropBox.getElement().setId("cms-dropBox");
  VerticalPanel dropBoxPanel = new VerticalPanel();
  dropBoxPanel.setSpacing(4);
  dropBoxPanel.add(dropBox);
  hPanel.add(dropBoxPanel);
  dropBox.addChangeHandler(new ChangeHandler() {
    public void onChange(ChangeEvent event) {
      Window.alert("change fired");
      dropBox.addItem("else");
      consoleLog("selected: "+ dropBox.getSelectedIndex());
    }
  });  
  return hPanel;
}

ChangeHandler не работает. Хотя в официальном примере он работает нормально ( http://samples.gwtproject.org/samples/Showcase/Showcase.html). Но это не работает в этом коде. Там нет ошибок.

DOM.sinkEvents((com.google.gwt.user.client.Element) dropBox.getElement(), Event.ONCHANGE );
DOM.setEventListener((com.google.gwt.user.client.Element) dropBox.getElement(), new EventListener() {
    @Override
    public void onBrowserEvent(Event event) {
        if (DOM.eventGetType(event) == Event.ONCHANGE) {
              Window.alert("change fired");
              dropBox.addItem("who");
              consoleLog("selected: "+ dropBox.getSelectedIndex());                                        
        }                                             
    }
}); 

Этот способ не работает ни

upd: все работает в классе MainEntryPoint, но нужен panel.add(новый SomeClass().getWidget()), и это не работает

2 ответа

Решение

Причина неработающего eventListener: невнимательность.

не переопределяйте HTML-содержимое готового DOM, например container.getElement().setInnerHTML(container.getElement().getInnerHTML()+"<div>somehtml</div>"); после добавления любого виджета с помощью EventListener

Итак, вам просто нужно подключить ListBox ChangeEvent из другого класса. Вы можете сделать это разными способами. Вот два простых метода.

Давайте предположим, что ListBox определен в class A и вам нужен обработчик в class B,

  • Первый метод: выставить ListBox из class A и использовать его в class B настроить обработчик.
  • Второй метод: добавить публичный метод в class A который устанавливает обработчик в ListBox, это будет использоваться в class B,

Вам нужно будет передать экземпляр class A конструктору class B,


public class A {
    private ListBox dropBox;

    public A() {
        // constructor - set up dropBox
        ...
    }

    // first method - expose a dropBox
    public ListBox getDropBox() {
        return dropBox;
    }

    // second method - allow external handlers
    public HandlerRegistration addListBoxChangeHandler(ChangeHandler handler) {
        return dropBox.addChangeHandler(handler);
    }
}

public class B {
    private A instanceOfClassA;

    public B(A instanceOfClassA) {
        // constructor
        this.instanceOfClassA = instanceOfClassA;
        ...

        // first method - dropBox is exposed in class A
        instanceOfClassA.getDropBox().addChangeHandler(handler);

        // second method - add external handler
        instanceOfClassA.addListBoxChangeHandler(handler);
    }
}

Второй способ более элегантный.

Другие вопросы по тегам