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

History | View | Annotate | Download (24.8 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_NONE:
395
                default:
396
                    this.state = nextstate;
397
                    break;
398
                }
399
                break;
400
            case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
401
            case STATE_NEED_RELOAD_FEATURE_TYPE:
402
                switch(this.state) {
403
                case STATE_NEED_RELOADALL:
404
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
405
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
406
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
407
                case STATE_NEED_RELOAD_FEATURE_TYPE:
408
                    this.state = STATE_NEED_RELOAD_FEATURE_TYPE;
409
                    break;                    
410
                case STATE_NEED_SELECTION_UP:
411
                    this.state = nextstate;
412
                    this.isSelecctionUp = true;
413
                    break;
414
                case STATE_NONE:
415
                default:
416
                    this.state = nextstate;
417
                    break;
418
                }
419
                break;
420
            case STATE_NEED_SELECTION_UP:
421
                switch(this.state) {
422
                case STATE_NEED_RELOADALL:
423
                case STATE_NEED_RELOAD_IF_FEATURE_COUNT_CHANGED:
424
                case STATE_NEED_RELOAD_IF_FEATURE_UPDATED:
425
                case STATE_NEED_RELOAD_IF_FEATURE_TYPE_CHANGED:
426
                case STATE_NEED_RELOAD_FEATURE_TYPE:
427
                case STATE_NEED_SELECTION_UP:
428
                    this.isSelecctionUp = true;
429
                    break;
430
                case STATE_NONE:
431
                default:
432
                    this.state = nextstate;
433
                    this.isSelecctionUp = true;
434
                    break;
435
                }
436
                break;
437
            case STATE_NONE:
438
            default:
439
                this.state = STATE_NONE;
440
                break;
441
            }
442
            if( this.state != STATE_NONE ) {
443
                this.start();
444
            }
445
        }
446
        
447
    }
448
    
449
    private DelayAction delayAction = new DelayAction();
450
            
451
    public void update(final Observable observable, final Object notification) {
452
        if (notification instanceof ComplexNotification) {
453
            // A lot of things might have happened in the store, so don't
454
            // bother looking into each notification.
455
            this.delayAction.nextState(DelayAction.STATE_NEED_RELOADALL);
456
//            reloadAll();
457
        } else if (observable.equals(getFeatureStore())
458
                && notification instanceof FeatureStoreNotification) {
459
            FeatureStoreNotification fsNotification
460
                    = (FeatureStoreNotification) notification;
461
            String type = fsNotification.getType();
462

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

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

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

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

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

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

    
523
    protected String[] getHiddenColumnNames() {
524
        return null;
525
    }
526
    
527
    /**
528
     * Returns the FeatureStore of the Collection.
529
     * 
530
     * @return the FeatureStore
531
     */
532
    public FeatureStore getFeatureStore() {
533
        return getHelper().getFeatureStore();
534
    }
535

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

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

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

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

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

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

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

    
614
    /**
615
     * Reloads the table data if a feature has been changed, not through the
616
     * table.
617
     */
618
    private void reloadIfFeatureCountChanged(Feature feature) {
619
        // Is any data is changed in the FeatureStore, notify the model
620
        // listeners. Ignore the case where the updated feature is
621
        // changed through us.
622
        if (editableFeature == null || !editableFeature.equals(feature)) {
623
            reloadFeatures();            
624
            fireTableDataChanged();
625
        }
626
    }
627
    
628
    private void reloadIfFeatureUpdated(Feature feature) {
629
        // Is any data is changed in the FeatureStore, notify the model
630
        // listeners. Ignore the case where the updated feature is
631
        // changed through us.
632
        if (editableFeature == null || !editableFeature.equals(feature)) {
633
            reloadFeatures();
634
            fireTableChanged(new TableModelEvent(this, 0, getRowCount()));            
635
        }
636
    }
637

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

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

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

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