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 @ 42454

History | View | Annotate | Download (24.6 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 FeatureCollection}
27
 */
28
package org.gvsig.fmap.mapcontrol.dal.feature.swing.table;
29

    
30
import java.awt.event.ActionEvent;
31
import java.awt.event.ActionListener;
32
import javax.swing.SwingUtilities;
33
import javax.swing.Timer;
34
import javax.swing.event.TableModelEvent;
35
import javax.swing.table.AbstractTableModel;
36
import org.gvsig.editing.EditingNotification;
37
import org.gvsig.editing.EditingNotificationManager;
38

    
39
import org.gvsig.fmap.dal.DALLocator;
40
import org.gvsig.fmap.dal.exception.DataException;
41
import org.gvsig.fmap.dal.feature.EditableFeature;
42
import org.gvsig.fmap.dal.feature.Feature;
43
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
44
import org.gvsig.fmap.dal.feature.FeatureQuery;
45
import org.gvsig.fmap.dal.feature.FeatureStore;
46
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
47
import org.gvsig.fmap.dal.feature.FeatureType;
48
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
49
import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper;
50
import org.gvsig.fmap.mapcontrol.MapControlLocator;
51
import org.gvsig.tools.exception.BaseException;
52
import org.gvsig.tools.observer.ComplexNotification;
53
import org.gvsig.tools.observer.ComplexObserver;
54
import org.gvsig.tools.observer.Observable;
55
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
57

    
58
/**
59
 * TableModel to access data of Features.
60
 *
61
 * This table model can't handle a FeatureSet with more than Integer.MAX_VALUE
62
 * elements. In that case, only the first Integer.MAX_VALUE elements will be
63
 * shown.
64
 *
65
 * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
66
 */
