Using the RowHeaderResizeListener

The JViewport constrains how much of the underlying component, or view, is visable. Resizing the rowheader viewport as the row header table is resized forces the main table to be repositioned.

  1 
  2 package com.vizitsolutions.identitytable;
  3 
  4 import javax.swing.table.DefaultTableColumnModel;
  5 import javax.swing.JScrollPane;
  6 import javax.swing.JTable;
  7 import javax.swing.JViewport;
  8 import javax.swing.table.TableColumn;
  9 import javax.swing.table.TableColumnModel;
 10 
 11 /**
 12  * <p>$Id$</p>
 13  *
 14  * <p>
 15  * This class maps a TableModel into two JTables, and places
 16  * them into a JScrollPane. The first JTable contains n fixed
 17  * columns, and represents what is commonly called a rowheader.
 18  * This is placed in the rowheader area of the JScrollPane. These
 19  * columns will not scroll horizontally. This is particularly
 20  * useful when you have one or more columns that identify an object
 21  * and several additional columns that contain attributes of the
 22  * object. Placing the identifying columns in these fixed columns
 23  * ensures that they are always visible while the attributes of the
 24  * object are scrolled into view.
 25  * </p>
 26  * <p>
 27  * The second JTable contains the remaining columns and is placed in
 28  * the main viewport and will scroll normally.
 29  * </p>
 30  *
 31  * @author Alex Kluge
 32  * @version $Revision$, $Date$
 33  */
 34 public class IdentityTable3 extends JScrollPane
 35 {
 36     private JTable           mainTable;
 37     private TableColumnModel mainColumnModel      = new DefaultTableColumnModel();
 38     private JTable           rowHeaderTable;
 39     private TableColumnModel rowHeaderColumnModel = new DefaultTableColumnModel();
 40     
 41     /**
 42      * Creates a new instance of IdentityTable1
 43      */
 44     public IdentityTable3(IdentityTableModel baseTableModel)
 45     {
 46         // Start out life as an empty scrollpane.
 47         super();
 48         
 49         // Loop over each of the fixed columns, and create columns in the row
 50         // header column model for them.
 51         TableColumn column;
 52         int         columnCount         = baseTableModel.getColumnCount();
 53         int         currentColumn;
 54         int         identityColumnCount = baseTableModel.getIdentityColumnCount();
 55         
 56         for (currentColumn = 0; currentColumn<identityColumnCount; currentColumn++)
 57         {
 58             column = new TableColumn(currentColumn);
 59             column.setHeaderValue(baseTableModel.getColumnName(currentColumn));
 60             
 61             rowHeaderColumnModel.addColumn(column);
 62         }
 63         
 64         // Now loop over the remaining columns, and add them to the main table's column model.
 65         for (currentColumn = identityColumnCount; currentColumn<columnCount; currentColumn++)
 66         {
 67             column = new TableColumn(currentColumn);
 68             column.setHeaderValue(baseTableModel.getColumnName(currentColumn));
 69             
 70             mainColumnModel.addColumn(column);
 71         }
 72         
 73         // Providing a column model here automatically sets the
 74         // autoCreateColumnsFromModel flag to false.
 75         rowHeaderTable = new JTable(baseTableModel, rowHeaderColumnModel);
 76         rowHeaderTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 77 
 78         mainTable      = new JTable(baseTableModel, mainColumnModel);
 79         mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 80         
 81         // Ensure that both tables have common selections.
 82         rowHeaderTable.setSelectionModel(mainTable.getSelectionModel());
 83         rowHeaderTable.setPreferredScrollableViewportSize(rowHeaderTable.getPreferredSize());
 84         
 85         // This puts the column headers in the upper left corner above the row
 86         // header columns. This is the same thing that happens when a JTable configures
 87         // the containing JScrollPane.
 88         setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeaderTable.getTableHeader());
 89         
 90         JViewport rowHeaderViewPort = new JViewport();
 91         rowHeaderViewPort.setView(rowHeaderTable);
 92         setRowHeader(rowHeaderViewPort);
 93 
 94         // Listen for resize events on the row header, and resize the main table as appropriate.
 95         RowHeaderResizeListener rowHeaderResizeListener = new RowHeaderResizeListener(this,           rowHeaderViewPort,
 96                                                                                       rowHeaderTable, mainTable);
 97         rowHeaderTable.addComponentListener(rowHeaderResizeListener);
 98 
 99         setViewportView(mainTable);
100     }
101     
102     public TableColumnModel getMainColumnModel()
103     {
104         return mainColumnModel;
105     }
106     
107     public TableColumnModel getRowHeaderColumnModel()
108     {
109         return rowHeaderColumnModel;
110     }
111 }
112 
113 

Notes