Statistics
| Revision:

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 / FeatureTableModel.java @ 42775

History | View | Annotate | Download (26.1 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
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 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * 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 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
/*
25
 * AUTHORS (In addition to CIT):
26
 * 2008 {DiSiD Technologies}  {Create a JTable TableModel for a FeatureCollection}
27
 */
28
package org.gvsig.fmap.mapcontrol.dal.feature.swing.table;
29
30 41822 jjdelcerro
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32 42639 dmartinezizquierdo
33 41822 jjdelcerro
import javax.swing.SwingUtilities;
34
import javax.swing.Timer;
35 40435 jjdelcerro
import javax.swing.event.TableModelEvent;
36
import javax.swing.table.AbstractTableModel;
37 42639 dmartinezizquierdo
38 40435 jjdelcerro
import org.gvsig.fmap.dal.DALLocator;
39 42775 jjdelcerro
import org.gvsig.fmap.dal.EditingNotification;
40
import org.gvsig.fmap.dal.EditingNotificationManager;
41 40435 jjdelcerro
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.feature.EditableFeature;
43
import org.gvsig.fmap.dal.feature.Feature;
44
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.FeatureQuery;
46
import org.gvsig.fmap.dal.feature.FeatureStore;
47
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
48
import org.gvsig.fmap.dal.feature.FeatureType;
49
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
50
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
51 42775 jjdelcerro
import org.gvsig.fmap.dal.swing.DALSwingLocator;
52 40435 jjdelcerro
import org.gvsig.tools.exception.BaseException;
53
import org.gvsig.tools.observer.ComplexNotification;
54
import org.gvsig.tools.observer.ComplexObserver;
55
import org.gvsig.tools.observer.Observable;
56
import org.slf4j.Logger;
57
import org.slf4j.LoggerFactory;
58
59
/**
60
 * TableModel to access data of Features.
61 42454 dmartinezizquierdo
 *
62 40435 jjdelcerro
 * This table model can't handle a FeatureSet with more than Integer.MAX_VALUE
63
 * elements. In that case, only the first Integer.MAX_VALUE elements will be
64
 * shown.
65 42454 dmartinezizquierdo
 *
66 40435 jjdelcerro
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
67
 */
68
public class FeatureTableModel extends AbstractTableModel implements ComplexObserver {
69
70 42454 dmartinezizquierdo
71 41822 jjdelcerro
        private static final Logger logger = LoggerFactory
72 40435 jjdelcerro
                        .getLogger(FeatureTableModel.class);
73 42454 dmartinezizquierdo
74 40435 jjdelcerro
    private static final long serialVersionUID = -2488157521902851301L;
75
76
    private FeaturePagingHelper helper;
77
78
    /** Used to know if a modification in the FeatureStore is created by us. */
79
    private EditableFeature editableFeature;
80
81 42639 dmartinezizquierdo
    private boolean selectionLocked=false;
82
83 40435 jjdelcerro
    /**
84
     * Constructs a TableModel from the features of a FeatureStore, with the
85
     * default page size.
86 42454 dmartinezizquierdo
     *
87 40435 jjdelcerro
     * @param featureStore
88
     *            to extract the features from
89
     * @param featureQuery
90
     *            the query to get the features from the store
91
     * @throws BaseException
92
     *             if there is an error reading data from the FeatureStore
93
     */
94
    public FeatureTableModel(FeatureStore featureStore,
95
        FeatureQuery featureQuery) throws BaseException {
96
        this(featureStore, featureQuery, FeaturePagingHelper.DEFAULT_PAGE_SIZE);
97
    }
98
99
    /**
100
     * Constructs a TableModel from the features of a FeatureStore, with the
101
     * default page size.
102 42454 dmartinezizquierdo
     *
103 40435 jjdelcerro
     * @param featureStore
104
     *            to extract the features from
105
     * @param featureQuery
106
     *            the query to get the features from the store
107
     * @param pageSize
108
     *            the number of elements per page data
109
     * @throws BaseException
110
     *             if there is an error reading data from the FeatureStore
111
     */
112
    public FeatureTableModel(FeatureStore featureStore,
113
        FeatureQuery featureQuery, int pageSize) throws BaseException {
114
        this(DALLocator.getDataManager().createFeaturePagingHelper(
115
            featureStore, featureQuery, pageSize));
116
    }
117
118
    /**
119
     * Constructs a TableModel from a FeatureCollection and a Paging helper.
120 42454 dmartinezizquierdo
     *
121 40435 jjdelcerro
     * @param featureCollection
122
     *            to extract data from
123
     * @param helper
124
     *            the paging helper
125
     * @throws DataException
126
     *             if there is an error reading data from the FeatureStore
127
     */
128
    protected FeatureTableModel(FeaturePagingHelper helper) {
129
        this.helper = helper;
130
        initialize();
131
    }
132
133
    public int getColumnCount() {
134
        // Return the number of fields of the Features
135
        FeatureType featureType = getFeatureType();
136
        return featureType.size();
137
    }
138
139
    public int getRowCount() {
140
        // Return the total size of the collection
141
        // If the size is bigger than INTEGER.MAX_VALUE, return that instead
142
            try {
143
                long totalSize = getHelper().getTotalSize();
144
                if (totalSize > Integer.MAX_VALUE) {
145
                    return Integer.MAX_VALUE;
146
                } else {
147
                    return (int) totalSize;
148
                }
149
            } catch (ConcurrentDataModificationException e) {
150 41822 jjdelcerro
                        logger.debug("Error while getting the total size of the set", e);
151 40435 jjdelcerro
                        return 0;
152
                }
153
    }
154
155
    public Object getValueAt(int rowIndex, int columnIndex) {
156
        // Get the Feature at row "rowIndex", and return the value of the
157
        // attribute at "columnIndex"
158
        Feature feature = getFeatureAt(rowIndex);
159
        return feature == null ? null : getFeatureValue(feature, columnIndex);
160
    }
161
162
    /**
163
     * Returns the value for a row position.
164 42454 dmartinezizquierdo
     *
165 40435 jjdelcerro
     * @param rowIndex
166
     *            the row position
167
     * @return the Feature
168
     */
169
    public Feature getFeatureAt(int rowIndex) {
170
        try {
171
            return getHelper().getFeatureAt(rowIndex);
172
        } catch (BaseException ex) {
173
            throw new GetFeatureAtException(rowIndex, ex);
174
        }
175
    }
176
177
    public Class<?> getColumnClass(int columnIndex) {
178
        // Return the class of the FeatureAttributeDescriptor for the value
179
        FeatureAttributeDescriptor attributeDesc =
180
            internalGetFeatureDescriptorForColumn(columnIndex);
181
        if (attributeDesc == null) {
182
                return super.getColumnClass(columnIndex);
183
        }
184
        Class<?> clazz = attributeDesc.getObjectClass();
185
        return (clazz == null ? super.getColumnClass(columnIndex) : clazz);
186
    }
187
188
    public String getColumnName(int column) {
189
        // Return the Feature attribute name
190
        FeatureAttributeDescriptor attributeDesc =
191
            internalGetFeatureDescriptorForColumn(column);
192
        return attributeDesc.getName();
193
    }
194
195
    @Override
196
    public boolean isCellEditable(int rowIndex, int columnIndex) {
197
        if (getFeatureStore().isEditing()) {
198
            FeatureAttributeDescriptor attributeDesc =
199
                internalGetFeatureDescriptorForColumn(columnIndex);
200
            return !attributeDesc.isReadOnly();
201
        }
202
203
        return false;
204
    }
205
206
    @Override
207
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
208
        // Get the feature at rowIndex
209
        Feature feature = getFeatureAt(rowIndex);
210
        // Only set the value if the feature exists
211
        if (feature != null) {
212
            // We only need to update if the value to set is not equal to the
213
            // current value
214
            Object currentValue = getFeatureValue(feature, columnIndex);
215
            if (value != currentValue
216
                && (value == null || !value.equals(currentValue))) {
217
                try {
218
                    // Store the editable feature to ignore the related store
219
                    // change notification
220
                    editableFeature =
221
                        setFeatureValue(feature, columnIndex, value);
222 42775 jjdelcerro
                    EditingNotificationManager editingNotificationManager = DALSwingLocator.getEditingNotificationManager();
223 41335 jjdelcerro
                    EditingNotification notification = editingNotificationManager.notifyObservers(
224 42454 dmartinezizquierdo
                            this,
225
                            EditingNotification.BEFORE_UPDATE_FEATURE,
226 41323 jjdelcerro
                            null,
227
                            this.getHelper().getFeatureStore(),
228
                            editableFeature);
229
                    if( notification.isCanceled() ) {
230
                        return;
231
                    }
232 41335 jjdelcerro
                    if( notification.shouldValidateTheFeature() ) {
233
                        if ( !editingNotificationManager.validateFeature(feature) ) {
234
                            return;
235
                        }
236 42454 dmartinezizquierdo
                    }
237 40435 jjdelcerro
                    this.getHelper().update(editableFeature);
238
                    // We'll have already received the event, so we can forget
239
                    // about it
240
                    getHelper().reloadCurrentPage();
241
                    fireTableCellUpdated(rowIndex, columnIndex);
242 42454 dmartinezizquierdo
243 41335 jjdelcerro
                    editingNotificationManager.notifyObservers(
244 42454 dmartinezizquierdo
                            this,
245
                            EditingNotification.AFTER_UPDATE_FEATURE,
246 41323 jjdelcerro
                            null,
247
                            this.getHelper().getFeatureStore(),
248
                            editableFeature);
249
                    editableFeature = null;
250 42454 dmartinezizquierdo
251 40435 jjdelcerro
                } catch (BaseException ex) {
252
                    throw new SetFeatureValueException(rowIndex, columnIndex,
253
                        value, ex);
254
                } finally {
255
                    // Just in case
256
                    editableFeature = null;
257
                }
258
            }
259
        }
260
    }
261
262
    /**
263
     * Returns a reference to the Paging Helper used to load the data from the
264
     * DataStore.
265 42454 dmartinezizquierdo
     *
266 40435 jjdelcerro
     * @return the paging helper
267
     */
268
    public FeaturePagingHelper getHelper() {
269
        return helper;
270
    }
271
272
    /**
273
     * Sets the FeatureType to show in the table. Used for FeatureStores with
274
     * many simultaneous FeatureTypes supported. Will cause a reload of the
275
     * current data.
276 42454 dmartinezizquierdo
     *
277 40435 jjdelcerro
     * @param featureType
278
     *            the FeatureType of the Features
279
     * @throws DataException
280
     *             if there is an error loading the data
281
     */
282
    public void setFeatureType(FeatureType featureType) {
283
        getFeatureQuery().setFeatureType(featureType);
284
        reloadFeatures();
285 42639 dmartinezizquierdo
        //Selection must be locked to avoid losing it when the table is refreshed
286
        selectionLocked=true;
287
        //The table is refreshed
288
        try {
289
            fireTableStructureChanged();
290
        } catch (Exception e) {
291
            logger.warn("Couldn't reload changed table");
292
        }finally{
293
            //The locked selection is unlocked.
294
            selectionLocked=false;
295
        }
296 40435 jjdelcerro
    }
297
298
    /**
299
     * Sets that the selected Features get returned first.
300
     */
301
    public void setSelectionUp(boolean selectionUp) {
302
        getHelper().setSelectionUp(selectionUp);
303
        fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1));
