001 /* 002 * $Id: ComponentAdapter.java,v 1.6 2006/05/14 08:12:13 dmouse Exp $ 003 * 004 * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, 005 * Santa Clara, California 95054, U.S.A. All rights reserved. 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 020 */ 021 022 package org.jdesktop.swingx.decorator; 023 024 import javax.swing.JComponent; 025 026 /** 027 * Abstract base class for all component data adapter classes. 028 * A <code>ComponentAdapter</code> allows a {@link Filter}, {@link Sorter}, 029 * or {@link Highlighter} to interact with a {@link #target} component through a 030 * common API. 031 * 032 * It has two aspects: 033 * <ul> 034 * <li> interact with the data of the component. The methods for this are those 035 * taking row/column indices as parameters. The coordinates 036 * are in model coordinate system. Typical clients of are Filters. 037 * <li> interact with the view state for a given data element. The row/cloumn fields and the 038 * parameterless methods service this aspect. The coordinates are in view coordinate system. 039 * Typical clients are the highlighting part of Highlighters. 040 * </ul> 041 * 042 * The adapter is responsible for mapping column coordinates. 043 * 044 * All input column 045 * indices are in model coordinates with exactly two exceptions: 046 * <ul> 047 * <li> {@link #column} in column view coordinates 048 * <li> the mapping method viewToModel(columnIndex) in view coordinates 049 * </ul> 050 * 051 * All input row indices are in model coordinates with exactly two exceptions: 052 * <ul> 053 * <li> {@link #row} in row view coordinates 054 * <li> the access method for the filtered value takes the row in view coordinates. 055 * </ul> 056 * 057 * 058 * @author Ramesh Gupta 059 */ 060 public abstract class ComponentAdapter { 061 /** current row in view coordinates. */ 062 public int row = 0; 063 /** current column in view coordinates. */ 064 public int column = 0; 065 protected final JComponent target; 066 067 /** 068 * Constructs a ComponentAdapter, setting the specified component as the 069 * target component. 070 * 071 * @param component target component for this adapter 072 */ 073 public ComponentAdapter(JComponent component) { 074 target = component; 075 } 076 077 public JComponent getComponent() { 078 return target; 079 } 080 081 //---------------------------- accessing the target's model 082 083 /** 084 * returns the column's label (= headerValue). 085 * 086 * Used f.i. in SearchPanel to fill the field with the 087 * column name. 088 * 089 * Note: it's up to the implementation to decide for which 090 * columns it returns a name - most will do so for the 091 * subset with isTestable = true. 092 * 093 * @param columnIndex in model coordinates 094 * @return column name or null if not found/not testable. 095 */ 096 public abstract String getColumnName(int columnIndex); 097 098 /** 099 * returns the logical name (== identifier) of the column at 100 * columnIndex in model coordinates. 101 * 102 * Used f.i. JNTable to store and apply column properties by identifier. 103 * 104 * Note: it's up to the implementation to decide for which 105 * columns it returns a name - most will do so for the 106 * subset with isTestable = true. 107 * 108 * @param columnIndex in model coordinates 109 * @return the String value of the column identifier at columnIndex 110 * or null if no identifier set 111 */ 112 public abstract String getColumnIdentifier(int columnIndex); 113 114 /** 115 * Returns the number of columns in the target's data model. 116 * 117 * @return the number of columns in the target's data model. 118 */ 119 public int getColumnCount() { 120 return 1; // default for combo-boxes, lists, and trees 121 } 122 123 /** 124 * Returns the number of rows in the target's data model. 125 * 126 * @return the number of rows in the target's data model. 127 */ 128 public int getRowCount() { 129 return 0; 130 } 131 132 /** 133 * Returns the value of the target component's cell identified by the 134 * specified row and column in model coordinates. 135 * 136 * @param row in model coordinates 137 * @param column in model coordinates 138 * @return the value of the target component's cell identified by the 139 * specified row and column 140 */ 141 public abstract Object getValueAt(int row, int column); 142 public abstract void setValueAt(Object aValue, int row, int column); 143 144 public abstract boolean isCellEditable(int row, int column); 145 146 /** 147 * returns true if the column should be included in testing. 148 * Here: returns true if visible (that is modelToView gives a valid 149 * view column coordinate). 150 * 151 * @param column in model coordinates 152 * @return true if the column should be included in testing 153 */ 154 public boolean isTestable(int column) { 155 return modelToView(column) >= 0; 156 } 157 158 //----------------------- accessing the target's view state 159 160 /** 161 * Returns the value of the cell identified by this adapter by invoking 162 * {@link #getValueAt(int, int)}, passing in the {@link #row} and 163 * {@link #column} values of this adapter. For target components that don't 164 * support multiple columns, the value of <code>column</code> is always zero. 165 * 166 * PENDING: needs clarification/cleanup - getValueAt(row, column) expects 167 * model coordinates!. 168 * 169 * @return the value of the cell identified by this adapter 170 */ 171 public Object getValue() { 172 return getValueAt(row, column); 173 } 174 175 /** 176 * returns the filtered value of the cell identified by the row 177 * in view coordinate and the column in model coordinates. 178 * 179 * Note: the asymetry of the coordinates is intentional - clients like 180 * Highlighters are interested in view values but might need to access 181 * non-visible columns for testing. 182 * 183 * @param row 184 * @param column 185 * @return the filtered value of the cell identified by the row 186 * in view coordinate and the column in model coordiantes 187 */ 188 public abstract Object getFilteredValueAt(int row, int column); 189 190 /** 191 * Returns true if the cell identified by this adapter currently has focus; 192 * Otherwise, it returns false. 193 * 194 * @return true if the cell identified by this adapter currently has focus; 195 * Otherwise, return false 196 */ 197 public abstract boolean hasFocus(); 198 199 /** 200 * Returns true if the cell identified by this adapter is currently selected; 201 * Otherwise, it returns false. 202 * 203 * @return true if the cell identified by this adapter is currently selected; 204 * Otherwise, return false 205 */ 206 public abstract boolean isSelected(); 207 208 /** 209 * Returns true if the cell identified by this adapter is currently expanded; 210 * Otherwise, it returns false. For components that do not support 211 * hierarchical data, this method always returns true because the cells in 212 * such components can never be collapsed. 213 * 214 * @return true if the cell identified by this adapter is currently expanded; 215 * Otherwise, return false 216 */ 217 public boolean isExpanded() { 218 return true; // sensible default for JList and JTable 219 } 220 221 /** 222 * Returns true if the cell identified by this adapter is a leaf node; 223 * Otherwise, it returns false. For components that do not support 224 * hierarchical data, this method always returns true because the cells in 225 * such components can never have children. 226 * 227 * @return true if the cell identified by this adapter is a leaf node; 228 * Otherwise, return false 229 */ 230 public boolean isLeaf() { 231 return true; // sensible default for JList and JTable 232 } 233 234 /** 235 * Returns true if the cell identified by this adapter displays the hierarchical node; 236 * Otherwise, it returns false. For components that do not support 237 * hierarchical data, this method always returns false because the cells in 238 * such components can never have children. 239 * 240 * @return true if the cell identified by this adapter displays the hierarchical node; 241 * Otherwise, return false 242 */ 243 public boolean isHierarchical() { 244 return false; // sensible default for JList and JTable 245 } 246 247 /** 248 * For target components that support multiple columns in their model, 249 * along with column reordering in the view, this method transforms the 250 * specified columnIndex from model coordinates to view coordinates. For all 251 * other types of target components, this method returns the columnIndex 252 * unchanged. 253 * 254 * @param columnIndex index of a column in model coordinates 255 * @return index of the specified column in view coordinates 256 */ 257 public int modelToView(int columnIndex) { 258 return columnIndex; // sensible default for JList and JTree 259 } 260 261 /** 262 * For target components that support multiple columns in their model, 263 * along with column reordering in the view, this method transforms the 264 * specified columnIndex from view coordinates to model coordinates. For all 265 * other types of target components, this method returns the columnIndex 266 * unchanged. 267 * 268 * @param columnIndex index of a column in view coordinates 269 * @return index of the specified column in model coordinates 270 */ 271 public int viewToModel(int columnIndex) { 272 return columnIndex; // sensible default for JList and JTree 273 } 274 275 public void refresh() { 276 target.revalidate(); 277 target.repaint(); 278 } 279 }