Using the ActionMap

The IdentityTable now has a new method, installKeybordActions, which puts the new actions into the ActionMap. Now, whenever the actions to move forward or backward a cell are accessed, our versions will be used.

  1 
  2 package com.vizitsolutions.identitytable;
  3 
  4 import javax.swing.ActionMap;
  5 import javax.swing.table.DefaultTableColumnModel;
  6 import javax.swing.JScrollPane;
  7 import javax.swing.JTable;
  8 import javax.swing.JViewport;
  9 import javax.swing.ListSelectionModel;
 10 import javax.swing.table.TableColumn;
 11 import javax.swing.table.TableColumnModel;
 12 
 13 /**
 14  * <p>$Id$</p>
 15  *
 16  * <p>
 17  * This class maps a TableModel into two JTables, and places
 18  * them into a JScrollPane. The first JTable contains n fixed
 19  * columns, and represents what is commonly called a rowheader.
 20  * This is placed in the rowheader area of the JScrollPane. These
 21  * columns will not scroll horizontally. This is particularly
 22  * useful when you have one or more columns that identify an object
 23  * and several additional columns that contain attributes of the
 24  * object. Placing the identifying columns in these fixed columns
 25  * ensures that they are always visible while the attributes of the
 26  * object are scrolled into view.
 27  * </p>
 28  * <p>
 29  * The second JTable contains the remaining columns and is placed in
 30  * the main viewport and will scroll normally.
 31  * </p>
 32  *
 33  * @author Alex Kluge
 34  * @version $Revision$, $Date$
 35  */
 36 public class IdentityTable4 extends JScrollPane
 37 {
 38     // These names follow those used in JTable UI delegate.
 39     public static final String LEFT_ARROW_ACTION_NAME  = "selectPreviousColumn";
 40     public static final String RIGHT_ARROW_ACTION_NAME = "selectNextColumn";
 41     public static final String SHIFT_TAB_ACTION_NAME   = "selectPreviousColumnCell";
 42     public static final String TAB_ACTION_NAME         = "selectNextColumnCell";
 43     
 44     private JTable           mainTable;
 45     private TableColumnModel mainColumnModel      = new DefaultTableColumnModel();
 46     private JTable           rowHeaderTable;
 47     private TableColumnModel rowHeaderColumnModel = new DefaultTableColumnModel();
 48     
 49     /**
 50      * Creates a new instance of IdentityTable
 51      */
 52     public IdentityTable4(IdentityTableModel baseTableModel)
 53     {
 54         // Start out life as an empty scrollpane.
 55         super();
 56         
 57         // Loop over each of the fixed columns, and create columns in the row
 58         // header column model for them.
 59         TableColumn column;
 60         int         columnCount         = baseTableModel.getColumnCount();
 61         int         currentColumn;
 62         int         identityColumnCount = baseTableModel.getIdentityColumnCount();
 63         
 64         for (currentColumn = 0; currentColumn<identityColumnCount; currentColumn++)
 65         {
 66             column = new TableColumn(currentColumn);
 67             column.setHeaderValue(baseTableModel.getColumnName(currentColumn));
 68             
 69             rowHeaderColumnModel.addColumn(column);
 70         }
 71         
 72         // Now loop over the remaining columns, and add them to the main table's column model.
 73         for (currentColumn = identityColumnCount; currentColumn<columnCount; currentColumn++)
 74         {
 75             column = new TableColumn(currentColumn);
 76             column.setHeaderValue(baseTableModel.getColumnName(currentColumn));
 77             
 78             mainColumnModel.addColumn(column);
 79         }
 80         
 81         // Providing a column model here automatically sets the
 82         // autoCreateColumnsFromModel flag to false.
 83         rowHeaderTable = new JTable(baseTableModel, rowHeaderColumnModel);
 84         rowHeaderTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 85 
 86         mainTable      = new JTable(baseTableModel, mainColumnModel);
 87         mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 88         
 89         // Ensure that both tables have common selections.
 90         // Save the row selection model for later.
 91         ListSelectionModel rowSelectionModel = mainTable.getSelectionModel();
 92         rowHeaderTable.setSelectionModel(rowSelectionModel);
 93         rowHeaderTable.setPreferredScrollableViewportSize(rowHeaderTable.getPreferredSize());
 94         
 95         // This puts the column headers in the upper left corner above the row
 96         // header columns. This is the same thing that happens when a JTable configures
 97         // the containing JScrollPane.
 98         setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeaderTable.getTableHeader());
 99         
100         JViewport rowHeaderViewPort = new JViewport();
101         rowHeaderViewPort.setView(rowHeaderTable);
102         setRowHeader(rowHeaderViewPort);
103 
104         // Listen for resize events on the row header, and resize the main table as appropriate.
105         RowHeaderResizeListener rowHeaderResizeListener = new RowHeaderResizeListener(this,           rowHeaderViewPort,
106                                                                                       rowHeaderTable, mainTable);
107         rowHeaderTable.addComponentListener(rowHeaderResizeListener);
108 
109         setViewportView(mainTable);
110         
111        installKeybordActions(rowHeaderTable,                      mainTable,
112                               rowSelectionModel,                   rowHeaderColumnModel.getSelectionModel(),
113                               mainColumnModel.getSelectionModel());
114     }
115     
116     protected void installKeybordActions(JTable             rowHeaderTable,           final JTable       mainTable,
117                                          ListSelectionModel rowSelectionModel,        ListSelectionModel headerColumnSelectionModel,
118                                          ListSelectionModel mainColumnSelectionModel)
119     {
120         ActionMap rowHeaderActionmap = rowHeaderTable.getActionMap();
121         ActionMap mainActionMap      = mainTable.getActionMap();
122 
123 
124          // Tab action handler, shift forward one cell, with wrapping
125         TabKeyActionHandler tabKeyActionHandler
126                     = new TabKeyActionHandler(rowHeaderTable,           mainTable,
127                                               rowSelectionModel,        headerColumnSelectionModel,
128                                               mainColumnSelectionModel, 1,
129                                               true);
130         // Put the action handler into the appropriate place for both the
131         // row header and the main table.
132         rowHeaderActionmap.put(TAB_ACTION_NAME, tabKeyActionHandler);
133         mainActionMap.put(TAB_ACTION_NAME,      tabKeyActionHandler);
134 
135         // Right arrow action handler, shift forward one cell, no wrapping.
136         tabKeyActionHandler
137                     = new TabKeyActionHandler(rowHeaderTable,           mainTable,
138                                               rowSelectionModel,        headerColumnSelectionModel,
139                                               mainColumnSelectionModel, 1,
140                                               false);
141 
142         rowHeaderActionmap.put(RIGHT_ARROW_ACTION_NAME, tabKeyActionHandler);
143         mainActionMap.put(RIGHT_ARROW_ACTION_NAME,      tabKeyActionHandler);
144 
145         // Shift-Tab action handler, shift backward one cell, with wrapping
146         tabKeyActionHandler
147                     = new TabKeyActionHandler(rowHeaderTable,           mainTable,
148                                               rowSelectionModel,        headerColumnSelectionModel,
149                                               mainColumnSelectionModel, -1,
150                                               true);
151 
152         rowHeaderActionmap.put(SHIFT_TAB_ACTION_NAME, tabKeyActionHandler);
153         mainActionMap.put(SHIFT_TAB_ACTION_NAME,      tabKeyActionHandler);
154 
155         // Left arrow action handler, shift backward one cell, no wrapping.
156         tabKeyActionHandler
157                     = new TabKeyActionHandler(rowHeaderTable,           mainTable,
158                                               rowSelectionModel,        headerColumnSelectionModel,
159                                               mainColumnSelectionModel, -1,
160                                               false);
161 
162         rowHeaderActionmap.put(LEFT_ARROW_ACTION_NAME, tabKeyActionHandler);
163         mainActionMap.put(LEFT_ARROW_ACTION_NAME,      tabKeyActionHandler);
164     }
165     
166     public TableColumnModel getMainColumnModel()
167     {
168         return mainColumnModel;
169     }
170     
171     public TableColumnModel getRowHeaderColumnModel()
172     {
173         return rowHeaderColumnModel;
174     }
175 }
176 
177 

Notes