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 @ 47421
History | View | Annotate | Download (33.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 | import javax.swing.SwingUtilities; |
||
33 | import javax.swing.Timer; |
||
34 | 40435 | jjdelcerro | import javax.swing.event.TableModelEvent; |
35 | import javax.swing.table.AbstractTableModel; |
||
36 | import org.gvsig.fmap.dal.DALLocator; |
||
37 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.EditingNotification; |
38 | import org.gvsig.fmap.dal.EditingNotificationManager; |
||
39 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.exception.DataException; |
40 | import org.gvsig.fmap.dal.feature.EditableFeature; |
||
41 | import org.gvsig.fmap.dal.feature.Feature; |
||
42 | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
||
43 | import org.gvsig.fmap.dal.feature.FeatureQuery; |
||
44 | import org.gvsig.fmap.dal.feature.FeatureStore; |
||
45 | import org.gvsig.fmap.dal.feature.FeatureStoreNotification; |
||
46 | import org.gvsig.fmap.dal.feature.FeatureType; |
||
47 | import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException; |
||
48 | import org.gvsig.fmap.dal.feature.paging.FeaturePagingHelper; |
||
49 | 42775 | jjdelcerro | import org.gvsig.fmap.dal.swing.DALSwingLocator; |
50 | 47219 | fdiaz | import org.gvsig.tools.dispose.DisposeUtils; |
51 | import org.gvsig.tools.dispose.SupportDisposable; |
||
52 | import org.gvsig.tools.dispose.impl.DisposableHelper; |
||
53 | 40435 | jjdelcerro | import org.gvsig.tools.exception.BaseException; |
54 | 44542 | omartinez | import org.gvsig.tools.logger.FilteredLogger; |
55 | 40435 | jjdelcerro | import org.gvsig.tools.observer.ComplexNotification; |
56 | import org.gvsig.tools.observer.ComplexObserver; |
||
57 | import org.gvsig.tools.observer.Observable; |
||
58 | import org.slf4j.Logger; |
||
59 | import org.slf4j.LoggerFactory; |
||
60 | |||
61 | /**
|
||
62 | * TableModel to access data of Features.
|
||
63 | 42454 | dmartinezizquierdo | *
|
64 | 40435 | jjdelcerro | * This table model can't handle a FeatureSet with more than Integer.MAX_VALUE
|
65 | * elements. In that case, only the first Integer.MAX_VALUE elements will be
|
||
66 | * shown.
|
||
67 | 42454 | dmartinezizquierdo | *
|
68 | 40435 | jjdelcerro | * @author <a href="mailto:cordin@disid.com">C?sar Ordi?ana</a>
|
69 | */
|
||
70 | 44977 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
71 | 47219 | fdiaz | public class FeatureTableModel extends AbstractTableModel implements ComplexObserver, SupportDisposable { |
72 | 40435 | jjdelcerro | |
73 | 44977 | jjdelcerro | private static final Logger LOGGER = LoggerFactory |
74 | .getLogger(FeatureTableModel.class); |
||
75 | 42454 | dmartinezizquierdo | |
76 | 40435 | jjdelcerro | private static final long serialVersionUID = -2488157521902851301L; |
77 | |||
78 | 47219 | fdiaz | private FeaturePagingHelper pagingHelper;
|
79 | |||
80 | private final DisposableHelper disposableHelper; |
||
81 | 40435 | jjdelcerro | |
82 | 47219 | fdiaz | |
83 | 44977 | jjdelcerro | /**
|
84 | * Used to know if a modification in the FeatureStore is created by us.
|
||
85 | */
|
||
86 | 40435 | jjdelcerro | private EditableFeature editableFeature;
|
87 | |||
88 | 44977 | jjdelcerro | private boolean selectionLocked = false; |
89 | 44542 | omartinez | private final FilteredLogger filterlogger; |
90 | 47039 | jjdelcerro | |
91 | private static final int STATUS_OK = 0; |
||
92 | private static final int STATUS_ERR_LOADFEATURES = 1; |
||
93 | private static final int STATUS_ERR_LOADFEATURETYPE = 2; |
||
94 | |||
95 | private int status; |
||
96 | 42639 | dmartinezizquierdo | |
97 | 40435 | jjdelcerro | /**
|
98 | * Constructs a TableModel from the features of a FeatureStore, with the
|
||
99 | * default page size.
|
||
100 | 42454 | dmartinezizquierdo | *
|
101 | 44977 | jjdelcerro | * @param featureStore to extract the features from
|
102 | * @param featureQuery the query to get the features from the store
|
||
103 | * @throws BaseException if there is an error reading data from the
|
||
104 | * FeatureStore
|
||
105 | 40435 | jjdelcerro | */
|
106 | public FeatureTableModel(FeatureStore featureStore,
|
||
107 | 44977 | jjdelcerro | FeatureQuery featureQuery) throws BaseException {
|
108 | 40435 | jjdelcerro | this(featureStore, featureQuery, FeaturePagingHelper.DEFAULT_PAGE_SIZE);
|
109 | } |
||
110 | |||
111 | /**
|
||
112 | * Constructs a TableModel from the features of a FeatureStore, with the
|
||
113 | * default page size.
|
||
114 | 42454 | dmartinezizquierdo | *
|
115 | 44977 | jjdelcerro | * @param featureStore to extract the features from
|
116 | * @param featureQuery the query to get the features from the store
|
||
117 | * @param pageSize the number of elements per page data
|
||
118 | * @throws BaseException if there is an error reading data from the
|
||
119 | * FeatureStore
|
||
120 | 40435 | jjdelcerro | */
|
121 | public FeatureTableModel(FeatureStore featureStore,
|
||
122 | 44977 | jjdelcerro | FeatureQuery featureQuery, int pageSize) throws BaseException { |
123 | 40435 | jjdelcerro | this(DALLocator.getDataManager().createFeaturePagingHelper(
|
124 | 44977 | jjdelcerro | featureStore, featureQuery, pageSize)); |
125 | 40435 | jjdelcerro | } |
126 | |||
127 | /**
|
||
128 | 47219 | fdiaz | * Constructs a TableModel from a FeatureCollection and a Paging pagingHelper.
|
129 | 42454 | dmartinezizquierdo | *
|
130 | 40435 | jjdelcerro | * @param helper
|
131 | */
|
||
132 | 44977 | jjdelcerro | @SuppressWarnings("OverridableMethodCallInConstructor") |
133 | 40435 | jjdelcerro | protected FeatureTableModel(FeaturePagingHelper helper) {
|
134 | 47219 | fdiaz | this.disposableHelper = new DisposableHelper(this); |
135 | 47039 | jjdelcerro | this.status = STATUS_OK;
|
136 | 47219 | fdiaz | this.pagingHelper = helper;
|
137 | 46608 | fdiaz | this.filterlogger = new FilteredLogger(LOGGER, "SimpleFeaturesTableModel", 30000L); |
138 | 40435 | jjdelcerro | initialize(); |
139 | } |
||
140 | |||
141 | 44977 | jjdelcerro | @Override
|
142 | 40435 | jjdelcerro | public int getColumnCount() { |
143 | 47039 | jjdelcerro | switch(this.status) { |
144 | case STATUS_OK:
|
||
145 | case STATUS_ERR_LOADFEATURES:
|
||
146 | break;
|
||
147 | case STATUS_ERR_LOADFEATURETYPE:
|
||
148 | return 0; |
||
149 | } |
||
150 | 40435 | jjdelcerro | // Return the number of fields of the Features
|
151 | FeatureType featureType = getFeatureType(); |
||
152 | return featureType.size();
|
||
153 | } |
||
154 | |||
155 | 44977 | jjdelcerro | @Override
|
156 | 40435 | jjdelcerro | public int getRowCount() { |
157 | 47039 | jjdelcerro | switch(this.status) { |
158 | case STATUS_OK:
|
||
159 | break;
|
||
160 | case STATUS_ERR_LOADFEATURETYPE:
|
||
161 | case STATUS_ERR_LOADFEATURES:
|
||
162 | return 0; |
||
163 | } |
||
164 | 40435 | jjdelcerro | // Return the total size of the collection
|
165 | // If the size is bigger than INTEGER.MAX_VALUE, return that instead
|
||
166 | 44977 | jjdelcerro | try {
|
167 | long totalSize = getHelper().getTotalSize();
|
||
168 | if (totalSize > Integer.MAX_VALUE) { |
||
169 | return Integer.MAX_VALUE; |
||
170 | } else {
|
||
171 | return (int) totalSize; |
||
172 | } |
||
173 | } catch (ConcurrentDataModificationException e) {
|
||
174 | LOGGER.debug("Error while getting the total size of the set", e);
|
||
175 | 47421 | fdiaz | this.delayAction.addAction(DelayAction.ACTION_RELOADALL);
|
176 | 44977 | jjdelcerro | return 0; |
177 | } |
||
178 | 40435 | jjdelcerro | } |
179 | |||
180 | 44977 | jjdelcerro | @Override
|
181 | 40435 | jjdelcerro | public Object getValueAt(int rowIndex, int columnIndex) { |
182 | 47039 | jjdelcerro | switch(this.status) { |
183 | case STATUS_OK:
|
||
184 | break;
|
||
185 | case STATUS_ERR_LOADFEATURETYPE:
|
||
186 | case STATUS_ERR_LOADFEATURES:
|
||
187 | return null; |
||
188 | } |
||
189 | 40435 | jjdelcerro | // Get the Feature at row "rowIndex", and return the value of the
|
190 | // attribute at "columnIndex"
|
||
191 | 44542 | omartinez | try {
|
192 | Feature feature = getFeatureAt(rowIndex); |
||
193 | if (feature == null) { |
||
194 | return null; |
||
195 | } |
||
196 | Object value;
|
||
197 | value = getFeatureValue(feature, columnIndex); |
||
198 | return value;
|
||
199 | } catch (Throwable ex) { |
||
200 | filterlogger.warn("Not been able to retrieve feature value", ex);
|
||
201 | 43995 | jjdelcerro | return null; |
202 | } |
||
203 | 40435 | jjdelcerro | } |
204 | |||
205 | /**
|
||
206 | * Returns the value for a row position.
|
||
207 | 42454 | dmartinezizquierdo | *
|
208 | 44977 | jjdelcerro | * @param rowIndex the row position
|
209 | 40435 | jjdelcerro | * @return the Feature
|
210 | */
|
||
211 | public Feature getFeatureAt(int rowIndex) { |
||
212 | try {
|
||
213 | return getHelper().getFeatureAt(rowIndex);
|
||
214 | } catch (BaseException ex) {
|
||
215 | throw new GetFeatureAtException(rowIndex, ex); |
||
216 | } |
||
217 | } |
||
218 | |||
219 | 44977 | jjdelcerro | @Override
|
220 | 40435 | jjdelcerro | public Class<?> getColumnClass(int columnIndex) { |
221 | // Return the class of the FeatureAttributeDescriptor for the value
|
||
222 | 44977 | jjdelcerro | FeatureAttributeDescriptor attributeDesc |
223 | = internalGetFeatureDescriptorForColumn(columnIndex); |
||
224 | 40435 | jjdelcerro | if (attributeDesc == null) { |
225 | 44977 | jjdelcerro | return super.getColumnClass(columnIndex); |
226 | 40435 | jjdelcerro | } |
227 | Class<?> clazz = attributeDesc.getObjectClass();
|
||
228 | return (clazz == null ? super.getColumnClass(columnIndex) : clazz); |
||
229 | } |
||
230 | |||
231 | 44977 | jjdelcerro | @Override
|
232 | 40435 | jjdelcerro | public String getColumnName(int column) { |
233 | // Return the Feature attribute name
|
||
234 | 44977 | jjdelcerro | FeatureAttributeDescriptor attributeDesc |
235 | = internalGetFeatureDescriptorForColumn(column); |
||
236 | 40435 | jjdelcerro | return attributeDesc.getName();
|
237 | } |
||
238 | |||
239 | @Override
|
||
240 | public boolean isCellEditable(int rowIndex, int columnIndex) { |
||
241 | if (getFeatureStore().isEditing()) {
|
||
242 | 44977 | jjdelcerro | FeatureAttributeDescriptor attributeDesc |
243 | = internalGetFeatureDescriptorForColumn(columnIndex); |
||
244 | 40435 | jjdelcerro | return !attributeDesc.isReadOnly();
|
245 | } |
||
246 | |||
247 | return false; |
||
248 | } |
||
249 | |||
250 | @Override
|
||
251 | public void setValueAt(Object value, int rowIndex, int columnIndex) { |
||
252 | // Get the feature at rowIndex
|
||
253 | Feature feature = getFeatureAt(rowIndex); |
||
254 | // Only set the value if the feature exists
|
||
255 | if (feature != null) { |
||
256 | // We only need to update if the value to set is not equal to the
|
||
257 | // current value
|
||
258 | Object currentValue = getFeatureValue(feature, columnIndex);
|
||
259 | if (value != currentValue
|
||
260 | 44977 | jjdelcerro | && (value == null || !value.equals(currentValue))) {
|
261 | 40435 | jjdelcerro | try {
|
262 | // Store the editable feature to ignore the related store
|
||
263 | // change notification
|
||
264 | 44977 | jjdelcerro | editableFeature |
265 | = setFeatureValue(feature, columnIndex, value); |
||
266 | 42775 | jjdelcerro | EditingNotificationManager editingNotificationManager = DALSwingLocator.getEditingNotificationManager(); |
267 | 41335 | jjdelcerro | EditingNotification notification = editingNotificationManager.notifyObservers( |
268 | 42454 | dmartinezizquierdo | this,
|
269 | EditingNotification.BEFORE_UPDATE_FEATURE, |
||
270 | 41323 | jjdelcerro | null,
|
271 | this.getHelper().getFeatureStore(),
|
||
272 | editableFeature); |
||
273 | 44977 | jjdelcerro | if (notification.isCanceled()) {
|
274 | 41323 | jjdelcerro | return;
|
275 | } |
||
276 | 44977 | jjdelcerro | if (notification.shouldValidateTheFeature()) {
|
277 | if (!editingNotificationManager.validateFeature(feature)) {
|
||
278 | 41335 | jjdelcerro | return;
|
279 | } |
||
280 | 42454 | dmartinezizquierdo | } |
281 | 40435 | jjdelcerro | this.getHelper().update(editableFeature);
|
282 | // We'll have already received the event, so we can forget
|
||
283 | // about it
|
||
284 | getHelper().reloadCurrentPage(); |
||
285 | fireTableCellUpdated(rowIndex, columnIndex); |
||
286 | 42454 | dmartinezizquierdo | |
287 | 41335 | jjdelcerro | editingNotificationManager.notifyObservers( |
288 | 42454 | dmartinezizquierdo | this,
|
289 | EditingNotification.AFTER_UPDATE_FEATURE, |
||
290 | 41323 | jjdelcerro | null,
|
291 | this.getHelper().getFeatureStore(),
|
||
292 | editableFeature); |
||
293 | editableFeature = null;
|
||
294 | 42454 | dmartinezizquierdo | |
295 | 40435 | jjdelcerro | } catch (BaseException ex) {
|
296 | throw new SetFeatureValueException(rowIndex, columnIndex, |
||
297 | 44977 | jjdelcerro | value, ex); |
298 | 40435 | jjdelcerro | } finally {
|
299 | // Just in case
|
||
300 | editableFeature = null;
|
||
301 | } |
||
302 | } |
||
303 | } |
||
304 | } |
||
305 | |||
306 | /**
|
||
307 | * Returns a reference to the Paging Helper used to load the data from the
|
||
308 | * DataStore.
|
||
309 | 42454 | dmartinezizquierdo | *
|
310 | 47219 | fdiaz | * @return the paging pagingHelper
|
311 | 40435 | jjdelcerro | */
|
312 | public FeaturePagingHelper getHelper() {
|
||
313 | 47219 | fdiaz | return pagingHelper;
|
314 | 40435 | jjdelcerro | } |
315 | |||
316 | /**
|
||
317 | * Sets the FeatureType to show in the table. Used for FeatureStores with
|
||
318 | * many simultaneous FeatureTypes supported. Will cause a reload of the
|
||
319 | * current data.
|
||
320 | 42454 | dmartinezizquierdo | *
|
321 | 44977 | jjdelcerro | * @param featureType the FeatureType of the Features
|
322 | 40435 | jjdelcerro | */
|
323 | public void setFeatureType(FeatureType featureType) { |
||
324 | getFeatureQuery().setFeatureType(featureType); |
||
325 | reloadFeatures(); |
||
326 | 42639 | dmartinezizquierdo | //Selection must be locked to avoid losing it when the table is refreshed
|
327 | 44977 | jjdelcerro | selectionLocked = true;
|
328 | 42639 | dmartinezizquierdo | //The table is refreshed
|
329 | try {
|
||
330 | fireTableStructureChanged(); |
||
331 | } catch (Exception e) { |
||
332 | 44542 | omartinez | LOGGER.warn("Couldn't reload changed table");
|
333 | 44977 | jjdelcerro | } finally {
|
334 | 42639 | dmartinezizquierdo | //The locked selection is unlocked.
|
335 | 44977 | jjdelcerro | selectionLocked = false;
|
336 | 42639 | dmartinezizquierdo | } |
337 | 40435 | jjdelcerro | } |
338 | |||
339 | /**
|
||
340 | * Sets that the selected Features get returned first.
|
||
341 | 44977 | jjdelcerro | *
|
342 | * @param selectionUp
|
||
343 | 40435 | jjdelcerro | */
|
344 | public void setSelectionUp(boolean selectionUp) { |
||
345 | 44977 | jjdelcerro | if (selectionUp) {
|
346 | delayAction.addAction(DelayAction.ACTION_ENABLE_SELECTION_UP); |
||
347 | } else {
|
||
348 | delayAction.addAction(DelayAction.ACTION_DISABLE_SELECTION_UP); |
||
349 | } |
||
350 | } |
||
351 | |||
352 | protected void fireTableChanged() { |
||
353 | 45070 | jjdelcerro | // LOGGER.info("fireTableChanged()");
|
354 | 40435 | jjdelcerro | fireTableChanged(new TableModelEvent(this, 0, getRowCount() - 1)); |
355 | } |
||
356 | 44977 | jjdelcerro | public static class Bitmask { |
357 | private int mask; |
||
358 | |||
359 | public Bitmask(int initialmask) { |
||
360 | this.mask = initialmask;
|
||
361 | } |
||
362 | |||
363 | public boolean isSetBit(int pos) { |
||
364 | return (mask & (1<<pos)) != 0; |
||
365 | } |
||
366 | |||
367 | public boolean isSet(int bits) { |
||
368 | return (mask & bits) == bits;
|
||
369 | } |
||
370 | |||
371 | public boolean isSetAny() { |
||
372 | return mask!=0; |
||
373 | } |
||
374 | |||
375 | public boolean isCleanAll() { |
||
376 | return mask == 0; |
||
377 | } |
||
378 | 40435 | jjdelcerro | |
379 | 44977 | jjdelcerro | public void set(int bits) { |
380 | mask = mask | bits; |
||
381 | } |
||
382 | |||
383 | public int get() { |
||
384 | return mask;
|
||
385 | } |
||
386 | |||
387 | public void clear(int bits) { |
||
388 | mask = ~bits & mask; |
||
389 | } |
||
390 | |||
391 | public void clearBit(int pos) { |
||
392 | mask = ~(1<<pos) & mask;
|
||
393 | } |
||
394 | |||
395 | public void clearAll() { |
||
396 | mask = 0;
|
||
397 | } |
||
398 | |||
399 | } |
||
400 | |||
401 | 41822 | jjdelcerro | private class DelayAction extends Timer implements ActionListener, Runnable { |
402 | 42454 | dmartinezizquierdo | |
403 | 44977 | jjdelcerro | private static final int ACTION_NONE = 0; |
404 | private static final int ACTION_RELOADALL = 1; |
||
405 | private static final int ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED = 2; |
||
406 | private static final int ACTION_RELOAD_IF_FEATURE_UPDATED = 4; |
||
407 | private static final int ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED = 8; |
||
408 | private static final int ACTION_RELOAD_FEATURE_TYPE = 16; |
||
409 | private static final int ACTION_ENABLE_SELECTION_UP = 32; |
||
410 | private static final int ACTION_RELOAD_ALL_FEATURES = 64; |
||
411 | private static final int ACTION_DISABLE_SELECTION_UP = 128; |
||
412 | private static final int ACTION_UPDATE_SELECTION = 256; |
||
413 | |||
414 | private final Bitmask current_actions = new Bitmask(ACTION_NONE); |
||
415 | 41822 | jjdelcerro | private Feature feature;
|
416 | private FeatureType featureType;
|
||
417 | 42454 | dmartinezizquierdo | |
418 | 44977 | jjdelcerro | @SuppressWarnings("OverridableMethodCallInConstructor") |
419 | 41822 | jjdelcerro | public DelayAction() {
|
420 | 44977 | jjdelcerro | super(1000, null); |
421 | 41822 | jjdelcerro | this.setRepeats(false); |
422 | this.reset();
|
||
423 | this.addActionListener(this); |
||
424 | } |
||
425 | |||
426 | 44977 | jjdelcerro | public final void reset() { |
427 | this.current_actions.clearAll();
|
||
428 | 41822 | jjdelcerro | this.feature = null; |
429 | this.featureType = null; |
||
430 | } |
||
431 | |||
432 | 44977 | jjdelcerro | @Override
|
433 | 41822 | jjdelcerro | public void actionPerformed(ActionEvent ae) { |
434 | this.run();
|
||
435 | } |
||
436 | 42454 | dmartinezizquierdo | |
437 | 44977 | jjdelcerro | @SuppressWarnings("UnusedAssignment") |
438 | private String getActionsLabel(Bitmask actions) { |
||
439 | if( actions.isCleanAll() ) {
|
||
440 | return "NONE"; |
||
441 | } |
||
442 | StringBuilder builder = new StringBuilder(); |
||
443 | boolean needSeparator = false; |
||
444 | if( actions.isSet(ACTION_RELOADALL) ) {
|
||
445 | if( needSeparator ) {
|
||
446 | builder.append("|");
|
||
447 | } |
||
448 | needSeparator = true;
|
||
449 | builder.append("RELOADALL");
|
||
450 | } |
||
451 | if( actions.isSet(ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED) ) {
|
||
452 | if( needSeparator ) {
|
||
453 | builder.append("|");
|
||
454 | } |
||
455 | needSeparator = true;
|
||
456 | builder.append("RELOAD_IF_FEATURE_COUNT_CHANGED");
|
||
457 | } |
||
458 | if( actions.isSet(ACTION_RELOAD_IF_FEATURE_UPDATED) ) {
|
||
459 | if( needSeparator ) {
|
||
460 | builder.append("|");
|
||
461 | } |
||
462 | needSeparator = true;
|
||
463 | builder.append("RELOAD_IF_FEATURE_UPDATED");
|
||
464 | } |
||
465 | if( actions.isSet(ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED) ) {
|
||
466 | if( needSeparator ) {
|
||
467 | builder.append("|");
|
||
468 | } |
||
469 | needSeparator = true;
|
||
470 | builder.append("RELOAD_IF_FEATURE_TYPE_CHANGED");
|
||
471 | } |
||
472 | if( actions.isSet(ACTION_RELOAD_FEATURE_TYPE) ) {
|
||
473 | if( needSeparator ) {
|
||
474 | builder.append("|");
|
||
475 | } |
||
476 | needSeparator = true;
|
||
477 | builder.append("RELOAD_FEATURE_TYPE");
|
||
478 | } |
||
479 | if( actions.isSet(ACTION_RELOAD_ALL_FEATURES) ) {
|
||
480 | if( needSeparator ) {
|
||
481 | builder.append("|");
|
||
482 | } |
||
483 | needSeparator = true;
|
||
484 | builder.append("RELOAD_ALL_FEATURES");
|
||
485 | } |
||
486 | if( actions.isSet(ACTION_DISABLE_SELECTION_UP) ) {
|
||
487 | if( needSeparator ) {
|
||
488 | builder.append("|");
|
||
489 | } |
||
490 | needSeparator = true;
|
||
491 | builder.append("DISABLE_SELECTION_UP");
|
||
492 | } |
||
493 | if( actions.isSet(ACTION_ENABLE_SELECTION_UP) ) {
|
||
494 | if( needSeparator ) {
|
||
495 | builder.append("|");
|
||
496 | } |
||
497 | needSeparator = true;
|
||
498 | builder.append("ENABLE_SELECTION_UP");
|
||
499 | } |
||
500 | if( actions.isSet(ACTION_UPDATE_SELECTION) ) {
|
||
501 | if( needSeparator ) {
|
||
502 | builder.append("|");
|
||
503 | } |
||
504 | needSeparator = true;
|
||
505 | builder.append("UPDATE_SELECTION");
|
||
506 | } |
||
507 | if( !needSeparator ) {
|
||
508 | builder.append(actions.get()); |
||
509 | } |
||
510 | return builder.toString();
|
||
511 | } |
||
512 | |||
513 | @Override
|
||
514 | 41822 | jjdelcerro | public void run() { |
515 | 44977 | jjdelcerro | if (!SwingUtilities.isEventDispatchThread()) { |
516 | 41822 | jjdelcerro | SwingUtilities.invokeLater(this); |
517 | return;
|
||
518 | } |
||
519 | this.stop();
|
||
520 | 45070 | jjdelcerro | // LOGGER.info("DelayAction.run begin ["+ getActionsLabel(this.current_actions) + "]");
|
521 | 44977 | jjdelcerro | boolean needFireTableChanged = false; |
522 | if( this.current_actions.isSet(ACTION_RELOADALL) ) { |
||
523 | this.current_actions.clear(
|
||
524 | ACTION_RELOADALL | |
||
525 | ACTION_RELOAD_FEATURE_TYPE | |
||
526 | ACTION_RELOAD_ALL_FEATURES | |
||
527 | ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED | |
||
528 | ACTION_RELOAD_IF_FEATURE_UPDATED | |
||
529 | ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED |
||
530 | ); |
||
531 | 41822 | jjdelcerro | reloadAll(); |
532 | 44977 | jjdelcerro | } |
533 | if( this.current_actions.isSet(ACTION_RELOAD_FEATURE_TYPE) ) { |
||
534 | this.current_actions.clear(
|
||
535 | ACTION_RELOAD_FEATURE_TYPE | |
||
536 | ACTION_RELOAD_ALL_FEATURES | |
||
537 | ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED | |
||
538 | ACTION_RELOAD_IF_FEATURE_UPDATED | |
||
539 | ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED |
||
540 | ); |
||
541 | 41822 | jjdelcerro | reloadFeatureType(); |
542 | updatePaginHelperWithHiddenColums(); |
||
543 | 44977 | jjdelcerro | } |
544 | if( this.current_actions.isSet(ACTION_RELOAD_ALL_FEATURES) ) { |
||
545 | this.current_actions.clear(
|
||
546 | ACTION_RELOAD_ALL_FEATURES | |
||
547 | ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED | |
||
548 | ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED | |
||
549 | ACTION_RELOAD_IF_FEATURE_UPDATED |
||
550 | ); |
||
551 | 42456 | dmartinezizquierdo | reloadFeatures(); |
552 | 44977 | jjdelcerro | needFireTableChanged = true;
|
553 | 41822 | jjdelcerro | } |
554 | 44977 | jjdelcerro | if( this.current_actions.isSet(ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED) ) { |
555 | if( reloadFeatureTypeIfTypeChanged(featureType) ) {
|
||
556 | this.current_actions.clear(
|
||
557 | ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED | |
||
558 | ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED | |
||
559 | ACTION_RELOAD_IF_FEATURE_UPDATED |
||
560 | ); |
||
561 | } |
||
562 | 41822 | jjdelcerro | } |
563 | 44977 | jjdelcerro | if( this.current_actions.isSet(ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED) ) { |
564 | if( reloadFeaturesIfFeatureCountChanged(feature) ) {
|
||
565 | this.current_actions.clear(
|
||
566 | ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED | |
||
567 | ACTION_RELOAD_IF_FEATURE_UPDATED |
||
568 | ); |
||
569 | } |
||
570 | } |
||
571 | if( this.current_actions.isSet(ACTION_RELOAD_IF_FEATURE_UPDATED) ) { |
||
572 | if( reloadFeaturesIfFeatureUpdated(feature) ) {
|
||
573 | this.current_actions.clear(
|
||
574 | ACTION_RELOAD_IF_FEATURE_UPDATED |
||
575 | ); |
||
576 | needFireTableChanged = true;
|
||
577 | } |
||
578 | } |
||
579 | |||
580 | if( this.current_actions.isSet(ACTION_ENABLE_SELECTION_UP) ) { |
||
581 | if (!getHelper().isSelectionUp()) {
|
||
582 | getHelper().setSelectionUp(true);
|
||
583 | this.current_actions.clear(
|
||
584 | ACTION_UPDATE_SELECTION |
||
585 | ); |
||
586 | } |
||
587 | this.current_actions.clear(
|
||
588 | ACTION_ENABLE_SELECTION_UP | |
||
589 | ACTION_DISABLE_SELECTION_UP |
||
590 | ); |
||
591 | needFireTableChanged = true;
|
||
592 | } else if( this.current_actions.isSet(ACTION_DISABLE_SELECTION_UP) ) { |
||
593 | if (getHelper().isSelectionUp()) {
|
||
594 | getHelper().setSelectionUp(false);
|
||
595 | this.current_actions.clear(
|
||
596 | ACTION_UPDATE_SELECTION |
||
597 | ); |
||
598 | } |
||
599 | this.current_actions.clear(
|
||
600 | ACTION_ENABLE_SELECTION_UP | |
||
601 | ACTION_DISABLE_SELECTION_UP |
||
602 | ); |
||
603 | needFireTableChanged = true;
|
||
604 | } |
||
605 | |||
606 | if( this.current_actions.isSet(ACTION_UPDATE_SELECTION) ) { |
||
607 | if (getHelper().isSelectionUp()) {
|
||
608 | // Se ha a?adido o quitado elementos de la seleccion, y estamos
|
||
609 | // en "seleccion arriba", asi que forzamos un refresco.
|
||
610 | try {
|
||
611 | getHelper().reloadCurrentPage(); |
||
612 | } catch(Throwable th) { |
||
613 | LOGGER.debug("No se ha podido recargar la pagina actual de la tabla", th);
|
||
614 | } |
||
615 | } |
||
616 | needFireTableChanged = true;
|
||
617 | } |
||
618 | |||
619 | if( needFireTableChanged ) {
|
||
620 | fireTableChanged(); |
||
621 | } |
||
622 | 41822 | jjdelcerro | this.reset();
|
623 | 45070 | jjdelcerro | // LOGGER.info("DelayAction.run end ["+ getActionsLabel(this.current_actions) + "]");
|
624 | 41822 | jjdelcerro | } |
625 | 42454 | dmartinezizquierdo | |
626 | 44977 | jjdelcerro | public void addAction(int action) { |
627 | this.addAction(action, null, null); |
||
628 | 41822 | jjdelcerro | } |
629 | 42454 | dmartinezizquierdo | |
630 | 44977 | jjdelcerro | public void addAction(int action, Feature feature) { |
631 | this.addAction(action, feature, null); |
||
632 | 41822 | jjdelcerro | } |
633 | 42454 | dmartinezizquierdo | |
634 | 44977 | jjdelcerro | public void addAction(int action, FeatureType featureType) { |
635 | this.addAction(action, null, featureType); |
||
636 | 41822 | jjdelcerro | } |
637 | 42454 | dmartinezizquierdo | |
638 | 44977 | jjdelcerro | public void addAction(int action, Feature feature, FeatureType featureType) { |
639 | 41904 | jjdelcerro | this.feature = feature;
|
640 | this.featureType = featureType;
|
||
641 | 44977 | jjdelcerro | this.current_actions.set(action);
|
642 | 45070 | jjdelcerro | // LOGGER.info("addAction: "+ this.getActionsLabel(current_actions));
|
643 | 44977 | jjdelcerro | if ( this.current_actions.isSetAny() ) { |
644 | 45070 | jjdelcerro | // LOGGER.info("addAction: start");
|
645 | 41822 | jjdelcerro | this.start();
|
646 | } |
||
647 | } |
||
648 | 42454 | dmartinezizquierdo | |
649 | 41822 | jjdelcerro | } |
650 | 42454 | dmartinezizquierdo | |
651 | 44977 | jjdelcerro | private final DelayAction delayAction = new DelayAction(); |
652 | 42454 | dmartinezizquierdo | |
653 | 44977 | jjdelcerro | @Override
|
654 | 40435 | jjdelcerro | public void update(final Observable observable, final Object notification) { |
655 | 45070 | jjdelcerro | // LOGGER.info("update: " +
|
656 | // (observable==null? "null":observable.getClass().getSimpleName()) +
|
||
657 | // ", " +
|
||
658 | // (notification==null? "null":notification.getClass().getSimpleName())
|
||
659 | // );
|
||
660 | 41212 | jjdelcerro | if (notification instanceof ComplexNotification) { |
661 | // A lot of things might have happened in the store, so don't
|
||
662 | // bother looking into each notification.
|
||
663 | 44977 | jjdelcerro | this.delayAction.addAction(DelayAction.ACTION_RELOADALL);
|
664 | 41212 | jjdelcerro | } else if (observable.equals(getFeatureStore()) |
665 | && notification instanceof FeatureStoreNotification) {
|
||
666 | FeatureStoreNotification fsNotification |
||
667 | = (FeatureStoreNotification) notification; |
||
668 | 40435 | jjdelcerro | String type = fsNotification.getType();
|
669 | |||
670 | 45070 | jjdelcerro | // LOGGER.info("update: "+type);
|
671 | 44977 | jjdelcerro | switch(type) {
|
672 | case FeatureStoreNotification.AFTER_DELETE:
|
||
673 | case FeatureStoreNotification.AFTER_INSERT:
|
||
674 | this.delayAction.addAction(DelayAction.ACTION_RELOAD_IF_FEATURE_COUNT_CHANGED, fsNotification.getFeature());
|
||
675 | break;
|
||
676 | 40435 | jjdelcerro | |
677 | 44977 | jjdelcerro | case FeatureStoreNotification.AFTER_UPDATE:
|
678 | this.delayAction.addAction(DelayAction.ACTION_RELOAD_IF_FEATURE_UPDATED, fsNotification.getFeature());
|
||
679 | break;
|
||
680 | 40435 | jjdelcerro | |
681 | 44977 | jjdelcerro | case FeatureStoreNotification.AFTER_UPDATE_TYPE:
|
682 | this.delayAction.addAction(DelayAction.ACTION_RELOAD_IF_FEATURE_TYPE_CHANGED, fsNotification.getFeatureType());
|
||
683 | break;
|
||
684 | 40435 | jjdelcerro | |
685 | 44977 | jjdelcerro | case FeatureStoreNotification.TRANSFORM_CHANGE:
|
686 | case FeatureStoreNotification.AFTER_UNDO:
|
||
687 | case FeatureStoreNotification.AFTER_REDO:
|
||
688 | case FeatureStoreNotification.AFTER_REFRESH:
|
||
689 | this.delayAction.addAction(DelayAction.ACTION_RELOADALL);
|
||
690 | break;
|
||
691 | 40435 | jjdelcerro | |
692 | 44977 | jjdelcerro | case FeatureStoreNotification.AFTER_FINISHEDITING:
|
693 | case FeatureStoreNotification.AFTER_STARTEDITING:
|
||
694 | case FeatureStoreNotification.AFTER_CANCELEDITING:
|
||
695 | /*
|
||
696 | No tengo nada claro por que es necesario llamar al reloadFeatureType
|
||
697 | pero si no se incluye hay problemas si durante la edicion se a?aden
|
||
698 | campos a la tabla. Sin esto, al cerrar la edicion, los campos a?adidos
|
||
699 | desaparecen de la tabla aunque estan en el fichero.
|
||
700 | Ver ticket #2434 https://devel.gvsig.org/redmine/issues/2434
|
||
701 | */
|
||
702 | this.delayAction.addAction(DelayAction.ACTION_RELOAD_FEATURE_TYPE, fsNotification.getFeatureType());
|
||
703 | break;
|
||
704 | |||
705 | case FeatureStoreNotification.SELECTION_CHANGE:
|
||
706 | this.delayAction.addAction(DelayAction.ACTION_UPDATE_SELECTION);
|
||
707 | break;
|
||
708 | |||
709 | default:
|
||
710 | 45888 | jjdelcerro | LOGGER.debug("update: skip notification("+type+")"); |
711 | 41212 | jjdelcerro | } |
712 | } |
||
713 | } |
||
714 | 40435 | jjdelcerro | |
715 | 41212 | jjdelcerro | protected void updatePaginHelperWithHiddenColums() { |
716 | FeatureQuery query = this.getHelper().getFeatureQuery();
|
||
717 | if (this.getHelper().getFeatureStore().isEditing()) { |
||
718 | if (query.hasConstantsAttributeNames()) {
|
||
719 | query.clearConstantsAttributeNames(); |
||
720 | } |
||
721 | } else {
|
||
722 | query.setConstantsAttributeNames(this.getHiddenColumnNames());
|
||
723 | } |
||
724 | try {
|
||
725 | this.getHelper().reload();
|
||
726 | } catch (BaseException ex) {
|
||
727 | 44542 | omartinez | LOGGER.warn("Can't reload paging-helper.", ex);
|
728 | 41212 | jjdelcerro | } |
729 | 40435 | jjdelcerro | } |
730 | |||
731 | 41212 | jjdelcerro | protected String[] getHiddenColumnNames() { |
732 | return null; |
||
733 | } |
||
734 | 42454 | dmartinezizquierdo | |
735 | 40435 | jjdelcerro | /**
|
736 | * Returns the FeatureStore of the Collection.
|
||
737 | 42454 | dmartinezizquierdo | *
|
738 | 40435 | jjdelcerro | * @return the FeatureStore
|
739 | */
|
||
740 | public FeatureStore getFeatureStore() {
|
||
741 | return getHelper().getFeatureStore();
|
||
742 | } |
||
743 | |||
744 | /**
|
||
745 | * Returns the descriptor of a Feature attribute for a table column.
|
||
746 | 42454 | dmartinezizquierdo | *
|
747 | 44977 | jjdelcerro | * @param columnIndex, the column index
|
748 | * @return
|
||
749 | 40435 | jjdelcerro | */
|
750 | public FeatureAttributeDescriptor getDescriptorForColumn(int columnIndex) { |
||
751 | return internalGetFeatureDescriptorForColumn(columnIndex);
|
||
752 | } |
||
753 | |||
754 | /**
|
||
755 | * @param columnIndex
|
||
756 | * @return
|
||
757 | */
|
||
758 | 44977 | jjdelcerro | protected FeatureAttributeDescriptor internalGetFeatureDescriptorForColumn(
|
759 | int columnIndex) {
|
||
760 | FeatureType featureType = getFeatureType(); |
||
761 | return featureType == null ? null : featureType |
||
762 | .getAttributeDescriptor(columnIndex); |
||
763 | } |
||
764 | 40435 | jjdelcerro | |
765 | /**
|
||
766 | * Initialize the TableModel
|
||
767 | */
|
||
768 | protected void initialize() { |
||
769 | // Add as observable to the FeatureStore, to detect data and selection
|
||
770 | // changes
|
||
771 | 47219 | fdiaz | pagingHelper.getFeatureStore().addObserver(this);
|
772 | 40435 | jjdelcerro | } |
773 | |||
774 | /**
|
||
775 | * Returns the value of a Feature attribute, at the given position.
|
||
776 | 42454 | dmartinezizquierdo | *
|
777 | 44977 | jjdelcerro | * @param feature the feature to get the value from
|
778 | * @param columnIndex the Feature attribute position
|
||
779 | 40435 | jjdelcerro | * @return the value
|
780 | */
|
||
781 | protected Object getFeatureValue(Feature feature, int columnIndex) { |
||
782 | return feature.get(columnIndex);
|
||
783 | } |
||
784 | |||
785 | /**
|
||
786 | * Sets the value of an Feature attribute at the given position.
|
||
787 | 42454 | dmartinezizquierdo | *
|
788 | 44977 | jjdelcerro | * @param feature the feature to update
|
789 | * @param columnIndex the attribute position
|
||
790 | * @param value the value to set
|
||
791 | * @return
|
||
792 | 40435 | jjdelcerro | */
|
793 | protected EditableFeature setFeatureValue(Feature feature, int columnIndex, |
||
794 | 44977 | jjdelcerro | Object value) {
|
795 | EditableFeature theEditableFeature = feature.getEditable(); |
||
796 | theEditableFeature.set(columnIndex, value); |
||
797 | return theEditableFeature;
|
||
798 | 40435 | jjdelcerro | } |
799 | |||
800 | /**
|
||
801 | * Returns the FeatureQuery used to get the Features.
|
||
802 | 42454 | dmartinezizquierdo | *
|
803 | 40435 | jjdelcerro | * @return the FeatureQuery
|
804 | */
|
||
805 | public FeatureQuery getFeatureQuery() {
|
||
806 | return getHelper().getFeatureQuery();
|
||
807 | } |
||
808 | |||
809 | /**
|
||
810 | 44977 | jjdelcerro | * Returns the type of the
|
811 | *
|
||
812 | * @return features.
|
||
813 | 40435 | jjdelcerro | */
|
814 | 41707 | jjdelcerro | protected FeatureType getFeatureType() {
|
815 | 40435 | jjdelcerro | return getHelper().getFeatureType();
|
816 | } |
||
817 | |||
818 | /**
|
||
819 | * Reloads the table data if a feature has been changed, not through the
|
||
820 | * table.
|
||
821 | */
|
||
822 | 44977 | jjdelcerro | private boolean reloadFeaturesIfFeatureCountChanged(Feature feature) { |
823 | 40435 | jjdelcerro | // Is any data is changed in the FeatureStore, notify the model
|
824 | // listeners. Ignore the case where the updated feature is
|
||
825 | // changed through us.
|
||
826 | if (editableFeature == null || !editableFeature.equals(feature)) { |
||
827 | 42454 | dmartinezizquierdo | reloadFeatures(); |
828 | 42639 | dmartinezizquierdo | //Selection must be locked to avoid losing it when the table is refreshed
|
829 | 44977 | jjdelcerro | selectionLocked = true;
|
830 | 42639 | dmartinezizquierdo | //The table is refreshed
|
831 | try {
|
||
832 | fireTableDataChanged(); |
||
833 | } catch (Exception e) { |
||
834 | 44542 | omartinez | LOGGER.warn("Couldn't reload changed table");
|
835 | 44977 | jjdelcerro | } finally {
|
836 | 42639 | dmartinezizquierdo | //The locked selection is unlocked.
|
837 | 44977 | jjdelcerro | selectionLocked = false;
|
838 | 42639 | dmartinezizquierdo | } |
839 | 44977 | jjdelcerro | return true; |
840 | 40435 | jjdelcerro | } |
841 | 44977 | jjdelcerro | return false; |
842 | 40435 | jjdelcerro | } |
843 | 42454 | dmartinezizquierdo | |
844 | 44977 | jjdelcerro | private boolean reloadFeaturesIfFeatureUpdated(Feature feature) { |
845 | 40435 | jjdelcerro | // Is any data is changed in the FeatureStore, notify the model
|
846 | // listeners. Ignore the case where the updated feature is
|
||
847 | // changed through us.
|
||
848 | if (editableFeature == null || !editableFeature.equals(feature)) { |
||
849 | reloadFeatures(); |
||
850 | 44977 | jjdelcerro | return true; |
851 | 40435 | jjdelcerro | } |
852 | 44977 | jjdelcerro | return false; |
853 | 40435 | jjdelcerro | } |
854 | |||
855 | /**
|
||
856 | * Reloads data and structure if the {@link FeatureType} of the features
|
||
857 | * being shown has changed.
|
||
858 | */
|
||
859 | 44977 | jjdelcerro | private boolean reloadFeatureTypeIfTypeChanged(FeatureType updatedType) { |
860 | 40435 | jjdelcerro | // If the updated featured type is the one currently being
|
861 | // shown, reload the table.
|
||
862 | 44977 | jjdelcerro | if (updatedType != null && updatedType.getId().equals(getFeatureType().getId())) { |
863 | 40435 | jjdelcerro | setFeatureType(updatedType); |
864 | 44977 | jjdelcerro | return true; |
865 | 40435 | jjdelcerro | } |
866 | 44977 | jjdelcerro | return false; |
867 | 40435 | jjdelcerro | } |
868 | |||
869 | private void reloadAll() { |
||
870 | 44977 | jjdelcerro | reloadFeatureType(); |
871 | 40435 | jjdelcerro | } |
872 | |||
873 | private void reloadFeatureType() { |
||
874 | try {
|
||
875 | 47039 | jjdelcerro | String ftypeid = getHelper().getFeatureType().getId();
|
876 | FeatureType ftype = getHelper().getFeatureStore().getFeatureType(ftypeid); |
||
877 | setFeatureType(ftype); |
||
878 | 40435 | jjdelcerro | } catch (DataException e) {
|
879 | 47039 | jjdelcerro | LOGGER.warn("Can't reload featuretype",e);
|
880 | this.status = STATUS_ERR_LOADFEATURETYPE;
|
||
881 | // throw new FeaturesDataReloadException(e);
|
||
882 | 40435 | jjdelcerro | } |
883 | } |
||
884 | |||
885 | /**
|
||
886 | * Reloads the features shown on the table.
|
||
887 | */
|
||
888 | private void reloadFeatures() { |
||
889 | 47039 | jjdelcerro | switch(this.status) { |
890 | case STATUS_OK:
|
||
891 | case STATUS_ERR_LOADFEATURES:
|
||
892 | break;
|
||
893 | case STATUS_ERR_LOADFEATURETYPE:
|
||
894 | return;
|
||
895 | } |
||
896 | 40435 | jjdelcerro | try {
|
897 | getHelper().reload(); |
||
898 | } catch (BaseException ex) {
|
||
899 | 47039 | jjdelcerro | LOGGER.warn("Can't reload features",ex);
|
900 | this.status = STATUS_ERR_LOADFEATURES;
|
||
901 | // throw new FeaturesDataReloadException(ex);
|
||
902 | 40435 | jjdelcerro | } |
903 | } |
||
904 | 42639 | dmartinezizquierdo | |
905 | /**
|
||
906 | * Returns true if selection must not be changed.
|
||
907 | 44977 | jjdelcerro | *
|
908 | 42639 | dmartinezizquierdo | * @return
|
909 | */
|
||
910 | public boolean isSelectionLocked() { |
||
911 | return selectionLocked;
|
||
912 | } |
||
913 | 47219 | fdiaz | |
914 | |||
915 | @Override
|
||
916 | public void dispose() { |
||
917 | this.disposableHelper.dispose(this); |
||
918 | } |
||
919 | 42639 | dmartinezizquierdo | |
920 | 47219 | fdiaz | @Override
|
921 | public void doDispose() throws BaseException { |
||
922 | DisposeUtils.disposeQuietly(this.pagingHelper);
|
||
923 | this.pagingHelper = null; |
||
924 | } |
||
925 | |||
926 | |||
927 | 40435 | jjdelcerro | } |