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 }