Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_controls / src / org / gvsig / fmap / mapcontrol / dal / feature / swing / FeatureSelectionModel.java @ 38564

History | View | Annotate | Download (9.66 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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 2
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
 */
22

    
23
/*
24
 * AUTHORS (In addition to CIT):
25
 * 2010 {}  {{Task}}
26
 */
27
package org.gvsig.fmap.mapcontrol.dal.feature.swing;
28

    
29
import javax.swing.ListSelectionModel;
30
import javax.swing.event.EventListenerList;
31
import javax.swing.event.ListSelectionEvent;
32
import javax.swing.event.ListSelectionListener;
33

    
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureSelection;
37
import org.gvsig.fmap.dal.feature.FeatureStore;
38
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
39
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
40
import org.gvsig.fmap.mapcontrol.dal.feature.swing.table.FeatureTableModel;
41
import org.gvsig.tools.observer.Observable;
42
import org.gvsig.tools.observer.Observer;
43
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
45

    
46
/**
47
 * @author 2010- C?sar Ordi?ana - gvSIG team
48
 */
49
public class FeatureSelectionModel implements ListSelectionModel, Observer {
50
    private static Logger LOG = 
51
        LoggerFactory.getLogger(FeatureSelectionModel.class);
52
    
53
        protected EventListenerList listenerList = new EventListenerList();
54

    
55
        private final FeatureTableModel featureTableModel;
56

    
57
        private int selectionMode = SINGLE_INTERVAL_SELECTION;
58

    
59
        private boolean isAdjusting = false;
60

    
61
        private int anchor = -1;
62

    
63
        private int lead = -1;
64
        
65
        private int currentFirst = -1;
66
        private int currentLast = -1;
67

    
68
        /**
69
         * Creates a new {@link FeatureSelectionModel} with a
70
         * {@link FeatureTableModel} used to get the {@link Feature}s by position in
71
         * the table.
72
         * 
73
         * @param featureTableModel
74
         *            to get Features from
75
         * @throws DataException
76
         *             if there is an error getting the store selection
77
         */
78
        public FeatureSelectionModel(FeatureTableModel featureTableModel)
79
                        throws DataException {
80
                this.featureTableModel = featureTableModel;
81
                this.featureTableModel.getFeatureStore().addObserver(this);
82
        }
83

    
84
        public int getAnchorSelectionIndex() {
85
                return anchor;
86
        }
87

    
88
        public int getLeadSelectionIndex() {
89
                return lead;
90
        }
91

    
92
        public int getMaxSelectionIndex() {
93
                FeatureSelection selection = getFeatureSelection();
94
                try {
95
                        if (!selection.isEmpty()) {
96
                                for (int i = featureTableModel.getRowCount() - 1; i >= 0; i--) {
97
                                        if (selection.isSelected(featureTableModel.getFeatureAt(i))) {
98
                                                return i;
99
                                        }
100
                                }
101
                        }
102
                } catch (DataException e) {
103
                        throw new SelectionChangeException(e);
104
                }
105
                return -1;
106
        }
107

    
108
        public int getMinSelectionIndex() {
109
                FeatureSelection selection = getFeatureSelection();
110
                try {
111
                        if (!selection.isEmpty()) {
112
                                for (int i = 0; i < featureTableModel.getRowCount(); i++) {
113
                                        if (selection.isSelected(featureTableModel.getFeatureAt(i))) {
114
                                                return i;
115
                                        }
116
                                }
117
                        }
118
                } catch (DataException e) {
119
                        throw new SelectionChangeException(e);
120
                }
121
                return -1;
122
        }
123

    
124
        public void insertIndexInterval(int index, int length, boolean before) {
125
                // Nothing to do
126
        }
127

    
128
        public void removeIndexInterval(int index0, int index1) {
129
                // Nothing to do
130
        }
131

    
132
        public void setAnchorSelectionIndex(int index) {
133
                this.anchor = index;
134
        }
135

    
136
        public void setLeadSelectionIndex(int index) {
137
                this.lead = index;
138
        }
139

    
140
        public void addSelectionInterval(int index0, int index1) {
141
                doWithSelection(new FeatureSelectionOperation() {
142

    
143
                        public void doWithSelection(FeatureSelection selection, int first,
144
                                        int last) throws DataException {
145
                                for (int i = first; i <= last; i++) {
146
                                        Feature feature = getFeature(i);
147
                                        if (!selection.isSelected(feature)) {
148
                                                selection.select(feature);
149
                                        }
150
                                }
151
                        }
152

    
153
                }, index0, index1, true);
154
        }
155

    
156
        public void setSelectionInterval(int index0, int index1) {
157
                doWithSelection(new FeatureSelectionOperation() {
158

    
159
                        public void doWithSelection(FeatureSelection selection, int first,
160
                                        int last) throws DataException {
161
                                selection.deselectAll();
162
                                for (int i = first; i <= last; i++) {
163
                                        Feature feature = getFeature(i);
164
                                        selection.select(feature);
165
                                }
166
                        }
167

    
168
                }, index0, index1, true);
169
        }
170

    
171
        public void removeSelectionInterval(int index0, int index1) {
172
                doWithSelection(new FeatureSelectionOperation() {
173

    
174
                        public void doWithSelection(FeatureSelection selection, int first,
175
                                        int last) throws DataException {
176
                                for (int i = first; i <= last; i++) {
177
                                        Feature feature = getFeature(i);
178
                                        if (selection.isSelected(feature)) {
179
                                                selection.deselect(feature);
180
                                        }
181
                                }
182
                        }
183

    
184
                }, index0, index1, false);
185
        }
186

    
187
        public void clearSelection() {
188
                try {
189
                        getFeatureSelection().deselectAll();
190
                } catch (DataException e) {
191
                        throw new SelectionChangeException(e);
192
                }
193
        }
194

    
195
        public boolean isSelectedIndex(int index) {
196
                if (index == -1) {
197
                        return false;
198
                }
199
                Feature feature = featureTableModel.getFeatureAt(index);
200
                return getFeatureSelection().isSelected(feature);
201
        }
202

    
203
        public boolean isSelectionEmpty() {
204
                try {
205
                        return getFeatureSelection().isEmpty();
206
                } catch (DataException ex) {
207
                        throw new SelectionChangeException(ex);
208
                }
209
        }
210

    
211
        public boolean getValueIsAdjusting() {
212
                return isAdjusting;
213
        }
214

    
215
        public void setValueIsAdjusting(boolean valueIsAdjusting) {
216
                if (this.isAdjusting != valueIsAdjusting) {
217
                        this.isAdjusting = valueIsAdjusting;
218
                        if (this.isAdjusting) {
219
                                getFeatureSelection().beginComplexNotification();
220
                        } else {
221
                                getFeatureSelection().endComplexNotification();
222
                        }
223
                }
224
        }
225

    
226
        public int getSelectionMode() {
227
                return selectionMode;
228
        }
229

    
230
        public void setSelectionMode(int selectionMode) {
231
                this.selectionMode = selectionMode;
232
        }
233

    
234
        public void addListSelectionListener(ListSelectionListener listener) {
235
                listenerList.add(ListSelectionListener.class, listener);
236
        }
237

    
238
        public void removeListSelectionListener(ListSelectionListener listener) {
239
                listenerList.remove(ListSelectionListener.class, listener);
240
        }
241

    
242
        public void update(Observable observable, Object notification) {
243
                if (notification instanceof FeatureStoreNotification) {
244
                        FeatureStoreNotification fnotification =
245
                                        (FeatureStoreNotification) notification;
246
                        if (!fnotification.getSource().equals(getFeatureStore())) {
247
                                return;
248
                        }
249
                        if (FeatureStoreNotification.SELECTION_CHANGE.equals(fnotification.getType())) {
250
                                try{
251
                                    fireValueChanged(-1, -1, false);
252
                                }catch(ConcurrentDataModificationException e){
253
                                    LOG.warn("The store has been updated and the selection can not be refreshed", e);
254
                                }
255
                        }
256
                }
257
        }
258

    
259
        private FeatureSelection getFeatureSelection() {
260
                try {
261
                        return (FeatureSelection) getFeatureStore().getSelection();
262
                } catch (DataException ex) {
263
                        throw new SelectionChangeException(ex);
264
                }
265
        }
266

    
267
        /**
268
         * @param operation
269
         * @param index0
270
         * @param index1
271
         */
272
        private void doWithSelection(FeatureSelectionOperation operation,
273
                        int index0, int index1, boolean select) {
274
                // Set the anchor and lead
275
                anchor = index0;
276
                lead = index1;
277

    
278
                // As index0 <= index1 is no guaranteed, calculate the first and second
279
                // values
280
                int first = (index0 <= index1) ? index0 : index1;
281
                int last = (index0 <= index1) ? index1 : index0;
282
                
283
                //If the new selection is not updated don't continue
284
                if ((currentFirst == first) && (currentLast == last)){
285
                    return;
286
                }
287
                currentFirst = first;
288
                currentLast = last;
289

    
290
                FeatureSelection selection = getFeatureSelection();
291

    
292
                // Perform the selection operation into a complex notification
293
                selection.beginComplexNotification();
294
                try {
295
                        // Is a full select or deselect
296
                        if (first == 00 && last == featureTableModel.getRowCount() - 1) {
297
                                if (select) {
298
                                        selection.selectAll();
299
                                } else {
300
                                        selection.deselectAll();
301
                                }
302
                        } else {
303
                                operation.doWithSelection(selection, first, last);
304
                        }
305
                } catch (DataException e) {
306
                        throw new SelectionChangeException(e);
307
                } finally {
308
                        selection.endComplexNotification();
309
                }
310

    
311
                fireValueChanged(first, last, isAdjusting);
312
        }
313

    
314
        /**
315
         * Returns a Feature by table row position.
316
         */
317
        private Feature getFeature(int index) {
318
                return featureTableModel.getFeatureAt(index);
319
        }
320

    
321
        /**
322
         * Returns the FeatureStore.
323
         */
324
        private FeatureStore getFeatureStore() {
325
                return featureTableModel.getFeatureStore();
326
        }
327

    
328
        /**
329
         * @param firstIndex
330
         *            the first index in the interval
331
         * @param lastIndex
332
         *            the last index in the interval
333
         * @param isAdjusting
334
         *            true if this is the final change in a series of adjustments
335
         * @see EventListenerList
336
         */
337
        protected void fireValueChanged(int firstIndex, int lastIndex,
338
                        boolean isAdjusting) {
339
                Object[] listeners = listenerList.getListenerList();
340
                ListSelectionEvent e = null;
341

    
342
                for (int i = listeners.length - 2; i >= 0; i -= 2) {
343
                        if (listeners[i] == ListSelectionListener.class) {
344
                                if (e == null) {
345
                                        e =
346
                                                        new ListSelectionEvent(this, firstIndex, lastIndex,
347
                                                                        isAdjusting);
348
                                }
349
                                ((ListSelectionListener) listeners[i + 1]).valueChanged(e);
350
                        }
351
                }
352
        }
353

    
354
        private interface FeatureSelectionOperation {
355
                void doWithSelection(FeatureSelection selection, int first, int last)
356
                                throws DataException;
357
        }
358
}