304
    }
305
306 41822 jjdelcerro
    private class DelayAction extends Timer implements ActionListener, Runnable {
307
        private static final int STATE_NONE = 0;
308
        private static final int STATE_NEED_RELOADALL = 1;
309
        private static final int STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED = 2;
310
        private static final int STATE_NEED_RELOAD_IF_FEATURE_UPDATED = 4;
311
        private static final int STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED = 8;
312
        private static final int STATE_NEED_RELOAD_FEATURE_TYPE = 16;
313
        private static final int STATE_NEED_SELECTION_UP = 32;
314 42456 dmartinezizquierdo
        private static final int STATE_NEED_RELOAD_ALL_FEATURES=64;
315 42454 dmartinezizquierdo
316 41822 jjdelcerro
        private int state = STATE_NONE;
317
        private Feature feature;
318
        private FeatureType featureType;
319
        private boolean isSelecctionUp;
320 42454 dmartinezizquierdo
321 41822 jjdelcerro
        public DelayAction() {
322
            super(1000,null);
323
            this.setRepeats(false);
324
            this.reset();
325
            this.addActionListener(this);
326
        }
327
328
        public void reset() {
329
            this.state = STATE_NONE;
330
            this.isSelecctionUp = false;
331
            this.feature = null;
332
            this.featureType = null;
333
        }
334
335
        public void actionPerformed(ActionEvent ae) {
336
            this.run();
337
        }
338 42454 dmartinezizquierdo
339 41822 jjdelcerro
        public void run() {
340
            if( !SwingUtilities.isEventDispatchThread() ) {
341
                SwingUtilities.invokeLater(this);
342
                return;
343
            }
344
            this.stop();
345
            logger.info("DelayAction.run["+this.state+"] begin");
346
            switch(this.state) {
347
            case STATE_NEED_RELOADALL:
348
                reloadAll();
349
                break;
350
            case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
351
                reloadIfFeatureCountChanged(feature);
352
                break;
353
            case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
354
                reloadIfFeatureUpdated(feature);
355
                break;
356
            case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
357
                reloadIfTypeChanged(featureType);
358
                break;
359
            case STATE_NEED_RELOAD_FEATURE_TYPE:
360
                reloadFeatureType();
361
                updatePaginHelperWithHiddenColums();
362
                break;
363 42456 dmartinezizquierdo
            case STATE_NEED_RELOAD_ALL_FEATURES:
364
                reloadFeatures();
365
                fireTableChanged(new TableModelEvent(FeatureTableModel.this, 0, getRowCount()));
366
                break;
367 41822 jjdelcerro
            case STATE_NEED_SELECTION_UP:
368
            case STATE_NONE:
369
            default:
370
                break;
371
            }
372
            if( isSelecctionUp ) {
373
                getHelper().setSelectionUp(true);
374
            }
375
            this.reset();
376
            logger.info("DelayAction.run["+this.state+"] end");
377
        }
378 42454 dmartinezizquierdo
379 41822 jjdelcerro
        public void nextState(int nextstate) {
380
            this.nextState(nextstate, null, null);
381
        }
382 42454 dmartinezizquierdo
383 41822 jjdelcerro
        public void nextState(int nextstate, Feature feature) {
384
            this.nextState(nextstate, feature, null);
385
        }
386 42454 dmartinezizquierdo
387 41822 jjdelcerro
        public void nextState(int nextstate, FeatureType featureType) {
388
            this.nextState(nextstate, null, featureType);
389
        }
390 42454 dmartinezizquierdo
391 41822 jjdelcerro
        public void nextState(int nextstate, Feature feature, FeatureType featureType) {
392 41904 jjdelcerro
            this.feature = feature;
393
            this.featureType = featureType;
394 41822 jjdelcerro
            switch(nextstate) {
395
            case STATE_NEED_RELOADALL:
396
            case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
397
            case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
398
                switch(this.state) {
399
                case STATE_NEED_RELOADALL:
400
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
401 42454 dmartinezizquierdo
                //case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
402 41822 jjdelcerro
                    this.state = STATE_NEED_RELOADALL;
403
                    break;
404
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
405
                case STATE_NEED_RELOAD_FEATURE_TYPE:
406
                    this.state = STATE_NEED_RELOAD_FEATURE_TYPE;
407 42454 dmartinezizquierdo
                    break;
408 42456 dmartinezizquierdo
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
409
                case STATE_NEED_RELOAD_ALL_FEATURES:
410
                    this.state=STATE_NEED_RELOAD_ALL_FEATURES;
411
                    break;
412 41822 jjdelcerro
                case STATE_NEED_SELECTION_UP:
413 42163 jbadia
                    this.state = nextstate;
414 41822 jjdelcerro
                    this.isSelecctionUp = true;
415
                    break;
416
                case STATE_NONE:
417
                default:
418
                    this.state = nextstate;
419
                    break;
420
                }
421
                break;
422
            case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
423
            case STATE_NEED_RELOAD_FEATURE_TYPE:
424
                switch(this.state) {
425
                case STATE_NEED_RELOADALL:
426
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
427
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
428 42456 dmartinezizquierdo
                case STATE_NEED_RELOAD_ALL_FEATURES:
429 41822 jjdelcerro
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
430
                case STATE_NEED_RELOAD_FEATURE_TYPE:
431
                    this.state = STATE_NEED_RELOAD_FEATURE_TYPE;
432 42454 dmartinezizquierdo
                    break;
433 41822 jjdelcerro
                case STATE_NEED_SELECTION_UP:
434 42163 jbadia
                    this.state = nextstate;
435 41822 jjdelcerro
                    this.isSelecctionUp = true;
436
                    break;
437
                case STATE_NONE:
438
                default:
439 41904 jjdelcerro
                    this.state = nextstate;
440 41822 jjdelcerro
                    break;
441
                }
442
                break;
443
            case STATE_NEED_SELECTION_UP:
444
                switch(this.state) {
445
                case STATE_NEED_RELOADALL:
446
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
447
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
448
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
449 42456 dmartinezizquierdo
                case STATE_NEED_RELOAD_ALL_FEATURES:
450 41822 jjdelcerro
                case STATE_NEED_RELOAD_FEATURE_TYPE:
451
                case STATE_NEED_SELECTION_UP:
452
                    this.isSelecctionUp = true;
453
                    break;
454
                case STATE_NONE:
455
                default:
456 42163 jbadia
                    this.state = nextstate;
457 41822 jjdelcerro
                    this.isSelecctionUp = true;
458
                    break;
459
                }
460
                break;
461
            case STATE_NONE:
462
            default:
463
                this.state = STATE_NONE;
464
                break;
465
            }
466
            if( this.state != STATE_NONE ) {
467
                this.start();
468
            }
469
        }
470 42454 dmartinezizquierdo
471 41822 jjdelcerro
    }
