Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 137: Manage distributed JTables

Efficiently display huge JTables using distributed caching TableModels

  • Print
  • Feedback
In this information-driven age, displaying tables with thousands or tens of thousands of rows is standard practice. The data that populates these tables is generally retrieved from remote databases, which presents a challenging dilemma: Should your program download all table data at once, or should it only download the first chunk of requested data? Downloading all data initially can result in a significant time delay before users can use it, which is especially annoying if they are only interested in the first few results. Downloading a chunk of data is common in Web search results, for example on Google, where results paginate into groups of ten. However, in certain circumstances, you might need to show this data in a table but still minimize the initial hit for users. You might, for instance, require a spreadsheet-type user interface with column sorting, cell selection, and data editing. Thanks to a neat design feature of JTable, we can maintain JTable's rich user interface while optimizing the required data download.

Note: You can download this article's source code from Resources.

A distributed caching TableModel

JTable implements the Model-View-Controller design pattern. In this pattern, the component's data source (the model) is separated from the component's graphical (view) and controller parts into three distinct modules (see Resources). In JTable's case, the model consists of the interface TableModel. This makes JTable very adaptable because you can wrap any data resource in a TableModel implementation, set the TableModel on the JTable, and display the table on screen. For example, you can create a table that displays data from a flat file, a database, or even a message queue using this technique. We take advantage of that adaptability in this tip.

The JTable loads data from its TableModel using a lazy loading process: it reads only data from the model when necessary, rather than step through all rows before displaying. When a JTable needs to render a particular table cell on the screen, it calls the method getValueAt(int row, int column) on its TableModel to retrieve the data value. This is also a lazy process because the data required to service this method can be derived by any means. For example, if we want the data to reside on the server side, we can request a URL that returns the data for this cell as XML. getValueAt() can then parse and return this XML, which ultimately displays in the JTable.

However, remote calls are time-consuming, so why not bundle the request for many data cells into the same remote call and cache those extra values until required? If the cell value at row 0, column 0 is required, we can call a servlet that returns all data for the cells between rows 0 and 50. This means we will have all data at hand to service the getValueAt() calls for all table cells currently in view. More data is retrieved from the servlet only when the user scolls down the table. Furthermore, you can implement a client-side cache so only n rows (e.g., 1,000), are held on the client side. When the user scrolls down the table past the 1,000th row, the data for the first set of rows can be overwritten since it's not currently required. If the user scrolls back up the table, data can be reread from the server as necessary.

  • Print
  • Feedback

Resources