svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.fmap.control / src / main / java / org / gvsig / fmap / mapcontrol / dal / feature / swing / table / ConfigurableFeatureTableModel.java @ 45308
History | View | Annotate | Download (18 KB)
1 |
/**
|
---|---|
2 |
* gvSIG. Desktop Geographic Information System.
|
3 |
*
|
4 |
* Copyright (C) 2007-2013 gvSIG Association.
|
5 |
*
|
6 |
* This program is free software; you can redistribute it and/or
|
7 |
* modify it under the terms of the GNU General Public License
|
8 |
* as published by the Free Software Foundation; either version 3
|
9 |
* of the License, or (at your option) any later version.
|
10 |
*
|
11 |
* This program is distributed in the hope that it will be useful,
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14 |
* GNU General Public License for more details.
|
15 |
*
|
16 |
* You should have received a copy of the GNU General Public License
|
17 |
* along with this program; if not, write to the Free Software
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
19 |
* MA 02110-1301, USA.
|
20 |
*
|
21 |
* For any additional information, do not hesitate to contact us
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com.
|
23 |
*/
|
24 |
/*
|
25 |
* AUTHORS (In addition to CIT):
|
26 |
* 2008 {DiSiD Technologies} {Create a JTable TableModel for a FeatureQuery}
|
27 |
*/
|
28 |
package org.gvsig.fmap.mapcontrol.dal.feature.swing.table; |
29 |
|
30 |
import java.security.InvalidParameterException; |
31 |
import java.text.SimpleDateFormat; |
32 |
import java.util.ArrayList; |
33 |
import java.util.HashMap; |
34 |
import java.util.Iterator; |
35 |
import java.util.List; |
36 |
import java.util.Locale; |
37 |
import java.util.Map; |
38 |
|
39 |
import javax.swing.event.TableModelEvent; |
40 |
import org.apache.commons.lang3.StringUtils; |
41 |
|
42 |
import org.gvsig.fmap.dal.DataTypes; |
43 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
44 |
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor; |
45 |
import org.gvsig.fmap.dal.feature.Feature; |
46 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
47 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
48 |
import org.gvsig.fmap.dal.feature.FeatureQueryOrder; |
49 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
50 |
import org.gvsig.fmap.dal.feature.FeatureType; |
51 |
import org.gvsig.tools.exception.BaseException; |
52 |
import org.slf4j.Logger; |
53 |
import org.slf4j.LoggerFactory; |
54 |
|
55 |
/**
|
56 |
* Extends the FeatureTableModel to add more configurable options, like the
|
57 |
* visible columns, column name aliases and row order.
|
58 |
*
|
59 |
* TODO: a?adir la persistencia.
|
60 |
*
|
61 |
* @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
|
62 |
*/
|
63 |
public class ConfigurableFeatureTableModel extends FeatureTableModel { |
64 |
|
65 |
private static final long serialVersionUID = -8223987814719746492L; |
66 |
|
67 |
private static final Logger logger = LoggerFactory.getLogger(ConfigurableFeatureTableModel.class); |
68 |
|
69 |
private List<String> columnNames; |
70 |
|
71 |
private List<String> visibleColumnNames; |
72 |
|
73 |
private List<String> visibleColumnNamesOriginal; |
74 |
|
75 |
private Map<String, String> name2Alias; |
76 |
|
77 |
private Map<String, String> name2AliasOriginal; |
78 |
|
79 |
private Map<String,String> patterns = null; |
80 |
|
81 |
private Locale localeOfData; |
82 |
/**
|
83 |
* @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery)
|
84 |
*/
|
85 |
public ConfigurableFeatureTableModel(FeatureStore featureStore,
|
86 |
FeatureQuery featureQuery) throws BaseException {
|
87 |
super(featureStore, featureQuery);
|
88 |
this.localeOfData = Locale.getDefault(); |
89 |
} |
90 |
|
91 |
/**
|
92 |
* @see FeatureTableModel#FeatureTableModel(FeatureStore, FeatureQuery, int)
|
93 |
*/
|
94 |
public ConfigurableFeatureTableModel(FeatureStore featureStore,
|
95 |
FeatureQuery featureQuery, int pageSize) throws BaseException { |
96 |
super(featureStore, featureQuery, pageSize);
|
97 |
} |
98 |
|
99 |
@Override
|
100 |
public int getColumnCount() { |
101 |
return visibleColumnNames.size();
|
102 |
} |
103 |
|
104 |
public int getOriginalColumnCount() { |
105 |
return super.getColumnCount(); |
106 |
} |
107 |
|
108 |
@Override
|
109 |
public String getColumnName(int column) { |
110 |
try {
|
111 |
int originalIndex = getOriginalColumnIndex(column);
|
112 |
return getAliasForColumn(getOriginalColumnName(originalIndex));
|
113 |
} catch (Exception ex) { |
114 |
return "C" + column; |
115 |
} |
116 |
} |
117 |
|
118 |
@Override
|
119 |
public Class<?> getColumnClass(int columnIndex) { |
120 |
int originalIndex = getOriginalColumnIndex(columnIndex);
|
121 |
return super.getColumnClass(originalIndex); |
122 |
} |
123 |
|
124 |
@Override
|
125 |
public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) { |
126 |
int originalIndex = getOriginalColumnIndex(columnIndex);
|
127 |
return super.getDescriptorForColumn(originalIndex); |
128 |
} |
129 |
|
130 |
/**
|
131 |
* Returns the original name of the column, ignoring the alias.
|
132 |
*
|
133 |
* @param column
|
134 |
* the original index of the column
|
135 |
* @return the original column name
|
136 |
*/
|
137 |
public String getOriginalColumnName(int column) { |
138 |
return super.getColumnName(column); |
139 |
} |
140 |
|
141 |
/**
|
142 |
* Sets the visibility of a table column.
|
143 |
*
|
144 |
* @param columnIndex
|
145 |
* the index of the column to update
|
146 |
* @param visible
|
147 |
* if the column will be visible or not
|
148 |
*/
|
149 |
public void setVisible(String name, boolean visible) { |
150 |
// If we don't have already the column as visible,
|
151 |
// add to the list, without order, and recreate
|
152 |
// the visible columns list in the original order
|
153 |
if (!columnNames.contains(name)) {
|
154 |
throw new InvalidParameterException(name); // FIXME |
155 |
} |
156 |
if (visible && !visibleColumnNames.contains(name)) {
|
157 |
visibleColumnNames.add(name); |
158 |
setVisibleColumns(visibleColumnNames); |
159 |
} else {
|
160 |
visibleColumnNames.remove(name); |
161 |
setVisibleColumns(visibleColumnNames); |
162 |
fireTableStructureChanged(); |
163 |
} |
164 |
|
165 |
} |
166 |
|
167 |
@Override
|
168 |
public void setFeatureType(FeatureType featureType) { |
169 |
// Check if there is a new column name
|
170 |
List<String> newColumns = new ArrayList<String>(); |
171 |
List<String> renamedColumnsNewName = new ArrayList<String>(); |
172 |
|
173 |
@SuppressWarnings("unchecked") |
174 |
Iterator<FeatureAttributeDescriptor> attrIter = featureType.iterator();
|
175 |
FeatureAttributeDescriptor fad = null;
|
176 |
EditableFeatureAttributeDescriptor efad = null;
|
177 |
|
178 |
String colName;
|
179 |
while (attrIter.hasNext()) {
|
180 |
fad = attrIter.next(); |
181 |
colName = fad.getName(); |
182 |
if (!columnNames.contains(colName)) {
|
183 |
if (fad instanceof EditableFeatureAttributeDescriptor) { |
184 |
efad = (EditableFeatureAttributeDescriptor) fad; |
185 |
/*
|
186 |
* If editable att descriptor,
|
187 |
* check original name
|
188 |
*/
|
189 |
if (efad.getOriginalName() != null) { |
190 |
if (!columnNames.contains(efad.getOriginalName())) {
|
191 |
/*
|
192 |
* Check with original name but add current name
|
193 |
*/
|
194 |
newColumns.add(colName); |
195 |
} else {
|
196 |
/*
|
197 |
* List of new names of renamed columns
|
198 |
*/
|
199 |
renamedColumnsNewName.add(colName); |
200 |
} |
201 |
} else {
|
202 |
newColumns.add(colName); |
203 |
} |
204 |
} else {
|
205 |
newColumns.add(colName); |
206 |
} |
207 |
} |
208 |
} |
209 |
|
210 |
// Update column names
|
211 |
columnNames.clear(); |
212 |
@SuppressWarnings("unchecked") |
213 |
Iterator<FeatureAttributeDescriptor> visibleAttrIter =
|
214 |
featureType.iterator(); |
215 |
while (visibleAttrIter.hasNext()) {
|
216 |
fad = visibleAttrIter.next(); |
217 |
colName = fad.getName(); |
218 |
columnNames.add(colName); |
219 |
//If the column is added has to be visible
|
220 |
if (!visibleColumnNames.contains(colName)) {
|
221 |
|
222 |
if (((newColumns.contains(colName)
|
223 |
|| renamedColumnsNewName.contains(colName))) |
224 |
&& |
225 |
fad.getType() != DataTypes.GEOMETRY) { |
226 |
// Add new columns and renamed
|
227 |
visibleColumnNames.add(colName); |
228 |
visibleColumnNamesOriginal.add(colName); |
229 |
} |
230 |
/*
|
231 |
if (renamedColumnsNewName.contains(colName)) {
|
232 |
// Add renamed
|
233 |
insertWhereOldName(visibleColumnNames, colName, fad);
|
234 |
insertWhereOldName(visibleColumnNamesOriginal, colName, fad);
|
235 |
}
|
236 |
*/
|
237 |
} |
238 |
} |
239 |
|
240 |
// remove from visible columns removed columns
|
241 |
visibleColumnNames = intersectKeepOrder(columnNames, visibleColumnNames); |
242 |
// instead of: visibleColumnNames.retainAll(columnNames);
|
243 |
|
244 |
visibleColumnNamesOriginal = intersectKeepOrder(columnNames, visibleColumnNamesOriginal); |
245 |
// instead of: visibleColumnNamesOriginal.retainAll(columnNames);
|
246 |
|
247 |
// remove from alias map removed columns
|
248 |
name2Alias.keySet().retainAll(columnNames); |
249 |
name2AliasOriginal.keySet().retainAll(columnNames); |
250 |
|
251 |
super.setFeatureType(featureType);
|
252 |
|
253 |
} |
254 |
|
255 |
/**
|
256 |
* keeps order of first parameter
|
257 |
*
|
258 |
* @param lista
|
259 |
* @param listb
|
260 |
* @return
|
261 |
*/
|
262 |
private List<String> intersectKeepOrder(List<String> lista, List<String> listb) { |
263 |
|
264 |
List<String> resp = new ArrayList<String>(); |
265 |
resp.addAll(lista); |
266 |
resp.retainAll(listb); |
267 |
return resp;
|
268 |
} |
269 |
|
270 |
private void insertWhereOldNamee( |
271 |
List<String> str_list, |
272 |
String str,
|
273 |
FeatureAttributeDescriptor fad) { |
274 |
|
275 |
if (fad instanceof EditableFeatureAttributeDescriptor) { |
276 |
EditableFeatureAttributeDescriptor efad = |
277 |
(EditableFeatureAttributeDescriptor) fad; |
278 |
if (efad.getOriginalName() != null) { |
279 |
int old_ind = str_list.indexOf(efad.getOriginalName());
|
280 |
if (old_ind != -1) { |
281 |
// Insert before old name
|
282 |
str_list.add(old_ind, str); |
283 |
} else {
|
284 |
// Insert anyway (add)
|
285 |
str_list.add(str); |
286 |
} |
287 |
} else {
|
288 |
// Insert anyway (add)
|
289 |
str_list.add(str); |
290 |
} |
291 |
} else {
|
292 |
// Insert anyway (add)
|
293 |
str_list.add(str); |
294 |
} |
295 |
} |
296 |
|
297 |
/**
|
298 |
* Sets the current visible columns list, in the original order.
|
299 |
*
|
300 |
* @param names
|
301 |
* the names of the columns to set as visible
|
302 |
*/
|
303 |
public void setVisibleColumns(List<String> names) { |
304 |
// Recreate the visible column names list
|
305 |
// to maintain the original order
|
306 |
visibleColumnNames = new ArrayList<String>(names.size()); |
307 |
for (int i = 0; i < columnNames.size(); i++) { |
308 |
String columnName = columnNames.get(i);
|
309 |
if (names.contains(columnName)) {
|
310 |
visibleColumnNames.add(columnName); |
311 |
} |
312 |
} |
313 |
updatePaginHelperWithHiddenColums(); |
314 |
fireTableStructureChanged(); |
315 |
} |
316 |
|
317 |
protected String[] getHiddenColumnNames() { |
318 |
List<String> hiddenColumns = new ArrayList<String>(); |
319 |
hiddenColumns.addAll(columnNames); |
320 |
|
321 |
for (int i = 0; i < visibleColumnNames.size(); i++) { |
322 |
String columnName = visibleColumnNames.get(i);
|
323 |
hiddenColumns.remove(columnName); |
324 |
} |
325 |
if( hiddenColumns.size()<1 ) { |
326 |
return null; |
327 |
} |
328 |
return (String[]) hiddenColumns.toArray(new String[hiddenColumns.size()]); |
329 |
} |
330 |
|
331 |
/**
|
332 |
* Changes all columns to be visible.
|
333 |
*/
|
334 |
public void setAllVisible() { |
335 |
visibleColumnNames.clear(); |
336 |
visibleColumnNames.addAll(columnNames); |
337 |
fireTableStructureChanged(); |
338 |
} |
339 |
|
340 |
/**
|
341 |
* Sets the alias for a column.
|
342 |
*
|
343 |
* @param name
|
344 |
* the name of the column
|
345 |
* @param alias
|
346 |
* the alias for the column
|
347 |
*/
|
348 |
public void setAlias(String name, String alias) { |
349 |
name2Alias.put(name, alias); |
350 |
fireTableStructureChanged(); |
351 |
} |
352 |
|
353 |
public void orderByColumn(String name, boolean ascending) |
354 |
throws BaseException {
|
355 |
FeatureQueryOrder order = getHelper().getFeatureQuery().getOrder(); |
356 |
order.clear(); |
357 |
order.add(name, ascending); |
358 |
getHelper().reload(); |
359 |
fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1)); |
360 |
} |
361 |
|
362 |
@Override
|
363 |
protected void initialize() { |
364 |
super.initialize();
|
365 |
|
366 |
initializeVisibleColumns(); |
367 |
initializeAliases(); |
368 |
updatePaginHelperWithHiddenColums(); |
369 |
} |
370 |
|
371 |
/**
|
372 |
* Returns if a column is visible.
|
373 |
*
|
374 |
* @param name
|
375 |
* the name of the column
|
376 |
* @return if the column is visible
|
377 |
*/
|
378 |
public boolean isVisible(String name) { |
379 |
return visibleColumnNames.contains(name);
|
380 |
} |
381 |
|
382 |
/**
|
383 |
* Initializes the table name aliases.
|
384 |
*/
|
385 |
private void initializeAliases() { |
386 |
int columns = super.getColumnCount(); |
387 |
name2Alias = new HashMap<String, String>(columns); |
388 |
name2AliasOriginal = new HashMap<String, String>(columns); |
389 |
} |
390 |
|
391 |
/**
|
392 |
* Initializes the table visible columns.
|
393 |
*/
|
394 |
protected void initializeVisibleColumns() { |
395 |
int columns = super.getColumnCount(); |
396 |
columnNames = new ArrayList<String>(columns); |
397 |
visibleColumnNames = new ArrayList<String>(columns); |
398 |
|
399 |
for (int i = 0; i < columns; i++) { |
400 |
String columnName = super.getColumnName(i); |
401 |
columnNames.add(columnName); |
402 |
|
403 |
// By default, geometry columns will not be visible
|
404 |
FeatureAttributeDescriptor descriptor = |
405 |
super.getDescriptorForColumn(i);
|
406 |
switch(descriptor.getType()) {
|
407 |
case DataTypes.GEOMETRY:
|
408 |
case DataTypes.BYTEARRAY:
|
409 |
case DataTypes.LIST:
|
410 |
case DataTypes.DYNOBJECT:
|
411 |
case DataTypes.MAP:
|
412 |
break;
|
413 |
default:
|
414 |
if( !descriptor.isHidden() ) {
|
415 |
visibleColumnNames.add(columnName); |
416 |
} |
417 |
} |
418 |
} |
419 |
|
420 |
visibleColumnNamesOriginal = new ArrayList<String>(visibleColumnNames); |
421 |
} |
422 |
|
423 |
/**
|
424 |
* Returns the alias for the name of a column.
|
425 |
*
|
426 |
* @param name
|
427 |
* of the column
|
428 |
* @return the alias
|
429 |
*/
|
430 |
protected String getAliasForColumn(String name) { |
431 |
String alias = name2Alias.get(name);
|
432 |
return alias == null ? name : alias; |
433 |
} |
434 |
|
435 |
/**
|
436 |
* Returns the original position of a column.
|
437 |
*
|
438 |
* @param columnIndex
|
439 |
* the current visible column index
|
440 |
* @return the original column index
|
441 |
*/
|
442 |
public int getOriginalColumnIndex(int columnIndex) { |
443 |
String columnName = visibleColumnNames.get(columnIndex);
|
444 |
return columnNames.indexOf(columnName);
|
445 |
} |
446 |
|
447 |
@Override
|
448 |
protected Object getFeatureValue(Feature feature, int columnIndex) { |
449 |
int realColumnIndex = getOriginalColumnIndex(columnIndex);
|
450 |
return super.getFeatureValue(feature, realColumnIndex); |
451 |
} |
452 |
|
453 |
@Override
|
454 |
protected EditableFeature setFeatureValue(Feature feature, int columnIndex, |
455 |
Object value) {
|
456 |
int realColumnIndex = getOriginalColumnIndex(columnIndex);
|
457 |
return super.setFeatureValue(feature, realColumnIndex, value); |
458 |
} |
459 |
|
460 |
/**
|
461 |
* Make current changes in configuration (visible columns and aliases)
|
462 |
* as definitive.
|
463 |
*/
|
464 |
public void acceptChanges() { |
465 |
visibleColumnNamesOriginal = new ArrayList<String>(visibleColumnNames); |
466 |
name2AliasOriginal = new HashMap<String, String>(name2Alias); |
467 |
} |
468 |
|
469 |
/**
|
470 |
* Cancel current changes in configuration (visible columns and aliases)
|
471 |
* and return to previous status.
|
472 |
*/
|
473 |
public void cancelChanges() { |
474 |
visibleColumnNames = new ArrayList<String>(visibleColumnNamesOriginal); |
475 |
name2Alias = new HashMap<String, String>(name2AliasOriginal); |
476 |
fireTableStructureChanged(); |
477 |
} |
478 |
|
479 |
protected void initializeFormattingPatterns() { |
480 |
this.patterns = new HashMap<String, String>(); |
481 |
|
482 |
int columns = super.getColumnCount(); |
483 |
|
484 |
for (int i = 0; i < columns; i++) { |
485 |
String columnName = super.getColumnName(i); |
486 |
initializeFormattingPattern(columnName); |
487 |
} |
488 |
} |
489 |
|
490 |
protected void initializeFormattingPattern(String columnName) { |
491 |
FeatureAttributeDescriptor descriptor = |
492 |
this.getFeatureType().getAttributeDescriptor(columnName);
|
493 |
|
494 |
switch(descriptor.getDataType().getType()) {
|
495 |
case DataTypes.BYTE:
|
496 |
case DataTypes.INT:
|
497 |
case DataTypes.LONG:
|
498 |
String defaultIntegerPattern = "#,##0"; |
499 |
this.patterns.put(columnName,defaultIntegerPattern);
|
500 |
break;
|
501 |
case DataTypes.DOUBLE:
|
502 |
String defaultDoublePattern = "#,##0.0000000000"; |
503 |
this.patterns.put(columnName,defaultDoublePattern);
|
504 |
break;
|
505 |
case DataTypes.FLOAT:
|
506 |
String defaultFloatPattern = "#,##0.0000"; |
507 |
this.patterns.put(columnName,defaultFloatPattern);
|
508 |
break;
|
509 |
case DataTypes.DATE:
|
510 |
String defaultDatePattern = new SimpleDateFormat().toPattern(); |
511 |
this.patterns.put(columnName,defaultDatePattern);
|
512 |
break;
|
513 |
default:
|
514 |
this.patterns.put(columnName,null); |
515 |
} |
516 |
} |
517 |
|
518 |
public String getFormattingPattern(int column) { |
519 |
String columnName = this.visibleColumnNames.get(column); |
520 |
return this.getFormattingPattern(columnName); |
521 |
} |
522 |
|
523 |
public String getFormattingPattern(String columnName) { |
524 |
if( this.patterns==null ) { |
525 |
initializeFormattingPatterns(); |
526 |
} |
527 |
String pattern = this.patterns.get(columnName); |
528 |
if( StringUtils.isBlank(pattern) ) {
|
529 |
initializeFormattingPattern(columnName); |
530 |
} |
531 |
return pattern;
|
532 |
} |
533 |
|
534 |
public void setFormattingPattern(String columnName, String pattern) { |
535 |
if( this.patterns==null ) { |
536 |
initializeFormattingPatterns(); |
537 |
} |
538 |
this.patterns.put(columnName,pattern);
|
539 |
} |
540 |
|
541 |
public Locale getLocaleOfData() { |
542 |
return this.localeOfData; |
543 |
} |
544 |
|
545 |
public void setLocaleOfData(Locale locale) { |
546 |
this.localeOfData = locale;
|
547 |
} |
548 |
|
549 |
|
550 |
} |