472 42454 dmartinezizquierdo
473 41822 jjdelcerro
    private DelayAction delayAction = new DelayAction();
474 42454 dmartinezizquierdo
475 40435 jjdelcerro
    public void update(final Observable observable, final Object notification) {
476 41212 jjdelcerro
        if (notification instanceof ComplexNotification) {
477
            // A lot of things might have happened in the store, so don't
478
            // bother looking into each notification.
479 41822 jjdelcerro
            this.delayAction.nextState(DelayAction.STATE_NEED_RELOADALL);
480
//            reloadAll();
481 41212 jjdelcerro
        } else if (observable.equals(getFeatureStore())
482
                && notification instanceof FeatureStoreNotification) {
483
            FeatureStoreNotification fsNotification
484
                    = (FeatureStoreNotification) notification;
485 40435 jjdelcerro
            String type = fsNotification.getType();
486
487
            // If there are new, updated or deleted features
488
            // reload the table data
489
            if (FeatureStoreNotification.AFTER_DELETE.equals(type)
490 41212 jjdelcerro
                    || FeatureStoreNotification.AFTER_INSERT.equals(type)) {
491 41822 jjdelcerro
//                reloadIfFeatureCountChanged(fsNotification.getFeature());
492
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED, fsNotification.getFeature());
493 40435 jjdelcerro
494
            } else if (FeatureStoreNotification.AFTER_UPDATE.equals(type)) {
495 41822 jjdelcerro
//                reloadIfFeatureUpdated(fsNotification.getFeature());
496
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_UPDATED, fsNotification.getFeature());
497 40435 jjdelcerro
498 41212 jjdelcerro
            } else if (FeatureStoreNotification.AFTER_UPDATE_TYPE.equals(type)) {
499 41822 jjdelcerro
//                reloadIfTypeChanged(fsNotification.getFeatureType());
500
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED, fsNotification.getFeatureType());
501 40435 jjdelcerro
502 41212 jjdelcerro
            } else if (FeatureStoreNotification.TRANSFORM_CHANGE.equals(type)
503
                    || FeatureStoreNotification.AFTER_UNDO.equals(type)
504 40435 jjdelcerro
                    || FeatureStoreNotification.AFTER_REDO.equals(type)
505 41212 jjdelcerro
                    || FeatureStoreNotification.AFTER_REFRESH.equals(type))  {
506 41822 jjdelcerro
//                reloadAll();
507
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOADALL);
508 40435 jjdelcerro
509 41212 jjdelcerro
            } else if (FeatureStoreNotification.AFTER_FINISHEDITING.equals(type)
510
                    || FeatureStoreNotification.AFTER_STARTEDITING.equals(type)
511
                    || FeatureStoreNotification.AFTER_CANCELEDITING.equals(type)) {
512 41250 jjdelcerro
                /*
513
                No tengo nada claro por que es necesario llamar al reloadFeatureType
514
                pero si no se incluye hay problemas si durante la edicion se a?aden
515 42454 dmartinezizquierdo
                campos a la tabla. Sin esto, al cerrar la edicion, los campos a?adidos
516 41250 jjdelcerro
                desaparecen de la tabla aunque estan en el fichero.
517
                Ver ticket #2434 https://devel.gvsig.org/redmine/issues/2434
518
                */
519 41822 jjdelcerro
//                reloadFeatureType();
520
//                updatePaginHelperWithHiddenColums();
521 41914 jjdelcerro
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_FEATURE_TYPE, fsNotification.getFeatureType());
522 41630 jjdelcerro
            } else if (FeatureStoreNotification.SELECTION_CHANGE.equals(type)) {
523
                if( this.getHelper().isSelectionUp() ) {
524 42163 jbadia
                    getHelper().setSelectionUp(true);
525 41822 jjdelcerro
                    this.delayAction.nextState(DelayAction.STATE_NEED_SELECTION_UP);
526 41630 jjdelcerro
                }
527 41212 jjdelcerro
            }
