【问题标题】:GWT Different column types in same column?GWT 同一列中的不同列类型?
【发布时间】:2011-05-09 14:02:45
【问题描述】:
我正在开发一个 GWT 应用程序,到目前为止,我喜欢 Java 开发人员友好的 UI 框架!
到目前为止,我几乎可以用这些小部件做任何事情,但这个让我很困惑。我有一个单元格表,用作用户输入源。它只是用户输入键值对来调用我的服务的一种方式。用户可以动态添加行和删除行。
现在棘手的部分是我想强制用户为某些键输入值。这些键只有 4-5 个可接受的值,因此对于这些行,我想用 selectionCell 替换 editableTextCell。不确定如何在表格中混合单元格类型,因为列单元格类型声明是在将列添加到表格时完成的。
感谢任何输入!
谢谢
【问题讨论】:
标签:
gwt
gwt-2.2-celltable
【解决方案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);
}
}
}
(未经测试的代码)
【解决方案2】:
非常有用。这是我对有条件渲染的CheckboxCell
的看法
导入 com.google.gwt.cell.client.AbstractCell;
导入 com.google.gwt.cell.client.CheckboxCell;
导入 com.google.gwt.cell.client.ValueUpdater;
导入 com.google.gwt.dom.client.Element;
导入 com.google.gwt.dom.client.EventTarget;
导入 com.google.gwt.dom.client.NativeEvent;
导入 com.google.gwt.safehtml.shared.SafeHtmlBuilder;
/**
*
CheckboxCell 如果封闭列的,则有条件地呈现
* Boolean com.google.gwt.user.cellview.client.Column.getValue(T object) 方法返回 true。
*/
公共类 ConditionallyRenderedCheckboxCell 扩展 AbstractCell {
公共 ConditionallyRenderedCheckboxCell() {
//我们处理和CheckboxCell一样的事件
超级(“改变”,“keydown”);
}
私人 CheckboxCell 单元格 = null;
@覆盖
公共无效渲染(上下文上下文,布尔renderCheckboxCell,SafeHtmlBuilder sb){
if (renderCheckboxCell) {
this.cell = new CheckboxCell(false,true);
//使复选框单元格未选中
this.cell.render(上下文,假,某人);
}
}
@覆盖
公共无效 onBrowserEvent(com.google.gwt.cell.client.Cell.Context 上下文,
元素父级、布尔值、NativeEvent 事件、
值更新器值更新器){
//如果我们创建了一个复选框单元格,则进行事件处理,否则,忽略它。
如果(this.cell!= null){
super.onBrowserEvent(context, parent, value, event, valueUpdater);
// 处理更改事件。
if ("change".equals(event.getType())) {
// 忽略最外层元素之外发生的事件。
EventTarget eventTarget = event.getEventTarget();
if (parent.isOrHasChild(Element.as(eventTarget))) {
// 使用它来获取选中的元素!!
元素 el = Element.as(eventTarget);
//检查我们是否真的点击了复选框
if (el.getNodeName().equalsIgnoreCase("input") && el.getPropertyString("type").equalsIgnoreCase("checkbox")) {
//如果定义了值更新器,则调用它
如果(valueUpdater != null)
valueUpdater.update(el.getPropertyBoolean("checked"));
}
}
}
}
}
}
【解决方案3】:
稍后再回答,但无论如何。几天前,一个人也面临着这个任务——文本或组合框必须在一列中用于单元格编辑。这是我的实现:
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);
}
这是一种解决方法,不是优雅的实现,但无论如何,它都可以正常工作