67
public class FeatureTableModel extends AbstractTableModel implements ComplexObserver {
68

    
69

    
70
        private static final Logger logger = LoggerFactory
71
                        .getLogger(FeatureTableModel.class);
72

    
73
    private static final long serialVersionUID = -2488157521902851301L;
74

    
75
    private FeaturePagingHelper helper;
76

    
77
    /** Used to know if a modification in the FeatureStore is created by us. */
78
    private EditableFeature editableFeature;
79

    
80
    /**
81
     * Constructs a TableModel from the features of a FeatureStore, with the
82
     * default page size.
83
     *
84
     * @param featureStore
85
     *            to extract the features from
86
     * @param featureQuery
87
     *            the query to get the features from the store
88
     * @throws BaseException
89
     *             if there is an error reading data from the FeatureStore
90
     */
91
    public FeatureTableModel(FeatureStore featureStore,
92
        FeatureQuery featureQuery) throws BaseException {
93
        this(featureStore, featureQuery, FeaturePagingHelper.DEFAULT_PAGE_SIZE);
94
    }
95

    
96
    /**
97
     * Constructs a TableModel from the features of a FeatureStore, with the
98
     * default page size.
99
     *
100
     * @param featureStore
101
     *            to extract the features from
102
     * @param featureQuery
103
     *            the query to get the features from the store
104
     * @param pageSize
105
     *            the number of elements per page data
106
     * @throws BaseException
107
     *             if there is an error reading data from the FeatureStore
108
     */
109
    public FeatureTableModel(FeatureStore featureStore,
110
        FeatureQuery featureQuery, int pageSize) throws BaseException {
111
        this(DALLocator.getDataManager().createFeaturePagingHelper(
112
            featureStore, featureQuery, pageSize));
113
    }
114

    
115
    /**
116
     * Constructs a TableModel from a FeatureCollection and a Paging helper.
117
     *
118
     * @param featureCollection
119
     *            to extract data from
120
     * @param helper
121
     *            the paging helper
122
     * @throws DataException
123
     *             if there is an error reading data from the FeatureStore
124
     */
125
    protected FeatureTableModel(FeaturePagingHelper helper) {
126
        this.helper = helper;
127
        initialize();
128
    }
129

    
130
    public int getColumnCount() {
131
        // Return the number of fields of the Features
132
        FeatureType featureType = getFeatureType();
133
        return featureType.size();
134
    }
135

    
136
    public int getRowCount() {
137
        // Return the total size of the collection
138
        // If the size is bigger than INTEGER.MAX_VALUE, return that instead
139
            try {
140
                long totalSize = getHelper().getTotalSize();
141
                if (totalSize > Integer.MAX_VALUE) {
142
                    return Integer.MAX_VALUE;
143
                } else {
144
                    return (int) totalSize;
145
                }
146
            } catch (ConcurrentDataModificationException e) {
147
                        logger.debug("Error while getting the total size of the set", e);
148
                        return 0;
149
                }
150
    }
151

    
152
    public Object getValueAt(int rowIndex, int columnIndex) {
153
        // Get the Feature at row "rowIndex", and return the value of the
154
        // attribute at "columnIndex"
155
        Feature feature = getFeatureAt(rowIndex);
156
        return feature == null ? null : getFeatureValue(feature, columnIndex);
157
    }
158

    
159
    /**
160
     * Returns the value for a row position.
161
     *
162
     * @param rowIndex
163
     *            the row position
164
     * @return the Feature
165
     */
166
    public Feature getFeatureAt(int rowIndex) {
167
        try {
168
            return getHelper().getFeatureAt(rowIndex);
169
        } catch (BaseException ex) {
170
            throw new GetFeatureAtException(rowIndex, ex);
171
        }
172
    }
173

    
174
    public Class<?> getColumnClass(int columnIndex) {
175
        // Return the class of the FeatureAttributeDescriptor for the value
176
        FeatureAttributeDescriptor attributeDesc =
177
            internalGetFeatureDescriptorForColumn(columnIndex);
178
        if (attributeDesc == null) {
179
                return super.getColumnClass(columnIndex);
180
        }
181
        Class<?> clazz = attributeDesc.getObjectClass();
182
        return (clazz == null ? super.getColumnClass(columnIndex) : clazz);
183
    }
184

    
185
    public String getColumnName(int column) {
186
        // Return the Feature attribute name
187
        FeatureAttributeDescriptor attributeDesc =
188
            internalGetFeatureDescriptorForColumn(column);
189
        return attributeDesc.getName();
190
    }
191

    
192
    @Override
193
    public boolean isCellEditable(int rowIndex, int columnIndex) {
194
        if (getFeatureStore().isEditing()) {
195
            FeatureAttributeDescriptor attributeDesc =
196
                internalGetFeatureDescriptorForColumn(columnIndex);
197
            return !attributeDesc.isReadOnly();
198
        }
199

    
200
        return false;
201
    }
202

    
203
    @Override
204
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
205
        // Get the feature at rowIndex
206
        Feature feature = getFeatureAt(rowIndex);
207
        // Only set the value if the feature exists
208
        if (feature != null) {
209
            // We only need to update if the value to set is not equal to the
210
            // current value
211
            Object currentValue = getFeatureValue(feature, columnIndex);
212
            if (value != currentValue
213
                && (value == null || !value.equals(currentValue))) {
214
                try {
215
                    // Store the editable feature to ignore the related store
216
                    // change notification
217
                    editableFeature =
218
                        setFeatureValue(feature, columnIndex, value);
219
                    EditingNotificationManager editingNotificationManager = MapControlLocator.getEditingNotificationManager();
220
                    EditingNotification notification = editingNotificationManager.notifyObservers(
221
                            this,
222
                            EditingNotification.BEFORE_UPDATE_FEATURE,
223
                            null,
224
                            this.getHelper().getFeatureStore(),
225
                            editableFeature);
226
                    if( notification.isCanceled() ) {
227
                        return;
228
                    }
229
                    if( notification.shouldValidateTheFeature() ) {
230
                        if ( !editingNotificationManager.validateFeature(feature) ) {
231
                            return;
232
                        }
233
                    }
234
                    this.getHelper().update(editableFeature);
235
                    // We'll have already received the event, so we can forget
236
                    // about it
237
                    getHelper().reloadCurrentPage();
238
                    fireTableCellUpdated(rowIndex, columnIndex);
239

    
240
                    editingNotificationManager.notifyObservers(
241
                            this,
242
                            EditingNotification.AFTER_UPDATE_FEATURE,
243
                            null,
244
                            this.getHelper().getFeatureStore(),
245
                            editableFeature);
246
                    editableFeature = null;
247

    
248
                } catch (BaseException ex) {
249
                    throw new SetFeatureValueException(rowIndex, columnIndex,
250
                        value, ex);
251
                } finally {
252
                    // Just in case
253
                    editableFeature = null;
254
                }
255
            }
256
        }
257
    }