528
        }
529
    }
530 40435 jjdelcerro
531 41212 jjdelcerro
    protected void updatePaginHelperWithHiddenColums() {
532
        FeatureQuery query = this.getHelper().getFeatureQuery();
533
        if (this.getHelper().getFeatureStore().isEditing()) {
534
            if (query.hasConstantsAttributeNames()) {
535
                query.clearConstantsAttributeNames();
536
            }
537
        } else {
538
            query.setConstantsAttributeNames(this.getHiddenColumnNames());
539
        }
540
        try {
541
            this.getHelper().reload();
542
        } catch (BaseException ex) {
543 41822 jjdelcerro
            logger.warn("Can't reload paging-helper.", ex);
544 41212 jjdelcerro
        }
545 40435 jjdelcerro
    }
546
547 41212 jjdelcerro
    protected String[] getHiddenColumnNames() {
548
        return null;
549
    }
550 42454 dmartinezizquierdo
551 40435 jjdelcerro
    /**
552
     * Returns the FeatureStore of the Collection.
553 42454 dmartinezizquierdo
     *
554 40435 jjdelcerro
     * @return the FeatureStore
555
     */
556
    public FeatureStore getFeatureStore() {
557
        return getHelper().getFeatureStore();
558
    }
559
560
    /**
561
     * Returns the descriptor of a Feature attribute for a table column.
562 42454 dmartinezizquierdo
     *
563 40435 jjdelcerro
     * @param columnIndex
564
     *            the column index
565
     */
