KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > swing > decorator > Filter


1 /*
2  * $Id: Filter.java,v 1.2 2005/02/18 11:22:47 kleopatra Exp $
3  *
4  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5  * Santa Clara, California 95054, U.S.A. All rights reserved.
6  */

7
8 package org.jdesktop.swing.decorator;
9
10 /**
11  * <p>A <b><code>Filter</code></b> is used to filter the data presented in a
12  * data-aware component such as a {@link org.jdesktop.swing.JXList} or a
13  * {@link org.jdesktop.swing.JXTable}. Filtering involves interposing one or
14  * more filters in a {@link org.jdesktop.swing.decorator.FilterPipeline} between
15  * a data model and a view to change the apparent order and/or number of records
16  * in the data model.</p>
17  *
18  * @author Ramesh Gupta
19  * @see org.jdesktop.swing.decorator.FilterPipeline
20  * @see org.jdesktop.swing.JXTable
21  */

22 public abstract class Filter {
23     private final int column; // in model coordinates
24
private FilterPipeline pipeline = null;
25     protected ComponentAdapter adapter = null; /** @todo make private */
26     int order = -1; // package private
27

28     /**
29      * Constructs a new filter for the first column of a data model (in model coordinates).
30      */

31     public Filter() {
32         this(0);
33     }
34
35     /**
36      * Constructs a new filter for the specified column of a data model (in model coordinates).
37      *
38      * @param col column index in model coordinates
39      */

40     public Filter(int col) {
41         column = col;
42         init();
43     }
44
45     /**
46      * Provides filter-specific initialization. Called from the <code>Filter</code>
47      * constructor.
48      */

49     protected abstract void init();
50
51     /**
52      * Resets the internal row mappings from this filter to the previous filter.
53      */

54     protected abstract void reset();
55
56     /**
57      * Generates the row mappings from the previous filter to this filter.
58      */

59     protected abstract void generateMappingFromPrevious();
60
61     /**
62      * Performs the filter operation defined by this filter.
63      */

64     protected abstract void filter();
65
66     /**
67      * Refreshes the internal state of the filter, performs the {@link #filter() filter}
68      * operation and regenerates row mappings from the previous filter. If this
69      * filter is bound to a filter pipeline (as most filters are), it also triggers a
70      * {@link org.jdesktop.swing.decorator.FilterPipeline#filterChanged(org.jdesktop.swing.decorator.Filter) filterChanged}
71      * notification.
72      */

73     public void refresh() {
74         refresh(true);
75     }
76
77     /**
78      * Refreshes the internal state of the filter, optionally resetting the
79      * cache of existing row mappings from this filter to the previous filter.
80      * Always performs the {@link #filter() filter} operation and regenerates
81      * row mappings from the previous filter. If this filter is bound to a filter
82      * pipeline (as most filters are), it also triggers a
83      * {@link org.jdesktop.swing.decorator.FilterPipeline#filterChanged(org.jdesktop.swing.decorator.Filter) filterChanged}
84      * notification.
85      *
86      * @param reset true if existing row mappings from this filter to the previous
87      * filter should be reset; false, if the existing row mappings should be preserved.
88      */

89     protected void refresh(boolean reset) {
90         if (reset) {
91             reset();
92         }
93
94         filter();
95         generateMappingFromPrevious();
96
97         // trigger direct notification; will cascade to next in pipeline, if any
98
if (pipeline != null) {
99             if (pipeline.contains(this)) {
100                 pipeline.filterChanged(this);
101                 return;
102             }
103         }
104         if (adapter != null) {
105             adapter.refresh();
106         }
107     }
108
109     /**
110      * Binds this filter to the specified <code>ComponentAdapter</code>.
111      * Called by {@link org.jdesktop.swing.decorator.FilterPipeline#bind(org.jdesktop.swing.decorator.ComponentAdapter) FilterPipeline.bind()}.
112      *
113      * @param adapter adapter that this filter is bound to
114      */

115     final void assign(ComponentAdapter adapter) {
116         if (adapter == null) {
117             throw new IllegalArgumentException JavaDoc("null adapter");
118         }
119
120         if (this.adapter == null) {
121             this.adapter = adapter;
122         }
123         else if (this.adapter != adapter){
124             throw new IllegalStateException JavaDoc("Already bound to another adapter");
125         }
126     }
127
128     /**
129      * Binds this filter to the specified filter pipeline.
130      * Called by {@link org.jdesktop.swing.decorator.FilterPipeline#bind(org.jdesktop.swing.decorator.ComponentAdapter) FilterPipeline.bind()}.
131      *
132      * @param pipeline the filter pipeline that this filter is bound to
133      */

134     final void assign(FilterPipeline pipeline) {
135         /** NOTE: JXTable.resetSorter may pass in null for filter pipeline!
136         if (pipeline == null) {
137             throw new IllegalArgumentException("null pipeline");
138         }
139         */

140
141         if ((this.pipeline == null) || (pipeline == null)) {
142             this.pipeline = pipeline;
143         }
144         else if (this.pipeline != pipeline) {
145             throw new IllegalStateException JavaDoc("Already bound to another pipeline");
146         }
147     }
148
149 /*
150     protected boolean memberOf(FilterPipeline pipeline) {
151         if (order < 0) {
152             return false;
153         }
154
155         return pipeline == null ? false : pipeline.isMember(this);
156     }
157 */

158     protected FilterPipeline getPipeline() {
159         return pipeline;
160     }
161
162     /**
163      * Returns the model index of the column that this filter has been bound to.
164      *
165      * @return the model index of the column that this filter has been bound to
166      */

167     public int getColumnIndex() {
168         return column; // model coordinates
169
}
170
171     public String JavaDoc getColumnName() {
172         if (adapter == null) {
173             return "Column " + column; // in model coordinates :-(
174
}
175         else {
176             int viewColumnIndex = adapter.modelToView(getColumnIndex());
177             return viewColumnIndex < 0 ?
178                 "" : adapter.getColumnName(viewColumnIndex);
179         }
180     }
181
182 /*
183     public void contentsChanged(PipelineEvent ev) {
184         // Do nothing
185     }
186 */

187
188     /**
189      * Convert row index from view coordinates to model coordinates
190      * accounting for the presence of sorters and filters.
191      *
192      * @param row row index in view coordinates
193      * @return row index in model coordinates
194      */

195     public int convertRowIndexToModel(int row) {
196         if ((order == 0) || (pipeline == null)) {
197             return translateToPreviousFilter(row);
198         }
199         else {
200             return pipeline.convertRowIndexToModel(this, translateToPreviousFilter(row));
201         }
202     }
203
204     /**
205      * Convert row index from model coordinates to view coordinates
206      * accounting for the presence of sorters and filters.
207      *
208      * @param row row index in model coordinates
209      * @return row index in view coordinates
210      */

211     public int convertRowIndexToView(int row) {
212         if ((order == 0) || (pipeline == null)) {
213             return translateFromPreviousFilter(row);
214         }
215         else {
216             return translateFromPreviousFilter(pipeline.convertRowIndexToView(this, row));
217         }
218     }
219
220     /**
221      * Returns the number of records that remain in this filter's "view"
222      * after the input records have been filtered.
223      *
224      * @return the number of records that remain in this filter's "view"
225      * after the input records have been filtered
226      */

227     public abstract int getSize();
228
229     /**
230      * Returns the row in this filter that maps to the specified row in the
231      * previous filter. If there is no previous filter in the pipeline, this returns
232      * the row in this filter that maps to the specified row in the data model.
233      * This method is called from
234      * {@link org.jdesktop.swing.decorator.Filter#convertRowIndexToView(int) convertRowIndexToView}
235      *
236      * @param row a row index in the previous filter's "view" of the data model
237      * @return the row in this filter that maps to the specified row in
238      * the previous filter
239      */

240     protected abstract int translateFromPreviousFilter(int row);
241
242     /**
243      * Returns the row in the previous filter that maps to the specified row in
244      * this filter. If there is no previous filter in the pipeline, this returns
245      * the row in the data model that maps to the specified row in this filter.
246      * This method is called from
247      * {@link org.jdesktop.swing.decorator.Filter#convertRowIndexToModel(int) convertRowIndexToModel}
248      *
249      * @param row a row index in this filter's "view" of the data model
250      * @return the row in the previous filter that maps to the specified row in
251      * this filter
252      */

253     protected abstract int translateToPreviousFilter(int row);
254
255     /**
256      * Returns the value at the specified row and column.
257      *
258      * @param row row index in view coordinates
259      * @param column column index in model coordinates
260      * @return the value at the specified row and column
261      */

262     public Object JavaDoc getValueAt(int row, int column) {
263         if ((order == 0) || (pipeline == null)) {
264             return adapter.getValueAt(translateToPreviousFilter(row), adapter.modelToView(column));
265         }
266         else {
267             return pipeline.getInputValueFor(this, translateToPreviousFilter(row), column);
268         }
269     }
270
271     /**
272      * Sets the specified value as the new value for the cell identified by the
273      * specified row and column index.
274      *
275      * @param aValue new value for the specified cell
276      * @param row row index in view coordinates
277      * @param column column index in model coordinates
278      */

279     public void setValueAt(Object JavaDoc aValue, int row, int column) {
280         if ((order == 0) || (pipeline == null)) {
281             adapter.setValueAt(aValue, translateToPreviousFilter(row), adapter.modelToView(column));
282         }
283         else {
284             pipeline.setInputValueFor(aValue, this, translateToPreviousFilter(row), column);
285         }
286     }
287
288     public boolean isCellEditable(int row, int column) {
289         if ((order == 0) || (pipeline == null)) {
290             return adapter.isCellEditable(translateToPreviousFilter(row), adapter.modelToView(column));
291         }
292         else {
293             return pipeline.isInputEditableFor(this, translateToPreviousFilter(row), column);
294         }
295     }
296
297     /**
298      * Returns the number of records that are processed by this filter.
299      *
300      * @return the number of records that are processed by this filter
301      */

302     protected int getInputSize() {
303         return pipeline == null ? adapter == null ?
304                 0 : adapter.getRowCount() : pipeline.getInputSize(this);
305     }
306
307     /**
308      * Returns the value of the cell at the specified row and column (in model coordinates).
309      *
310      * @param row in the coordinates of what is the filter's "view" of the model
311      * @param column in model coordinates
312      * @return the value of the cell at the specified row and column (in model coordinates)
313      */

314     protected Object JavaDoc getInputValue(int row, int column) {
315         if (pipeline != null) {
316             return pipeline.getInputValueFor(this, row, column);
317         }
318         else if (adapter != null) {
319             return adapter.getValueAt(row, adapter.modelToView(column));
320         }
321
322         return null;
323     }
324
325 }
326
327
Popular Tags