258

    
259
    /**
260
     * Returns a reference to the Paging Helper used to load the data from the
261
     * DataStore.
262
     *
263
     * @return the paging helper
264
     */
265
    public FeaturePagingHelper getHelper() {
266
        return helper;
267
    }
268

    
269
    /**
270
     * Sets the FeatureType to show in the table. Used for FeatureStores with
271
     * many simultaneous FeatureTypes supported. Will cause a reload of the
272
     * current data.
273
     *
274
     * @param featureType
275
     *            the FeatureType of the Features
276
     * @throws DataException
277
     *             if there is an error loading the data
278
     */
279
    public void setFeatureType(FeatureType featureType) {
280
        getFeatureQuery().setFeatureType(featureType);
281
        reloadFeatures();
282
        fireTableStructureChanged();
283
    }
284

    
285
    /**
286
     * Sets that the selected Features get returned first.
287
     */
288
    public void setSelectionUp(boolean selectionUp) {
289
        getHelper().setSelectionUp(selectionUp);
290
        fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1));
291
    }
292

    
293
    private class DelayAction extends Timer implements ActionListener, Runnable {
294
        private static final int STATE_NONE = 0;
295
        private static final int STATE_NEED_RELOADALL = 1;
296
        private static final int STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED = 2;
297
        private static final int STATE_NEED_RELOAD_IF_FEATURE_UPDATED = 4;
298
        private static final int STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED = 8;
299
        private static final int STATE_NEED_RELOAD_FEATURE_TYPE = 16;
300
        private static final int STATE_NEED_SELECTION_UP = 32;
301

    
302
        private int state = STATE_NONE;
303
        private Feature feature;
304
        private FeatureType featureType;
305
        private boolean isSelecctionUp;
306

    
307
        public DelayAction() {
308
            super(1000,null);
309
            this.setRepeats(false);
310
            this.reset();
311
            this.addActionListener(this);
312
        }
313

    
314
        public void reset() {
315
            this.state = STATE_NONE;
316
            this.isSelecctionUp = false;
317
            this.feature = null;
318
            this.featureType = null;
319
        }
320

    
321
        public void actionPerformed(ActionEvent ae) {
322
            this.run();
323
        }
324

    
325
        public void run() {
326
            if( !SwingUtilities.isEventDispatchThread() ) {
327
                SwingUtilities.invokeLater(this);
328
                return;
329
            }
330
            this.stop();
331
            logger.info("DelayAction.run["+this.state+"] begin");
332
            switch(this.state) {
333
            case STATE_NEED_RELOADALL:
334
                reloadAll();
335
                break;
336
            case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
337
                reloadIfFeatureCountChanged(feature);
338
                break;
339
            case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
340
                reloadIfFeatureUpdated(feature);
341
                break;
342
            case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
343
                reloadIfTypeChanged(featureType);
344
                break;
345
            case STATE_NEED_RELOAD_FEATURE_TYPE:
346
                reloadFeatureType();
347
                updatePaginHelperWithHiddenColums();
348
                break;
349
            case STATE_NEED_SELECTION_UP:
350
            case STATE_NONE:
351
            default:
352
                break;
353
            }
354
            if( isSelecctionUp ) {
355
                getHelper().setSelectionUp(true);
356
            }
357
            this.reset();
358
            logger.info("DelayAction.run["+this.state+"] end");
359
        }
360

    
361
        public void nextState(int nextstate) {
362
            this.nextState(nextstate, null, null);
363
        }
364

    
365
        public void nextState(int nextstate, Feature feature) {
366
            this.nextState(nextstate, feature, null);
367
        }
368

    
369
        public void nextState(int nextstate, FeatureType featureType) {
370
            this.nextState(nextstate, null, featureType);
371
        }
372

    
373
        public void nextState(int nextstate, Feature feature, FeatureType featureType) {
374
            this.feature = feature;
375
            this.featureType = featureType;
376
            switch(nextstate) {
377
            case STATE_NEED_RELOADALL:
378
            case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
379
            case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
380
                switch(this.state) {
381
                case STATE_NEED_RELOADALL:
382
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
383
                //case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
384
                    this.state = STATE_NEED_RELOADALL;
385
                    break;
386
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
387
                case STATE_NEED_RELOAD_FEATURE_TYPE:
388
                    this.state = STATE_NEED_RELOAD_FEATURE_TYPE;
389
                    break;
390
                case STATE_NEED_SELECTION_UP:
391
                    this.state = nextstate;
392
                    this.isSelecctionUp = true;
393
                    break;
394
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
395
                case STATE_NONE:
396
                default:
397
                    this.state = nextstate;
398
                    break;
399
                }
400
                break;
401
            case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
402
            case STATE_NEED_RELOAD_FEATURE_TYPE:
403
                switch(this.state) {
404
                case STATE_NEED_RELOADALL:
405
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
406
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
407
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
408
                case STATE_NEED_RELOAD_FEATURE_TYPE:
409
                    this.state = STATE_NEED_RELOAD_FEATURE_TYPE;
410
                    break;
411
                case STATE_NEED_SELECTION_UP:
412
                    this.state = nextstate;
413
                    this.isSelecctionUp = true;
414
                    break;
415
                case STATE_NONE:
416
                default:
417
                    this.state = nextstate;
418
                    break;
419
                }
420
                break;
421
            case STATE_NEED_SELECTION_UP:
422
                switch(this.state) {
423
                case STATE_NEED_RELOADALL:
424
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
425
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
426
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
427
                case STATE_NEED_RELOAD_FEATURE_TYPE:
428
                case STATE_NEED_SELECTION_UP:
429
                    this.isSelecctionUp = true;
430
                    break;
431
                case STATE_NONE:
432
                default:
433
                    this.state = nextstate;
434
                    this.isSelecctionUp = true;
435
                    break;
436
                }
437
                break;
438
            case STATE_NONE:
439
            default:
440
                this.state = STATE_NONE;
441
                break;
442
            }
443
            if( this.state != STATE_NONE ) {
444
                this.start();
445
            }
446
        }
447

    
448
    }