566
    public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) {
567
        return internalGetFeatureDescriptorForColumn(columnIndex);
568
    }
569
570
    /**
571
     * @param columnIndex
572
     * @return
573
     */
574
        protected FeatureAttributeDescriptor internalGetFeatureDescriptorForColumn(
575
                        int columnIndex) {
576
                FeatureType featureType = getFeatureType();
577
                return featureType == null ? null : featureType
578
                                .getAttributeDescriptor(columnIndex);
579
        }
580
581
    /**
582
     * Initialize the TableModel
583
     */
584
    protected void initialize() {
585
        // Add as observable to the FeatureStore, to detect data and selection
586
        // changes
587
        helper.getFeatureStore().addObserver(this);
588
    }
589
590
    /**
591
     * Returns the value of a Feature attribute, at the given position.
592 42454 dmartinezizquierdo
     *
593 40435 jjdelcerro
     * @param feature
594
     *            the feature to get the value from
595
     * @param columnIndex
596
     *            the Feature attribute position
597
     * @return the value
598
     */
599
    protected Object getFeatureValue(Feature feature, int columnIndex) {
600
        return feature.get(columnIndex);
601
    }
602
603
    /**
604
     * Sets the value of an Feature attribute at the given position.
605 42454 dmartinezizquierdo
     *
606 40435 jjdelcerro
     * @param feature
607
     *            the feature to update
608
     * @param columnIndex
609
     *            the attribute position
610
     * @param value
611
     *            the value to set
612
     * @throws IsNotFeatureSettingException
613
     *             if there is an error setting the value
614
     */
