Swing lists and tables use an implementation of ListSelectionModel to handle keeping track of the selection. Every time you change the selection or rows then the component sends those changes to the selection model to keep it in sync. The default implementation that you get is DefaultListSelectionModel. Its implmentation is highly optimized for certain kinds of operations but has had to make comprimizes for a some other operations.

Back when I was doing Imagery I created an alternative implementation of ListSelectionModel because I needed an easy way to convert the selection into a SQL where clause. After much thought I came up with the idea of representing the selection as a list of ranges of selected ids. This means that you can then convert the selection into a list of "id >= rangeMin AND id <= rangeMax" SQL expressions. This solution is well suited to the case where the selection is created by the user. The only way for a user to create more than one range is to "Control" click the rows. It is unlikely that the user will ever select more than a couple dozen ranges. This results in a model that is always simple however many rows there are in the List/Table. As a by product of this alternative selection model can be up to 88,000x faster than the default with large amounts of rows. I have put together a couple of JUnit tests, one does a huge amount of random operations on both a DefaultListSelectionModel and a RangeListSelectionModel and compares the results at each stage. This means that I can be very sure that my implementation is fully compatible with the default one. The second unit test does some performance tests to compare the two models. The data set is 1,000,000 rows and 20,000 operations for each test

Performance Results

Test Default Model Ranges Model Perfomance Gain
Add selection interval 0.017 s 2.533 s -149x
Is selected index 0.009 s 0.011 s -1.2x
Remove index interval 16:09 min 0.011 s 88,053x
Set selected item 1:30 min 0.067 s 1405x
20k Random Operations 4:25 min 0.055 s 4810x
Average 18,823x

As you can see from the results that it is a large win on average. The test that it is slow at is AddSelectionInterval this is because it ends up with 17482 ranges. This should never happen in most real world applications, the only way I can see it happen is if you select all table rows that meet some search criteria which results in 1000s of random rows being selected. In all cases where the selection is user controlled then this will never happen.

Conclusion

I have seen bug reports coming in of hugely bad JTable performance when adding/removing rows from a huge table. After profiling I found that it was the SelectionModel causing the problems. You can see from the performance results that it can take minutes to do a large chunk of selection changes on a big table. So please try out my Ranges implementation in your application and tell me how it performs. If the responses are good I could change it to the default ListSelectionModel implementation in Java 7. To use it you just need to add the line "myTable.setSelectionModel(new RangeListSelectionModel());".

Code Downloads

Here are the sources so you can try it out for yourself:

Java Icon
RangeListSelectionModel.java
Java Icon
RangeSelectionModelPerformanceTest.java
Java Icon
RangeSelectionModelTest.java