449

    
450
    private DelayAction delayAction = new DelayAction();
451

    
452
    public void update(final Observable observable, final Object notification) {
453
        if (notification instanceof ComplexNotification) {
454
            // A lot of things might have happened in the store, so don't
455
            // bother looking into each notification.
456
            this.delayAction.nextState(DelayAction.STATE_NEED_RELOADALL);
457
//            reloadAll();
458
        } else if (observable.equals(getFeatureStore())
459
                && notification instanceof FeatureStoreNotification) {
460
            FeatureStoreNotification fsNotification
461
                    = (FeatureStoreNotification) notification;
462
            String type = fsNotification.getType();
463

    
464
            // If there are new, updated or deleted features
465
            // reload the table data
466
            if (FeatureStoreNotification.AFTER_DELETE.equals(type)
467
                    || FeatureStoreNotification.AFTER_INSERT.equals(type)) {
468
//                reloadIfFeatureCountChanged(fsNotification.getFeature());
469
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED, fsNotification.getFeature());
470

    
471
            } else if (FeatureStoreNotification.AFTER_UPDATE.equals(type)) {
472
//                reloadIfFeatureUpdated(fsNotification.getFeature());
473
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_UPDATED, fsNotification.getFeature());
474

    
475
            } else if (FeatureStoreNotification.AFTER_UPDATE_TYPE.equals(type)) {
476
//                reloadIfTypeChanged(fsNotification.getFeatureType());
477
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED, fsNotification.getFeatureType());
478

    
479
            } else if (FeatureStoreNotification.TRANSFORM_CHANGE.equals(type)
480
                    || FeatureStoreNotification.AFTER_UNDO.equals(type)
481
                    || FeatureStoreNotification.AFTER_REDO.equals(type)
482
                    || FeatureStoreNotification.AFTER_REFRESH.equals(type))  {
483
//                reloadAll();
484
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOADALL);
485

    
486
            } else if (FeatureStoreNotification.AFTER_FINISHEDITING.equals(type)
487
                    || FeatureStoreNotification.AFTER_STARTEDITING.equals(type)
488
                    || FeatureStoreNotification.AFTER_CANCELEDITING.equals(type)) {
489
                /*
490
                No tengo nada claro por que es necesario llamar al reloadFeatureType
491
                pero si no se incluye hay problemas si durante la edicion se a?aden
492
                campos a la tabla. Sin esto, al cerrar la edicion, los campos a?adidos
493
                desaparecen de la tabla aunque estan en el fichero.
494
                Ver ticket #2434 https://devel.gvsig.org/redmine/issues/2434
495
                */
496
//                reloadFeatureType();
497
//                updatePaginHelperWithHiddenColums();
498
                this.delayAction.nextState(DelayAction.STATE_NEED_RELOAD_FEATURE_TYPE, fsNotification.getFeatureType());
499
            } else if (FeatureStoreNotification.SELECTION_CHANGE.equals(type)) {
500
                if( this.getHelper().isSelectionUp() ) {
501
                    getHelper().setSelectionUp(true);
502
                    this.delayAction.nextState(DelayAction.STATE_NEED_SELECTION_UP);
503
                }
504
            }