615
    protected EditableFeature setFeatureValue(Feature feature, int columnIndex,
616
        Object value) {
617
        EditableFeature editableFeature = feature.getEditable();
618
        editableFeature.set(columnIndex, value);
619
        return editableFeature;
620
    }
621
622
    /**
623
     * Returns the FeatureQuery used to get the Features.
624 42454 dmartinezizquierdo
     *
625 40435 jjdelcerro
     * @return the FeatureQuery
626
     */
627
    public FeatureQuery getFeatureQuery() {
628
        return getHelper().getFeatureQuery();
629
    }
630
631
    /**
632
     * Returns the type of the features.
633
     */
634 41707 jjdelcerro
    protected FeatureType getFeatureType() {
635 40435 jjdelcerro
        return getHelper().getFeatureType();
636
    }
637
638
    /**
639
     * Reloads the table data if a feature has been changed, not through the
640
     * table.
641
     */
642
    private void reloadIfFeatureCountChanged(Feature feature) {
643
        // Is any data is changed in the FeatureStore, notify the model
644
        // listeners. Ignore the case where the updated feature is
645
        // changed through us.
646
        if (editableFeature == null || !editableFeature.equals(feature)) {
647 42454 dmartinezizquierdo
            reloadFeatures();
648 42639 dmartinezizquierdo
            //Selection must be locked to avoid losing it when the table is refreshed
649
            selectionLocked=true;
650
            //The table is refreshed
651
            try {
652
                fireTableDataChanged();
653
            } catch (Exception e) {
654
                logger.warn("Couldn't reload changed table");
655
            }finally{
656
                //The locked selection is unlocked.
657
                selectionLocked=false;
658
            }
659 40435 jjdelcerro
        }
660
    }
