Community
Participate
Working Groups
When TableViewer#getSelection() is invoked on a TableViewer that is using a DeferredContentProvider as input, the selection that is returned is sometimes incomplete. This happens when multiple rows are selected and the selection spans more than one "screenful" of rows. This is not a problem for a TableViewer with your basic ILazyContentProvider. The latest build I have reproduced this in is 3.2.0 build I20051116-1332. The testcase attached is a small SWT/jface application. The main() method is in DeferrredTableSelections.java - Start the application - Press the button that reads "Set 50000 Items". The left table fills in with 50000 items. - Select the first item in the table. - Scroll the table down to extend the selection to item 150 and shift-click that item to extend the selection. In my tests, the selection controls (to the left of the table) reports the starting and ending items but the number of items selected is off. - Press the "transfer" button to copy all the items in the selection to the table on the right. The contents of the table on the right displays where the gap is. The bug appears in tables of relatively small size (e.g. 80 items). I think it just depends upon the number of table items in view. You can change the spinner and reset the left table to a different number of items to experiment. Sometimes when you make a selection where there is a gap and then scroll the view (a single row at a time), blank rows show up in the table reflecting the gaps recorded in the selection. I can't think of a good workaround because multi-row selections can be discontiguous (CTRL-select).
Created attachment 30276 [details] 2 java classes that make up the testcase mentioned in the description
Created attachment 31990 [details] oops. please ignore. meant to attach it to bug 117165 ZIP file containing two java files
The Javadoc for ILazyContentProvider.updateElement says: * <strong>NOTE</strong> #updateElement(int index) can be used to determine selection * values. If TableViewer#replace(Object, int) is not called before * returning from this method selections may have missing or stale elements. * In this situation it is suggested that the selection is asked * for again after he update. Unfortunately, DeferredContentProvider (which implements ILazyContentProvider) does not call back immediately and thus breaks getSelection(). Honestly, I don't know how this can be fixed. If you have any idea please let me know.
(In reply to comment #3) > * In this situation it is suggested that the selection is asked > * for again after he update. I was wondering what this suggestion means exactly. With the DeferredContentProvider, aren't I going to get the same results no matter how many times I request the selection because there isn't a way of forcing the provider to invoke replace()? Also, I really don't want the replace() invoked for items that are not visible. > Unfortunately, DeferredContentProvider (which implements ILazyContentProvider) > does not call back immediately and thus breaks getSelection(). > > Honestly, I don't know how this can be fixed. If you have any idea please let > me know. I have some thoughts on the matter that I will share, but I'm rather new to eclipse, swt and jface so I wouldn't be surprised if my suggestion is unacceptable (I can think of a few reasons). I implemented a workaround by modifying TableViewer#getVirtualSelection. I believe what I did is an unacceptable hack from a jface design perspective, however it does lead me to suggest that ILazyContentProvider be extended (and implemented by the DeferredContentProvider) so that the TableViewer has a method for retrieving elements directly from the content provider. (I'd suggest that ILazyContentProvider be changed, but I can see how that would not sit well with the current implementors.) Simply for discussion's sake, say that you created an extension of ILazyContentProvider. Call it IBackgroundContentProvider and put the following method in it: Object getElement(int index); This is similar to updateElement (same parameter) but allows the TableViewer to get its answer immediately and it doesn't have to create a TableItem if it doesn't want to. In the getVirtualSelection() method, the TableViewer would check to see if the content provider implements IBackgroundContentProvider and get the element data using the getElement() method instead of the updateElement()/getTable().getItem() sequence. I think this allows for the small number of TableItems desirable of a VIRTUAL viewer while resolving the getSelection() issue because the DeferrendContentProvider seems to have all the data getSelection() needs. I suppose my suggestion runs afoul of the case where the content provider is still in the act of sorting/filtering the elements covered by the selection. That issue may need to be solved at the same time or independently. But I'm not sure it's an issue because it seems acceptable to me that the getElement() method doesn't return until the index it wants has been "finalized" by the sorting/filtering going on. I didn't implement my suggestion. The hack I implemented involved adding an "if (getContentProvider() instanceof DeferredContentProvider ){}" statement to TableViewer#getVirtualSelection (plus adding a method to DeferredContentProvider), but the method invocation sequence is essentially similar to my suggestion.
Thanks for your ideas, it seems like this would solve the problem. In the case where the sorting/filtering job is still running, I think it is problematic to block until it has finished. Maybe returning a different kind of selection that has some null elements? For 3.3, there are good chances that we will deprecate ILazyContentProvider and create a new one because of another problem - try removing an element from a virtual table and you will find out why... (bug 97786)
Deferring
Hitesh is now responsible for watching bugs in the [Viewers] component area.
(In reply to comment #7) > Hitesh is now responsible for watching bugs in the [Viewers] component area. Thanks Boris. Hitesh, any news around this bug, it's assigned for a long some time now and a fix idea is present so we could get rid of if for 3.8 I think, what do you think? Helmut
No one is watching this area at the moment. I'd consider a patch contribution for 3.8/4.2. PW
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.