505
        }
506
    }
507

    
508
    protected void updatePaginHelperWithHiddenColums() {
509
        FeatureQuery query = this.getHelper().getFeatureQuery();
510
        if (this.getHelper().getFeatureStore().isEditing()) {
511
            if (query.hasConstantsAttributeNames()) {
512
                query.clearConstantsAttributeNames();
513
            }
514
        } else {
515
            query.setConstantsAttributeNames(this.getHiddenColumnNames());
516
        }
517
        try {
518
            this.getHelper().reload();
519
        } catch (BaseException ex) {
520
            logger.warn("Can't reload paging-helper.", ex);
521
        }
522
    }
523

    
524
    protected String[] getHiddenColumnNames() {
525
        return null;
526
    }
527

    
528
    /**
529
     * Returns the FeatureStore of the Collection.
530
     *
531
     * @return the FeatureStore
532
     */
533
    public FeatureStore getFeatureStore() {
534
        return getHelper().getFeatureStore();
535
    }
536

    
537
    /**
538
     * Returns the descriptor of a Feature attribute for a table column.
539
     *
540
     * @param columnIndex
541
     *            the column index
542
     */
543
    public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) {
544
        return internalGetFeatureDescriptorForColumn(columnIndex);
545
    }
546

    
547
    /**
548
     * @param columnIndex
549
     * @return
550
     */
