On Friday, March 10, 2017 at 10:13:44 AM UTC+1, Gordan Krešić wrote:
>
> I'm editing List of ValueProxies and I'm trying to implement reordering 
> of items (move to front, move to back, move up, move down the list). Since 
> ListEditors work by reflecting change in underlying List and List 
> interface does not support atomic "move" operation for item reordering, my 
> only option is to first remove item from List and then add elements at 
> desired index. So far so good, but in ListEditor, underlying List 
> contains *unflushed* values so when I reinsert them, newely created 
> editors get old values and I loose changes made before reordering took 
> place.
>
> Since flushing ListEditor before remove/add didn't seem as a good idea 
> (breaks editor contract and I would have to propagate Driver down the 
> editors hierarchy) I've ended up cloning ListEditor and its underlying 
> ListEditorWrapper to my own DynamicListEditor and DynamicListEditorWrapper 
> (couldn't even extend them, because relevant members are private).
>
> In DynamicListEditorWrapper I've added one additional method to reorder 
> both elements in underlying list and their corresponding editors in-place:
>
> public void move(int fromIndex, int toIndex) {
> workingCopy.add(toIndex, workingCopy.remove(fromIndex));
> editors.add(toIndex, editors.remove(fromIndex));
> for (int i = Math.min(fromIndex, toIndex), j = Math.max(fromIndex, 
> toIndex); i <= j; i++)
> editorSource.setIndex(editors.get(i), i);
> }
>
> In DynamicListEditor I've used that new wrapper and exposed it in getList 
> method:
>
> public DynamicListEditorWrapper<T, E> getList() {
> return list;
> }
>
> Now I'm able to move item one place up the list by calling:
>
> int currIndex = /* get current index, easy */;
> if (currIndex == 0)
> return;
> listEditor.getList().move(currIndex, currIndex - 1);
>
> I works, but I can't shake off the feeling that I'm over-engineering it 
> and that there is a better (simpler) way for doing this. After all, Lists 
> are ordered collections and editing that order should not be this 
> complicated.
>
> Any advice?
>

I dug into one of our apps and something I've seen is that we did the same 
kind of things except "around" ListEditor rather than duplicating it:
The widget is a ValueAwareEditor<List<T>>, has a child @Path("") 
ListEditor<T, E> and has *two* fields of type List<T>: the actual value 
being edited (called 'value'), and a copy of it to track changes (called 
'list').
Our flush() and setValue() from ValueAwareEditor are:
  @Override
  public void flush() {
    this.value.clear();
    this.value.addAll(this.list);
  }

  @Override
  public void setValue(List<P> value) {
    this.value = value;
    this.list.clear();
    this.list.addAll(value);
  }

The other methods are no-ops.
And our moveUp/moveDown manipulate the widgets/editors themselves (I note 
that the widgets aren't IsEditor<T>, but directly Editor<T>, if that makes 
a difference) and the 'list' (but not 'value').
In other words, we only manipulate 'value' on setValue/flush, which I 
believe is to not break the editor contract.

I can't tell if this was over-engineered as well or not, or hackish 
(probably a bit), as that code is nearly 6 years old already.

(btw, instead of "workingCopy.add(toIndex, workingCopy.remove(fromIndex))" 
we use "Collections.swap(this.list, index, newIndex)"; probably does the 
same but is more readable; and we limit ourselves to a delta of -1/1)

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.

Reply via email to