Комплексные идентификаторы GWT CellTable и ListBoxes - PullRequest
4 голосов
/ 12 марта 2012

Я следую примеру Гулге о том, как добавить ListBoxes / SelectionCells в CellTable, но я не могу понять, как изменить поведение, чтобы сопоставление не выполнялось с отображаемым строковым значением.

Элементы, которые я отображаю @SelectionCell, не являются уникальными (то есть может быть 2 элемента с одинаковым именем), поэтому мне нужно использовать другие поля, связанные с объектом, чтобы узнать, какой из них был выбран

for (IrrigationProgramDTO program: programOptions)    
 categoryNames.add(program.getName());

SelectionCell categoryCell = new SelectionCell(categoryNames);
Column<IrrigationGapDTO, String> categoryColumn = new Column<IrrigationGapDTO, String>    (categoryCell) {
      @Override
      public String getValue(IrrigationGapDTO object) {
          if (object.getProgramSelected()!=null)
              return object.getProgramSelected().getName();
          else
              return "";
      }
    };      
    categoryColumn.setFieldUpdater(new FieldUpdater<IrrigationGapDTO, String>() {
      public void update(int index, IrrigationGapDTO object, String value) {
          for (IrrigationProgramDTO program: programOptions) {
                  //not valid as there could be more than 1 program with the same name
              if (program.getName().equals(value)) { 
                  object.setProgramSelected(program);
                  break;
              }

          }  
      }

Ответы [ 3 ]

2 голосов
/ 31 января 2013

Вот моя новая реализация решения # 3 (обратите внимание, что необходимо добавить FieldUpdater в столбец, чтобы он работал):

import java.util.Arrays;
import java.util.List;

import com.google.gwt.cell.client.AbstractEditableCell;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.BrowserEvents;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.SelectElement;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.client.SafeHtmlTemplates.Template;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;

/**
 * A {@link Cell} used to render a drop-down list.
 *
 * @author Gaspard van Koningsveld
 */
public class ItemSelectionCell<C> extends AbstractEditableCell<C, C> {

    interface Template extends SafeHtmlTemplates {
        @Template("<select tabindex=\"-1\" style=\"width:100%\">")
        SafeHtml beginSelect();

        @Template("<option value=\"{0}\">{1}</option>")
        SafeHtml deselected(int hash, String option);

        @Template("<option value=\"{0}\" selected=\"selected\">{1}</option>")
        SafeHtml selected(int hash, String option);

        @Template("</select>")
        SafeHtml endSelect();
    }

    private static Template template;

    private List<C> items;

    public ItemSelectionCell(C itemsArray[]) {
        this(Arrays.asList(itemsArray));
    }

    public ItemSelectionCell(List<C> items) {
        super(BrowserEvents.CHANGE);
        if (template == null) {
            template = GWT.create(Template.class);
        }
        this.items = items;
    }

    @Override
    public void onBrowserEvent(Context context, Element parent, C value, NativeEvent event, ValueUpdater<C> valueUpdater) {
        super.onBrowserEvent(context, parent, value, event, valueUpdater);
        if (BrowserEvents.CHANGE.equals(event.getType())) {
            SelectElement select = parent.getFirstChild().cast();
            int newIndex = select.getSelectedIndex();
            valueUpdater.update(items.get(newIndex));
        }
    }

    @Override
    public void render(Context context, C value, SafeHtmlBuilder sb) {
        sb.append(template.beginSelect());
        for (int i = 0; i < items.size(); i++) {
            C item = items.get(i);
            if (item.equals(value)) {
                sb.append(template.selected(i, getItemDisplayString(item)));
            } else {
                sb.append(template.deselected(i, getItemDisplayString(item)));
            }
        }
        sb.append(template.endSelect());
    }

    public String getItemDisplayString(C item) {
        return item.toString();
    }

    public List<C> getItems() {
        return items;
    }

    public void setItems(List<C> items) {
        this.items = items;
    }

    @Override
    public boolean isEditing(Context context, Element parent, C value) {
        return false;
    }
}
1 голос
/ 12 марта 2012

3 возможных решения:

1. Грязный обходной путь :

Вместо getName() вернуть getName() + некоторый уникальный идентификатор:

public String getValue(IrrigationGapDTO object) {
    if (object.getProgramSelected()!=null)
        return object.getProgramSelected().getName()+"_"+object.getUniqueIdentiufier();
    else
        return "";
}

, затем в FieldUpdater вы можете разделить символ "_" и обработать дубликаты

2. Используйте уникальный идентификатор вместо getName(): Просто сгенерируйте / назначьте уникальный идентификатор вашим программам и используйте его вместо имени.

3. Используйте IrrigationProgramDTO тип вместо String:

Вместо String вы можете использовать класс IrrigationProgramDTO в определении столбца. Однако вам, вероятно, придется использовать определяемый пользователем объект SelectionCell, который принимает тип IrrigationProgramDTO вместо String в качестве типа данных.

Column<IrrigationGapDTO, IrrigationProgramDTO> categoryColumn = new Column<IrrigationGapDTO, IrrigationProgramDTO>    (categoryCell) {
  @Override
  public IrrigationProgramDTO (IrrigationGapDTO object) {
      if (object.getProgramSelected()!=null)
          return object.getProgramSelected();
      else
          return null;
  }

};      
categoryColumn.setFieldUpdater(new FieldUpdater<IrrigationGapDTO, IrrigationProgramDTO>() {
  public void update(int index, IrrigationGapDTO object, IrrigationProgramDTO value) {
       object.setProgramSelected(program);
      }  
  }
0 голосов
/ 30 января 2013

Вот моя реализация Решения № 3 @ Ümit:

public static abstract class EditSelectColumn<E, S> {

    Map<String, S> selectionMap = new HashMap<String, S>();

    EditColumn<E> column;

    protected final String relationshipFieldName;

    public EditSelectColumn(String relationshipFieldName) {
        this.relationshipFieldName = relationshipFieldName;

        for (S option : getOptions()) {
            assert getOptionString(option) != null : "Option string cannot be null, please check your database";
            selectionMap.put(getOptionString(option), option);
        }
        SelectionCell cell = new SelectionCell(new ArrayList<String>(selectionMap.keySet()));
        column = new EditColumn<E>(cell) {
            @Override
            public String getValue(E object) {
                if (getOption(object) == null)
                    return "";
                return getOptionString(getOption(object));
            }

            @Override
            public void setValue(E object, String value) {
                setOption(object, selectionMap.get(value));
            }
        };
    }

    public EditColumn<E> getColumn() {
        return column;
    }

    public abstract List<S> getOptions();

    public abstract String getOptionString(S option);

    public abstract S getOption(E object);

    public abstract void setOption(E object, S value);
}
...