Bug 519387 - Selection in table isn't preserved after calling refresh on the corresponding TableViewer in RWT, whereas in SWT the selection is preserved
Summary: Selection in table isn't preserved after calling refresh on the corresponding...
Status: ASSIGNED
Alias: None
Product: RAP
Classification: RT
Component: JFace (show other bugs)
Version: 3.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-07 08:04 EDT by Matthias Boehm CLA
Modified: 2018-02-21 06:13 EST (History)
1 user (show)

See Also:


Attachments
The test programs (SWT/RWT) (14.58 KB, application/x-zip-compressed)
2017-07-07 08:04 EDT, Matthias Boehm CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Boehm CLA 2017-07-07 08:04:09 EDT
Created attachment 269282 [details]
The test programs (SWT/RWT)

Please take a look at the appended test programs (using nearly the same code once in SWT and once in RWT). I'm using a TableViewer with a content model that provides a list of descending numbers. Each time getElements is called, one number is added. There is also a button that refreshes the list with this code:

ISelection sel = viewer.getSelection();
viewer.refresh();
viewer.setSelection(sel, true);

This should preserve the selection. In SWT, this is the case (look at the appended program). In RWT, this is not the case (look at the other appended program). There, after each click on the update button, another number is selected.
Comment 1 Ivan Furnadjiev CLA 2017-10-24 04:15:25 EDT
The issue is a little bit complicated and hard to fix. 
- In SWT viewer.refresh() do the redraw immidiatelly and the SetData event is fired. Based on this event in AbstractTableViewer#VirtualManager the new element is associated with every TableItem. viewer.setSelection uses the associated element to find the correct TableItem and set selection to it.
- In RAP the (fake) redraw is not executed immidiatelly, but ONCE after all async messages - see Display#runPendingMessages -> executeNextRedraw. This is needed to avoid virtual table data to refresh multiple times (on every redraw call), as this operation is performance criticle, especially in multiuser environment. As a result, the viewer.setSelection is executed on the old associated elements. Wrong item is found in this case.

The only workaround I can think of (and tested) is to use RAP internals to force data update on all TableItems before selection is set back like:
---
ISelection sel = viewer.getSelection();
viewer.refresh();
viewer.getTable().getAdapter( ITableAdapter.class ).checkData();
viewer.setSelection( sel, true );
---
This is the same code executed by RAP fake redraw but in the exact time - before restoring the selection.
Comment 2 Matthias Boehm CLA 2018-02-21 06:13:49 EST
Thank you for the workaround, which solves the Problem.