551
        protected FeatureAttributeDescriptor internalGetFeatureDescriptorForColumn(
552
                        int columnIndex) {
553
                FeatureType featureType = getFeatureType();
554
                return featureType == null ? null : featureType
555
                                .getAttributeDescriptor(columnIndex);
556
        }
557

    
558
    /**
559
     * Initialize the TableModel
560
     */
561
    protected void initialize() {
562
        // Add as observable to the FeatureStore, to detect data and selection
563
        // changes
564
        helper.getFeatureStore().addObserver(this);
565
    }
566

    
567
    /**
568
     * Returns the value of a Feature attribute, at the given position.
569
     *
570
     * @param feature
571
     *            the feature to get the value from
572
     * @param columnIndex
573
     *            the Feature attribute position
574
     * @return the value
575
     */
576
    protected Object getFeatureValue(Feature feature, int columnIndex) {
577
        return feature.get(columnIndex);
578
    }
579

    
580
    /**
581
     * Sets the value of an Feature attribute at the given position.
582
     *
583
     * @param feature
584
     *            the feature to update
585
     * @param columnIndex
586
     *            the attribute position
587
     * @param value
588
     *            the value to set
589
     * @throws IsNotFeatureSettingException
590
     *             if there is an error setting the value
591
     */
592
    protected EditableFeature setFeatureValue(Feature feature, int columnIndex,
593
        Object value) {
594
        EditableFeature editableFeature = feature.getEditable();
595
        editableFeature.set(columnIndex, value);
596
        return editableFeature;
597
    }
598

    
599
    /**
600
     * Returns the FeatureQuery used to get the Features.
601
     *
602
     * @return the FeatureQuery
603
     */
604
    public FeatureQuery getFeatureQuery() {
605
        return getHelper().getFeatureQuery();
606
    }
607

    
608
    /**
609
     * Returns the type of the features.
610
     */
611
    protected FeatureType getFeatureType() {
612
        return getHelper().getFeatureType();
613
    }
614

    
615
    /**
616
     * Reloads the table data if a feature has been changed, not through the
617
     * table.
618
     */
619
    private void reloadIfFeatureCountChanged(Feature feature) {
620
        // Is any data is changed in the FeatureStore, notify the model
621
        // listeners. Ignore the case where the updated feature is
622
        // changed through us.
623
        if (editableFeature == null || !editableFeature.equals(feature)) {
624
            reloadFeatures();
625
            fireTableDataChanged();
626
        }
627
    }
628

    
629
    private void reloadIfFeatureUpdated(Feature feature) {
630
        // Is any data is changed in the FeatureStore, notify the model
631
        // listeners. Ignore the case where the updated feature is
632
        // changed through us.
633
        if (editableFeature == null || !editableFeature.equals(feature)) {
634
            reloadFeatures();
635
            fireTableChanged(new TableModelEvent(this, 0, getRowCount()));
636
        }
637
    }
638

    
639
    /**
640
     * Reloads data and structure if the {@link FeatureType} of the features
641
     * being shown has changed.
642
     */
643
    private void reloadIfTypeChanged(FeatureType updatedType) {
644
        // If the updated featured type is the one currently being
645
        // shown, reload the table.
646
        if (updatedType != null
647
            && updatedType.getId().equals(getFeatureType().getId())) {
648
            setFeatureType(updatedType);
649
        }
650
    }
651

    
652
    private void reloadAll() {
653
            reloadFeatureType();
654
    }
655

    
656
    private void reloadFeatureType() {
657
        try {
658
            setFeatureType(getHelper().getFeatureStore().getFeatureType(
659
                getHelper().getFeatureType().getId()));
660
        } catch (DataException e) {
661
            throw new FeaturesDataReloadException(e);
662
        }
663
    }
664

    
665
    /**
666
     * Reloads the features shown on the table.
667
     */
668
    private void reloadFeatures() {
669
        try {
670
            getHelper().reload();
671
        } catch (BaseException ex) {
672
            throw new FeaturesDataReloadException(ex);
673
        }
674
    }
675
}