Есть ли разные типы столбцов в одном столбце?

#gwt #gwt-2.2-celltable

#gwt #gwt-2.2-таблица ячеек

Вопрос:

Я работаю над приложением GWT, и пока мне нравится платформа пользовательского интерфейса, удобная для разработчиков Java!

До сих пор мне удавалось делать с виджетами практически все, что угодно, но этот вариант поставил меня в тупик. У меня есть таблица ячеек, которую я использую в качестве источника пользовательского ввода. Это просто способ для пользователей вводить пары ключ-значение для вызова моей службы. Пользователь может динамически добавлять строки и удалять строки.

Теперь сложная часть в том, что я хочу заставить пользователя ввести значение для некоторых ключей. Для этих ключей есть только определенные 4-5 допустимых значений, поэтому для этих строк я хотел бы заменить editableTextCell на selectionCell. Не уверен, как я могу смешивать типы ячеек в таблице, учитывая, что объявление типа ячейки столбца выполняется при добавлении столбца в таблицу.

Приветствуется любой вклад!

Спасибо

Ответ №1:

Вам нужно будет создать пользовательскую ячейку, которая иногда отображает <select> , а иногда отображает <input> . Если вы посмотрите на код EditableTextCell и SelectionCell, вы можете получить идеи о том, как этого добиться. Это может быть довольно просто — вы могли бы составить по одному из каждого, и в вашей render функции просто передать данные в соответствующую ячейку.

Что-то вроде…

 public class ChoosyCell extends AbstractCell<YourData> {
    SelectionCell selectCell = new SelectionCell<YourData>();
    EditableTextCell textCell = new EditableTextCell<YourData>();

    public void render(Context context, YourData data, SafeHtmlBuilder sb) {
        if (data.isTheLimitedType()) {
            selectCell.render(context, data, sb);
        } else {
            textCell.render(context,data, sb);
        }
     }
}
  

(непроверенный код)

Комментарии:

1. Интересно, я попробую это, а затем сообщу!

Ответ №2:

Очень полезно. Вот мой взгляд на условно отображаемую CheckboxCell

  
    import com.google.gwt.cell.client.AbstractCell;
    import com.google.gwt.cell.client.CheckboxCell;
    import com.google.gwt.cell.client.ValueUpdater;
    import com.google.gwt.dom.client.Element;
    import com.google.gwt.dom.client.EventTarget;
    import com.google.gwt.dom.client.NativeEvent;
    import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

    /**
     *  CheckboxCell   that is conditionally rendered if the enclosing column's
     * Boolean com.google.gwt.user.cellview.client.Column.getValue(T object)   method returns true  . 
*/ 
 открытый класс ConditionallyRenderedCheckboxCell расширяет AbstractCell {

 public ConditionallyRenderedCheckboxCell() {
 // Мы обрабатываем те же события, что и CheckboxCell 
 супер ("изменить", "нажатие клавиши");
 }

 ячейка private CheckboxCell = null;

 @Переопределение 
 общедоступный пустой рендеринг (контекст context, Boolean renderCheckboxCell, SafeHtmlBuilder sb) { 
 if (renderCheckboxCell) { 
 this.cell = новая ячейка CheckboxCell(false, true); 
 // Снять флажок с ячейки 
 this.cell.render(контекст, false, sb);
 }
 }

 @Переопределение 
 общедоступная пустота на browserevent (com.google.gwt.cell.client.Cell.Контекст context, 
 Родительский элемент, логическое значение, событие nativeEvent, 
 ValueUpdater Обновление значения) {

 // Если мы создали ячейку с флажком, выполните обработку события, в противном случае проигнорируйте его.
 если( this.cell != null ){
 super.onBrowserEvent (контекст, родительский элемент, значение, событие, обновление значения);

 // Обработать событие изменения.
 if ("change".equals(event.GetType())) {

 // Игнорировать события, которые происходят за пределами самого внешнего элемента.
 EventTarget EventTarget = event.getEventTarget();

 если (parent.isOrHasChild(Element.as (EventTarget))) {

 // Используйте это, чтобы получить выбранный элемент!!
 Элемент el = Element.as (EventTarget);

 // Проверьте, действительно ли мы нажали на флажок 
 if (el.getNodeName().equalsIgnoreCase("ввод") amp;amp; el.getPropertyString("тип").equalsIgnoreCase("флажок")) {

 //Если был определен механизм обновления значений, вызовите его 
 if(valueUpdater != null)
 valueUpdater.update(el.getPropertyBoolean("проверено")); 
 }
 }
 }
 }
 } 
 }

Ответ №3:

Ответ чуть позже, но в любом случае. Несколько дней назад a также столкнулся с этой задачей - текст или поля со списком должны использоваться в одном столбце для редактирования ячеек. Вот моя реализация:

 final GridInlineEditingTextOrCombo editing = new GridInlineEditingTextOrCombo(attributeTableGrid);
    editing.addEditor(valueCol);
  

И пользовательская реализация GridInlineEditing выглядит следующим образом:

 /**
 * Class intended to create GridInlineEditing functionality,
 * but with two type of editors in one column - TextField or SimpleComboBox,
 * depending of SnmpParameterDefDTO.getAllowedValues().
 */
class GridInlineEditingTextOrCombo extends GridInlineEditing<SnmpParameterDefDTO> {
    IsField<String> textField = new TextField();
    SimpleComboBox<String> simpleComboBox = new SimpleComboBox<String>(new StringLabelProvider<String>());
    Grid.GridCell currentCell = null;
    private boolean currentCellChanged = false;
    IsField<String> currentCellEditor;
    //ComboBox<String> comboBox = new ComboBox<String>();

    public GridInlineEditingTextOrCombo(Grid<SnmpParameterDefDTO> editableGrid) {
    super(editableGrid);
    simpleComboBox.setEditable(false);
    simpleComboBox.setAllowTextSelection(false);
    simpleComboBox.setTriggerAction(ComboBoxCell.TriggerAction.ALL);
    }

    @Override
    @SuppressWarnings("unchecked")
    public <O> IsField<O> getEditor(ColumnConfig<SnmpParameterDefDTO, ?> columnConfig) {
    IsField<O> field = super.getEditor(columnConfig);
    if(field!=null ){
        if(!currentCellChanged){
        return (IsField<O>)currentCellEditor;
        }else{
        currentCellChanged = false;
        SnmpParameterDefDTO param = this.editableGrid.getStore().get(this.currentCell.getRow());
        if(param.getAllowedValues() == null || param.getAllowedValues().size() == 0){
            currentCellEditor = (IsField<String>)field;
        }else{
            simpleComboBox.getStore().clear();
            simpleComboBox.add(param.getAllowedValues());
            currentCellEditor = simpleComboBox;
        }
        return (IsField<O>)currentCellEditor;
        }
    }
    return null;
    }

    @Override
    public <T> void addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig, IsField<T> field) {
    throw new RuntimeException("You can not call this method. Please use addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig) instead");
    }

    public <T> void addEditor(ColumnConfig<SnmpParameterDefDTO, T> columnConfig) {
    super.addEditor(columnConfig, (IsField<T>)textField);
    }

    @Override
    public void startEditing(Grid.GridCell cell){
    currentCell = cell;
    currentCellChanged = true;
    super.startEditing(cell);
    }
  

Это скорее обходной путь, а не элегантная реализация, но в любом случае, он работает нормально