GWT 同一列中有不同的列类型?

发布于 2024-11-05 18:57:01 字数 321 浏览 0 评论 0原文

我正在开发一个 GWT 应用程序,到目前为止,我很喜欢 Java 开发人员友好的 UI 框架!

到目前为止,我已经能够使用这些小部件做几乎任何事情,但是这个让我难住了。我有一个单元格表,用作用户输入源。它只是用户输入键值对来调用我的服务的一种方式。用户可以动态添加行和删除行。

现在棘手的部分是我想强制用户输入某些键的值。这些键只有特定的 4-5 个可接受的值,因此对于这些行,我想将 editableTextCell 替换为 SelectionCell。考虑到列单元格类型声明是在将列添加到表中时完成的,不确定如何在表中混合单元格类型。

任何意见表示赞赏!

谢谢

I'm working on a GWT app, and so far I'm loving the Java developer friendly UI framework!

So far I've been able to do pretty much anything with the widgets, but this one has me stumped. I have a cell table, that I use as a user input source. Its just a way for users to enter key-value pairs to call my service. User can dynamically add rows and delete rows.

Now the tricky part is I want to force the user to enter value for some keys. There are only certain 4-5 acceptable values for these keys so for those rows I would like to replace the editableTextCell with a selectionCell. Not sure how I can mix cell types within a table, given that the column cell type declaration is done while adding the column to the table.

Any input is appreciated!

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

偏爱你一生 2024-11-12 18:57:01

您必须创建一个自定义单元格,有时会呈现 。如果您查看 EditableTextCell 和 SelectionCell 的代码,您可以了解如何实现这一目标。它可能非常简单 - 您可以编写其中的一个,然后在您的渲染函数中将数据传递到适当的单元格。

类似...

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);
        }
     }
}

(未经测试的代码)

You'll have to create a custom Cell that sometimes renders a <select> and sometimes renders an <input>. If you look at the code of EditableTextCell and SelectionCell you can get ideas about how to accomplish that. It may be pretty simple - you could compose one of each, and in your render function just pass the data to the appropriate cell.

Something like...

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);
        }
     }
}

(untested code)

想你只要分分秒秒 2024-11-12 18:57:01

非常有用。这是我对条件渲染的 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.
     */
    public class ConditionallyRenderedCheckboxCell extends AbstractCell {

        public ConditionallyRenderedCheckboxCell() {
        //We handle the same events as CheckboxCell
        super("change", "keydown");
        }

        private CheckboxCell cell = null;

        @Override
        public void render(Context context, Boolean renderCheckboxCell, SafeHtmlBuilder sb) {
            if (renderCheckboxCell) {            
                this.cell = new CheckboxCell(false,true);  
                //Render the checkbox cell unchecked
                this.cell.render(context, false, sb);
            }
         }

        @Override
        public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context,
            Element parent, Boolean value, NativeEvent event,
            ValueUpdater valueUpdater) {

        //If we have created a checkbox cell, do event handling, otherwise, ignore it.
        if( this.cell != null ){
            super.onBrowserEvent(context, parent, value, event, valueUpdater);

            // Handle the change event.
            if ("change".equals(event.getType())) {

            // Ignore events that occur outside of the outermost element.
            EventTarget eventTarget = event.getEventTarget();

            if (parent.isOrHasChild(Element.as(eventTarget))) {

                // Use this to get the selected element!!
                Element el = Element.as(eventTarget);

                //Check if we really clicked on the checkbox
                if (el.getNodeName().equalsIgnoreCase("input") && el.getPropertyString("type").equalsIgnoreCase("checkbox")) {

                //If an value updater was defined, invoke it
                if(valueUpdater != null)
                    valueUpdater.update(el.getPropertyBoolean("checked"));          
                }
            }
            }
        }
        }        
    }

Very useful. Here is my take on a conditionally rendered 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.
     */
    public class ConditionallyRenderedCheckboxCell extends AbstractCell {

        public ConditionallyRenderedCheckboxCell() {
        //We handle the same events as CheckboxCell
        super("change", "keydown");
        }

        private CheckboxCell cell = null;

        @Override
        public void render(Context context, Boolean renderCheckboxCell, SafeHtmlBuilder sb) {
            if (renderCheckboxCell) {            
                this.cell = new CheckboxCell(false,true);  
                //Render the checkbox cell unchecked
                this.cell.render(context, false, sb);
            }
         }

        @Override
        public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context,
            Element parent, Boolean value, NativeEvent event,
            ValueUpdater valueUpdater) {

        //If we have created a checkbox cell, do event handling, otherwise, ignore it.
        if( this.cell != null ){
            super.onBrowserEvent(context, parent, value, event, valueUpdater);

            // Handle the change event.
            if ("change".equals(event.getType())) {

            // Ignore events that occur outside of the outermost element.
            EventTarget eventTarget = event.getEventTarget();

            if (parent.isOrHasChild(Element.as(eventTarget))) {

                // Use this to get the selected element!!
                Element el = Element.as(eventTarget);

                //Check if we really clicked on the checkbox
                if (el.getNodeName().equalsIgnoreCase("input") && el.getPropertyString("type").equalsIgnoreCase("checkbox")) {

                //If an value updater was defined, invoke it
                if(valueUpdater != null)
                    valueUpdater.update(el.getPropertyBoolean("checked"));          
                }
            }
            }
        }
        }        
    }

岁月打碎记忆 2024-11-12 18:57:01

稍后回答,但无论如何。几天前,也面临着这个任务 - 必须在一列中使用文本或组合框进行单元格编辑。这是我的实现:

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);
    }

这是相当解决方法,不是优雅的实现,但无论如何,它工作得很好

A little bit later answer, but any way. Few days ago a faced this task also - text or combo boxes has to be used in one column for cell editing. Here are my implementation:

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

And custom GridInlineEditing implementation is as this:

/**
 * 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);
    }

It is rather workaround, not elegant implementation, but any way, it works fine

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文