Community
Participate
Working Groups
EC post: "Problem inserting an element into a TableViewer with a filter" by WHH on Aug 1, 2001. I am using version 0.120 [ne] 01 of org.eclipse.jface.viewers.TableViewer. The TableViewer is configured with a filter to only allow certain elements to be displayed. When I tried to insert an element into the TableViewer using the insert(Object element , int position) method, I found out that the position argument is ignored, and the element is always inserted at the end. I dug in the code and found out that if the TableViewer has either a Sorter or a Filter, the insert method calls add(Object) to service the call (see code fragment below) public void insert(Object element, int position) { tableViewerImpl.applyEditorValue(); if (getSorter() != null || hasFilters()) { add(element); return; } if (position == -1) position = table.getItemCount(); updateItem(new TableItem(table, SWT.NONE, position), element); } As you can see, if the TableViewer has any filters, it calls add(Object), but does not pass the position argument along. Internally, add(Object) calls indexForElement(Object), but without a Sorter it always returns the position at the end of the table. Does it mean that if one uses a filter, one must supply a sorter at the same time? I thought about it a little bit and this makes sense to a certain degree. The semantics of the position is ambiguous. It can mean the position of the added element in either the filtered list or un-filtered list. However, simply ignoring the position argument and relegating the element to the end of the list seems to be the worst of both worlds. Thanks in advance. NOTES: NE (8/1/01 3:00:24 PM) Yes, this is a bug, for which I've filed a PR. The spec states that the position is relative to the model. As you point out, however, it can't figure out the correct position in the widget if items have been filtered out. The only way it could figure it out would be for the viewer to hang onto the original, pre-filtered list from the model, but it does not do this: it gets the list from the model, optionally filters and sorts it, then stuffs the corresponding labels into the underlying table widget. So about the best it could do currently is to do a full refresh of the list. As a workaround for this bug, you could do a refresh() on the table viewer yourself. Note that this is an O(N) operation, though. So if you're inserting many items, it would be better to just modify your model, then issue a single refresh() after all insertions are done. NE (8/2/01 9:56:27 AM) WHH posts: great to hear that you have filed a PR about this problem. Your work-around is fine and it works. However, for people using MOF2, another work-around is necessary because the insert and update calls are generate automatically and the developer does not have easy control over them. I am working around this problem in another way, and I want to share it here with other people. The work-around is to add a sorter which sorts the elements in the model order. Since a sorter is available, the indexOfElement method actually returns a meaningful result and enables the element to be inserted correctly. Using a sorter sounds like a bad performance choice. However, I don't think that a full sort was performed during the insert. The method indexOfElement just uses the sorter to perform a binary search of the proper index to search for the element, which is an O(log(N)) operation. The statements above are the results of very casual thoughts and may be incorrect. I am sharing this as a possible alternative. If something is wrong please correct me.
PRODUCT VERSION: 0.9
Defer. Viewer could keep map from original element order to filtered order. On an insert with a given position, it would map to the corresponding filtered position.
Reopen for investigation
Deferring. Again.