События нескольких ячеек в одном столбце

У меня есть две кнопки (редактировать + удалить) в одном столбце.

    ButtonCell functionButtonCell = new ButtonCell() {
    @Override
    public void render(final Context context, final SafeHtml data, final SafeHtmlBuilder sb) {
        sb.appendHtmlConstant("<button type='button' class='gwt-Button' style = 'width:60px;margin:1px;'>Edit</button>");
        sb.appendHtmlConstant("<br/>");
        sb.appendHtmlConstant("<button type='button' class='gwt-Button' style = 'width:60px;margin:1px;'>Delete</button>");
        }
    };
    functionColumn = new Column<AdminModel, String>(functionButtonCell) {
        public String getValue(final AdminModel object) {
            return object.getSeq().toString();
        }
    };

Привязать событие для этого столбца в Presenter как

.........
view.getFunctionColumn().setFieldUpdater(new FieldUpdater<AdminModel, String>() {

   public void update(final int index, final AdminModel object, final String value) {
            Window.alert(index + "-" + value);
        }
    });

После нажатия на кнопку редактирования появилось окно с предупреждением, но не на кнопке удаления. Когда я нажал кнопку удаления, ничего не появилось. В чем проблема?

Дополнение: Как определить, какая кнопка была нажата пользователем (изменить или удалить) в моем докладчике?

Я был бы очень признателен за любые ваши предложения, потому что я давно беспокоюсь об этом. Спасибо!


person Cataclysm    schedule 09.06.2014    source источник


Ответы (2)


ButtonCell фильтрует события только для первого дочернего элемента: https://gwt.googlesource.com/gwt/+/2.6.1/user/src/com/google/gwt/cell/client/ButtonCell.java. Вот почему вы не получать событие при нажатии второй кнопки (примечание: цель этого кода — убедиться, что вы нажали на кнопку, а не на пустое место вокруг кнопки; см. https://gwt.googlesource.com/gwt/+/a0dc88c8be7408be9554f746eb1ec93798183a28)

Самый простой способ реализовать ячейку с двумя кнопками — использовать CompositeCell; для этого требуется, чтобы дочерние ячейки отображались в одноуровневые элементы (по умолчанию используются <span>s, пример ниже переопределяет рендеринг для использования <div>s, поэтому ваши кнопки складываются каждая в отдельной строке).

new CompositeCell<AdminModel>(Arrays.asList(
  // First button
  new HasCell<AdminModel, String>() {
    @Override public Cell<String> getCell() { return new ButtonCell(); }
    @Override public FieldUpdated<AdminModel, String> getFieldUpdater() {
      return new FieldUpdater<AdminModel, String>() {
        @Override public void update(int index, AdminModel object, String value) {
          Window.alert("Edit " + object.getId());
        }
      };
    }
    @Override public String getValue(AdminModel o) {
      return "Edit";
    }
  },
  // Second button
  new HasCell<AdminModel, String>() {
    @Override public Cell<String> getCell() { return new ButtonCell(); }
    @Override public FieldUpdated<AdminModel, String> getFieldUpdater() {
      return new FieldUpdater<AdminModel, String>() {
        @Override public void update(int index, AdminModel object, String value) {
          Window.alert("Delete " + object.getId());
        }
      };
    }
    @Override public String getValue(AdminModel o) {
      return "Delete";
    }
  }) {
  @Override protected <X> void render(Cell.Context context, AdminModel value, SafeHtmlBuilder sb, HasCell<String,X> hasCell) {
    // use a <div> instead of the default <span>
    Cell<X> cell = hasCell.getCell();
    sb.appendHtmlConstant("<div>");
    cell.render(context, hasCell.getValue(value), sb);
    sb.appendHtmlConstant("</div>");
  }
};

(примечание: в вашем случае, поскольку текст кнопки не зависит от объекта строки, возможно, вам следует использовать ActionCell; он лучше «семантически» соответствовал бы тому, что вы делаете, но в остальном это почти то же самое, с ActionCell, вы бы использовали HasCell<AdminModel, AdminModel>, ActionCell<AdminModel>, getFieldUpdater, чтобы вернуть аргумент null, and thegetValueof theHasCellwould just return theAdminModel` как есть).

В противном случае реализуйте свой Cell (или AbstractCell) полностью самостоятельно.

person Thomas Broyer    schedule 09.06.2014

В идеале столбец должен иметь только один тип ячеек, будь то ImageCell, ButtonCell и т. д. Потому что все эти ImageCell и ButtonCell не обеспечивают никаких встроенных событий. События обрабатываются самим FieldUpdater, у которого нет дифференциаторов для идентификации того, по которому щелкнули ButtonCell. В идеале при щелчке по этому столбцу будет вызываться средство обновления полей.

Вам лучше создать свой собственный составной виджет, который расширяет HasCell. Этот составной виджет будет иметь две разные кнопки, а встроенные методы вызываются при нажатии соответствующей кнопки.

public void onModuleLoad() {
    CellTable<Person> table = new CellTable<Person>();

    List<HasCell<Person, ?>> cells = new LinkedList<HasCell<Person, ?>>();
    cells.add(new ActionHasCell("Edit", new Delegate<Person>() {

        @Override
        public void execute(Person object) {
           // EDIT CODE
        }
    }));
    cells.add(new ActionHasCell("Delete", new Delegate<Person>() {

        @Override
        public void execute(Person object) {
            // DELETE CODE
        }
    }));

    CompositeCell<Person> cell = new CompositeCell<Person>(cells);
    table.addColumn(new TextColumn<Person>() {

        @Override
        public String getValue(Person object) {
            return object.getName()
        }
    }, "Name");

    // ADD Cells for Age and Address

    table.addColumn(new Column<Person, Person>(cell) {

        @Override
        public Person getValue(Person object) {
            return object;
        }
    }, "Actions");


}

private class ActionHasCell implements HasCell<Person, Person> {
    private ActionCell<Person> cell;

    public ActionHasCell(String text, Delegate<Person> delegate) {
        cell = new ActionCell<Person>(text, delegate);
    }

    @Override
    public Cell<Person> getCell() {
        return cell;
    }

    @Override
    public FieldUpdater<Person, Person> getFieldUpdater() {
        return null;
    }

    @Override
    public Person getValue(Person object) {
        return object;
    }
}

Также смотрите ссылку ниже. [GWT CellTable-Необходимо иметь две кнопки в последней отдельной ячейке каждой строки

person PVR    schedule 09.06.2014
comment
Спасибо за ваш ответ, сэр! И... пожалуйста, поддержите меня в использовании. Мне нужно создать новый составной класс? Как добавить это в таблицу ячеек? - person Cataclysm; 09.06.2014
comment
@Cataclysm: ActionHasCell — это составной виджет, созданный и используемый в onModuleLoad() для CellTable. Попытайтесь понять представленную реализацию. - person PVR; 09.06.2014
comment
Пожалуйста, не обращайте внимания, сэр, я еще не поймал. Я все еще новичок в GWT. Итак, я хотел бы знать, как создать мою колонку с составным классом, который вы описали. Спасибо. - person Cataclysm; 09.06.2014