Как разрешить редактору GWT с одним элементом/вложенным редактором удалить себя из ListEditor, который его содержит? например при нажатии кнопки удаления

При попытке использовать систему ListEditor GWT мне не удалось найти работающий пример, в котором пользовательский интерфейс каждого элемента в списке имел кнопку удаления/удаления.

Все найденные мной примеры были похожи на этот[1] и реализация EditorSource.create() создает для каждого элемента Editor и, по-видимому, подключает обработчик для удаления элемента из базового списка через listEditor.getList().remove(index).

Однако анонимная реализация обработчика удаления замыкается вокруг значения индекса во время создания субредактора, что приводит к удалению IndexOutOfBoundExceptions или неправильного элемента, поскольку каждое удаление изменяет индекс всех элементов, следующих за ним.

Я дернул себя за волосы на некоторое время, пытаясь увидеть, чего мне не хватало в примерах, которые препятствовали тому, чтобы это произошло, но, насколько я могу судить, у них действительно была эта проблема, поэтому, хотя исправление довольно простое, я все же опубликую это здесь, так что есть хотя бы один пример, который люди могут найти, который правильно удаляет элемент.

[1] Я думаю, что все примеры, которые я нашел, были получены из того, на который я ссылался, хотя в этом, в частности, было немного больше логики в remove(), и, возможно, он делал что-то, чтобы избежать проблемы, например, каким-то образом исправляя порядок списка, Я не копался в другом коде в этом проекте.


person Bjartr    schedule 18.04.2015    source источник


Ответы (1)


Ниже приведен минимальный 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; 
    }
}
person Bjartr    schedule 18.04.2015
comment
Большое спасибо за добавление этого. Определенно полезно для сообщества :) - person slugmandrew; 05.06.2015