661 42454 dmartinezizquierdo
662 40435 jjdelcerro
    private void reloadIfFeatureUpdated(Feature feature) {
663
        // Is any data is changed in the FeatureStore, notify the model
664
        // listeners. Ignore the case where the updated feature is
665
        // changed through us.
666
        if (editableFeature == null || !editableFeature.equals(feature)) {
667
            reloadFeatures();
668 42454 dmartinezizquierdo
            fireTableChanged(new TableModelEvent(this, 0, getRowCount()));
669 40435 jjdelcerro
        }
670
    }
671
672
    /**
673
     * Reloads data and structure if the {@link FeatureType} of the features
674
     * being shown has changed.
675
     */
676
    private void reloadIfTypeChanged(FeatureType updatedType) {
677
        // If the updated featured type is the one currently being
678
        // shown, reload the table.
679
        if (updatedType != null
680
            && updatedType.getId().equals(getFeatureType().getId())) {
681
            setFeatureType(updatedType);
682
        }
683
    }
684
685
    private void reloadAll() {
686
            reloadFeatureType();
687
    }
688
689
    private void reloadFeatureType() {
690
        try {
691
            setFeatureType(getHelper().getFeatureStore().getFeatureType(
692
                getHelper().getFeatureType().getId()));
693
        } catch (DataException e) {
694
            throw new FeaturesDataReloadException(e);
695
        }
696
    }
697
698
    /**
699
     * Reloads the features shown on the table.
700
     */
701
    private void reloadFeatures() {
702
        try {
703
            getHelper().reload();
704
        } catch (BaseException ex) {
705
            throw new FeaturesDataReloadException(ex);
706
        }
707
    }
708 42639 dmartinezizquierdo
709
    /**
710
     * Returns true if selection must not be changed.
711
     * @return
712
     */
713
    public boolean isSelectionLocked() {
714
        return selectionLocked;
715
    }
716
717 40435 jjdelcerro
}