如何允许单项/子编辑器GET编辑器从包含它的列表编辑器中删除自身?例如点击删除按钮

时间:2015-04-18 17:41:18

标签: gwt indexoutofboundsexception gwt-editors

在尝试使用GWT的ListEditor系统时,我无法找到一个工作示例,其中列表中每个项目的UI都有删除/删除按钮。

我发现的示例都像this one [1]并且EditorSource.create()实现创建了每个项目Editor并且似​​乎连接处理程序以从中删除项目通过listEditor.getList().remove(index)的基础列表。

但是,删除处理程序的匿名实现会在子编辑器创建时围绕index的值关闭,这会导致IndexOutOfBoundExceptions或删除错误的项目,因为每次删除都会更改所有的索引之后的项目。

我把头发拉了一会儿试图看看我在实例中遗漏了什么,但是从我能说的确实他们确实都有这个问题,所以虽然修复很简单,但是仍然会在这里发布,所以至少有一个人可以找到正确删除项目的例子。

[1]我认为我发现的所有例子都是从我链接的那个例子派生出来的,虽然特别是在remove()中有一点逻辑,并且可能已经做了一些事情来避免纠正列表这样的问题以某种方式命令,我没有挖掘该项目中的其他代码。

1 个答案:

答案 0 :(得分:4)

以下是一个最小ListEditor示例,用于更正其他示例中的问题。

public abstract class FooEditor extends Composite implements Editor<Foo> {

    Widget root; // Instantiated explicitly or through uibinder

    // Implemented as one of uibinder+fields, fields, methods, or LeafValueEditor.set/getValue()

    public FooEditor() { 
        initWidget(root); 
    }

    // Used for brevity, could be any triggering mechanism, click handler, event handler, etc.
    abstract void onDeleteClicked(); 
}

public class FooListEditor extends Composite implements IsEditor<ListEditor<Foo, FooEditor>> {

    private class FooEditorSource extends EditorSource<FooEditor> {

        @Override 
        public FooEditor create(int index) {

            FooEditor subEditor = new FooEditor()
            {
                @Override
                public void onDeleteClicked()
                {
                    // =======================================================
                    //
                    // This fixes the problem present in other examples
                    // by determining the current index at the time of removal
                    //
                    // =======================================================
                    int currentIndex = listEditor.getEditors().indexOf(this);
                    listEditor.getList().remove(currentIndex);    
                }
            };

            setIndex(subEditor, index);

            return subEditor;
        }

        @Override 
        public void dispose(FooEditor subEditor) { 
            subEditor.removeFromParent(); 
        }

        @Override 
        public void setIndex(FooEditor subEditor, int index) {
            listPanel.insert(subEditor, index);
        }
    }

    FlowPanel listPanel; // Instantiated explicitly or through uibinder

    ListEditor<Foo, FooEditor> listEditor = ListEditor.of(new FooEditorSource());

    public FooListEditor() {
        initWidget(listPanel);
    }

    @Override 
    public ListEditor<Foo, FooEditor> asEditor() { 
        return listEditor; 
    }
}