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 | } |