pre1.6 jtable sorter – a simple impl

In a high-speed trading GUI, it’s not uncommon to have 2 tables showing the same live data, but in different sort orders. As data stream in, the 2 tables must auto-refresh (either periodically or event-driven).

This requires a separate-view-shared-model design. Whenever content of the model (object) is updated, the updater method would call myTableModel.fireXXX() on EDT. Since the 2 (JTable) views are always among the listeners of myTableModel, fireXXX() method always invokes the callback on each, sequentially, on EDT. When the callback event handler runs, it basically queries myTableModel and displays its content sorted. This could take many millisec on each table if content is huge. If you have 5 tables on myTableModel, the latency adds up. Use paging if necessary.

Don’t do the naïve sort — recreate a table model instance, and setModel(). This way the 2 views will show inconsistent data — detached.

Table sorting should not change the data, should change the presentation instead. Here’s one simple way to keep a live table (or two) sorted —

Provide a decorator class/object implementing TableModel. This is the object you put into mySortedJtable.setModel(). It holds a decoratee TableModel instance. As you query it via getValueAt(int,int), you go through a row index translator, which translates view-index to physical-index.

* Physical index is the row-index into decoratee.getValueAt(). The sequencing inside decoratee doesn’t change during sort
* view index is the row-index into this.getValueAt()

So when the table is re-drawn, this.getValueAt() gets called 22 times if there are 22 rows. First call (row 0) will hit physical-index 21 in a reverse sort.

This is enough to present a static content sorted. But our data is live. Every 2 seconds, or whenever MOM delivers new data, some method updates the underlying data structure inside decoratee. Now the view won’t show it. The same method would trigger (perhaps via invokeLater or timer event) a decorator.sort() and decorator.fireXXX(). The sort() would update the row-index translator. The fireXXX() would make the view query its model (i.e. decorator) via decorator.getValueAt().

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s