For those of us who don't know Excel that well, this option allows the user to have the top X columns (X is configurable) remain fixed. Scrolling will be limited to the remaining columns. The same can be applied to the left X rows as well. If both a number of rows and a number of columns are frozen the bottom-right part contains the scrolling.
I can think of one technique to do this:
- create one JTable with the TableModel. Use a RowSorter with a RowFilter to filter out all rows with a row number >= X. This will be the table part with the header and the first X rows.
- create another JTable with the same TableModel. Again, use a RowSorter with a RowFilter to filter out all rows with a row number < X. This will be the table part with everything but the header and the first X rows.
- add a TableColumnModelListener to the TableColumnModel of the top JTable; this listener will apply the same changes to the TableColumnModel of the bottom JTable. This will make sure that when you resize a column in the top JTable (the one with the header) the column will be resized equally in the bottom JTable.
- wrap the bottom JTable in a JScrollPane. This will automatically add the header of this JTable.
- set the column header of the JScrollPane to be a JPanel with the top JTable and its JTableHeader. I think this should do it:
I haven't tested this, but I think this should do it. You basically moved X rows from the JScrollPane's view port to its column header.
Edit: scratch step 3. Instead of using two TableColumnModels that are synchronized using listeners, just set the bottom JTable's TableColumnModel to that of the top JTable.
Here's that all written in code, using the sharing of the TableColumnModel:
This has two problems:
1) the JScrollPane's column header will be reset by the JScrollPane automatically to the JTableHeader of the second table.
2) the resizing of columns is now somehow broken; dragging works as expected.
I'm sure one of our Swing guru's (Rob C, Darryl B, Pete S, Michael D) can help fix these issues.
That code works for freezing the left X columns. Now do the same for freezing the top X rows
The problem with that is the table header. You'll need to show only one (or two, if you also freeze the left X columns), but the resizing / reordering will need to work on the bottom table(s) as well. Still, by not using JScrollPane's column header, row header and other non-viewport components the solution may solve the problems I had with my code.