glazedlists / glazedlists

Open Source List Transformations for Java
Other
163 stars 32 forks source link

Inserted items become selected #31

Closed hbrands closed 20 years ago

hbrands commented 20 years ago

I am delighted with the performance, flexibility and ease of use of your platform, which I am
currently evaluating for use in a table intensive application for my employer.

Our application needs to display tabular data which gets notified through JMS. That means,
ultimately, that data arrives via a callback method in out code. I am therefore using a
BasicEventList as base list, encapsulated in a SortedList and a subclass of AbstractFilterList as a
means of providing the functionality (sorting & filtering by various criteria) that we need.

The only problem so far arises with keeping selected rows between data insertions. I set the
underlying table selection model to ListSelectionModel.MULTIPLE_INTERVAL_SELECTION (anyway,
as it is the default value). A thread keeps adding rows to the table, at a rate of 10 per second (to
test performance). I have noticed that whenever I select a row, further row insertions may
modify the number of selected rows. In particular, if a new row has the same internal index as
the currently selected one, it is guaranteed I will end up with two selected rows.

That seems to be your intended behaviour as per the documentation of the class SelectionList;
however, I tried to modify it in order to suppress this behaviour to no avail. In particular, I
suppressed the lines marked inside SelectionList.notifyListChanges():
// when an element is inserted, it is selected if its index was selected
} else if(changeType == ListChangeBlock.INSERT) {
    // when selected, add the flag and fire a selection event
    if(previouslySelected)

{         flagList.add(index, Boolean.TRUE); // <--- SUPRESS         updates.appendChange(previousSelectionIndex, ListChangeBlock.INSERT); // <--- SUPRESS     // when not selected, just add the space     }

else

{         flagList.add(index, null);     }

I tried other changes, including the method SelectionList.valueChanged(). Do you have any
suggestion to solve this problem? Is it a bug in your code? In that case, I'd be willing to help and
contribute back to your project any bugfixes I develop. I can also provide you with my testing
code, but at this stage it's really simple: the thread inserting fake data rows does so in an
invokeLater() block, and uses a java.util.Timer for scheduling data feed.

The problem does not manifest when I set the table selection model to
ListSelectionModel.SINGLE_SELECTION, by the way.

Thank you for your time and for providing the Java Community with such a promising piece of
work.

Yours
Iván Rivera Rodríguez

[GLAZEDLISTS-15] created by jessewilson

hbrands commented 20 years ago

Iván -

The current behaviour is "as designed" but I agree that there may be a better way to solve this
problem.

This behaviour is the same as the behaviour of a simple JTable (ie. no Glazed Lists). When JTable
receives in insert at some index, say i, then the newly inserted row will be selected only if row i
was selected before the insertion. This behaviour has some nice properties: values inserted
within a range of selected values will themselves become selected.

But I also agree that this behaviour can be problematic. I think the solution is to add an extra
"mode" to the SelectionList. The new mode will be as you describe. Inserted values will never be
selected until done so explicitly by the user.

Due to constraints at school and at work I will be unable to add this functionality until at least
February 14th, 2004. In the worst case it will take until February 21st to complete. Hopefully then
I will get something working that solves this problem!

by jessewilson

hbrands commented 20 years ago

According to the J2SE 1.4.1 API for DefaultListSelectionModel:
"If the value at index is itself selected and the selection mode is not SINGLE_SELECTION, set all of
the newly inserted items as selected. Otherwise leave them unselected. "
http://java.sun.com/j2se/1.4.1/docs/api/javax/swing/
DefaultListSelectionModel.html#insertIndexInterval(int,%20int,%20boolean)

I have tested some of the simple ways to solve this problem and I do not think that they will work
elegantly. The problem is that I need to undo the selection which is added by
DefaultListSelectionModel. This would be trivial except that the ListSelectionModel fires events that
also need to be done and undone.

I am considering changing the Interface of SelectionList, to become a ListSelectionModel and
EventList simultaneously. This approach is complex but appropriate as the SelectionList already
tracks the table selection.

I will continue to review my options but for now it looks like implementing ListSelectionModel is my
best bet.

by jessewilson

hbrands commented 20 years ago

I have solved the problem by implementing ListSelectionModel. Implementing this class was
difficult as the interface specification was not explicit enough for the behaviour in certain cases. I
think that the behaviour of my ListSelectionModel should be the same as the J2SE 1.4
DefaultListSelectionModel. If you discover a descrepancy, let me know.

This new ListSelectionModel has a new mode for solving this problem
"MULTIPLE_INTERVAL_SELECTION_DEFENSIVE". The new mode is the default list selection mode.

My ListSelectionModel is fully capable of switching between different modes and retains the
appropriate selection when the mode changes. To test this, there is a commented out block of
code in ProgrammingLanguageBrowser.java that provides a JComboBox to switch between
different ListSelectionModel modes.

I hope this fix helps, it took quite a bit of code to make it work - 653 lines!

by jessewilson

hbrands commented 20 years ago

From Iván Rivera:

Thank you very much. I had also some time to work on the issue last Friday and came up with a
subclass of javax.swing.DefaultListSelectionModel which undoes the selection, without caring for
events generated. I append a copy to this mail for you to examine, as it seems to correct the
(Swing-default) behaviour.

You are right about the event handling problem, but it doesn't seem to be causing troubles in my
test benchmark. Perhaps it's just a matter of performance. Anyway, your solution is surely more
elegant. I won't be able to see your code until this night at home, since at work I'm behind an
extremely restrictive firewall which doesn't even allow SSH tunneling for CVS checkout.

I'm working in some components to enable automatic width adjustment for columns based on
content and column hiding. I hope to be able to contribute the code once I'm done (this week,
most likely).

Once again, thanks for your interest.

Yours,

Iván Rivera

by jessewilson

hbrands commented 20 years ago

This bug has been fixed for two weeks with no problems. I am marking it closed.

by jessewilson