Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / featureform / swing / impl / DefaultJFeatureReferencesForm.java @ 46959

History | View | Annotate | Download (19.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2014 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.featureform.swing.impl;
24

    
25
import java.awt.BorderLayout;
26
import java.awt.Dimension;
27
import java.awt.event.ActionEvent;
28
import java.awt.event.ActionListener;
29
import java.awt.event.ComponentAdapter;
30
import java.awt.event.ComponentEvent;
31
import java.util.AbstractList;
32
import java.util.List;
33
import javax.swing.AbstractAction;
34
import static javax.swing.Action.ACTION_COMMAND_KEY;
35
import static javax.swing.Action.NAME;
36
import static javax.swing.Action.SHORT_DESCRIPTION;
37
import static javax.swing.Action.SMALL_ICON;
38
import javax.swing.JComponent;
39
import javax.swing.JPanel;
40
import org.gvsig.featureform.swing.JFeatureReferencesForm;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
43
import org.gvsig.fmap.dal.feature.Feature;
44
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
45
import org.gvsig.fmap.dal.feature.FeatureReference;
46
import org.gvsig.fmap.dal.feature.FeatureStore;
47
import org.gvsig.fmap.dal.swing.DALSwingLocator;
48
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
49
import org.gvsig.tools.ToolsLocator;
50
import org.gvsig.tools.dispose.Disposable;
51
import org.gvsig.tools.dynform.AbortActionException;
52
import org.gvsig.tools.dynform.DynFormDefinition;
53
import org.gvsig.tools.dynform.DynFormLocator;
54
import org.gvsig.tools.dynform.DynFormManager;
55
import org.gvsig.tools.dynform.JDynForm;
56
import org.gvsig.tools.dynform.JDynFormField;
57
import org.gvsig.tools.dynform.JDynFormSet;
58
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
59
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
60
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
61
import org.gvsig.tools.dynobject.DynClass;
62
import org.gvsig.tools.dynobject.DynObject;
63
import org.gvsig.tools.i18n.I18nManager;
64
import org.gvsig.tools.swing.api.ActionListenerSupport;
65
import org.gvsig.tools.swing.api.ToolsSwingLocator;
66
import org.gvsig.tools.swing.api.ToolsSwingUtils;
67
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
68
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
69
import org.gvsig.tools.swing.icontheme.IconTheme;
70
import org.slf4j.Logger;
71
import org.slf4j.LoggerFactory;
72

    
73
/**
74
 * @author fdiaz
75
 *
76
 */
77
@SuppressWarnings("UseSpecificCatch")
78
public class DefaultJFeatureReferencesForm implements Disposable, JFeatureReferencesForm {
79

    
80
    private final String REFRESHFORM_ACTION = "refreshForm";
81

    
82
    public static class FeaturesList extends AbstractList<Feature> {
83

    
84
        private final List<FeatureReference> references;
85

    
86
        public FeaturesList(List<FeatureReference> references) {
87
            this.references = references;
88
        }
89
        
90
        @Override
91
        public Feature get(int index) {
92
            try {
93
                return this.references.get(index).getFeature();
94
            } catch (DataException ex) {
95
                throw new RuntimeException("Can't get feature "+index, ex);
96
            }
97
        }
98

    
99
        @Override
100
        public int size() {
101
            return this.references.size();
102
        }
103
        
104
    }
105
    
106
    public static class DynObjectsList extends AbstractList<DynObject> {
107

    
108
        private final List<FeatureReference> references;
109

    
110
        public DynObjectsList( List<FeatureReference> references) {
111
            this.references = references;
112
        }
113
        
114
        @Override
115
        public DynObject get(int index) {
116
            try {
117
                Feature feature = this.references.get(index).getFeature();
118
                return feature.getAsDynObject();
119
            } catch (DataException ex) {
120
                throw new RuntimeException("Can't get dynobject "+index, ex);
121
            }
122
        }
123

    
124
        @Override
125
        public int size() {
126
            return this.references.size();
127
        }
128
        
129
    }
130
    
131
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeatureReferencesForm.class);
132

    
133
    private JPanel panel;
134
    private JDynFormSet formset;
135
    private DynFormDefinition definition = null;
136
    private final ActionListenerSupport actionListeners;
137
    private List<FeatureReference> references;
138
    private List<Feature> features;
139
    private List<DynObject> dynobjects;
140
    private FeatureStore store;
141
    
142

    
143
    public DefaultJFeatureReferencesForm() {
144
        this.panel = new JPanel(new BorderLayout());
145
        this.panel.addComponentListener(new ComponentAdapter() {
146
            @Override
147
            public void componentHidden(ComponentEvent e) {
148
                dispose();
149
            }
150
        });
151
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
152
    }
153

    
154
    @Override
155
    public void setPreferredSize(Dimension dimension) {
156
        panel.setPreferredSize(dimension);
157
    }
158

    
159
    private void updateForm() {
160
        if (this.formset == null) {
161
            this.getFormset();
162
        }
163
        try {
164
            this.formset.setValues(this.dynobjects);
165
        } catch (Exception ex) {
166
            throw new RuntimeException("Can't update form", ex);
167
        }
168
        updateButtonEnabledStatus();
169
    }
170

    
171
    @Override
172
    public JComponent asJComponent() {
173
//        if (this.features == null) {
174
//            try {
175
                updateForm();
176
//            } catch (Exception ex) {
177
//                throw new RuntimeException(ex);
178
//            }
179
//        }
180
        return this.panel;
181
    }
182

    
183
    @Override
184
    public void bind(FeatureStore store, List<FeatureReference> references) {
185
        this.bind(store, null, references);
186
    }
187
    
188
    public void bind(FeatureStore store, DynClass definition, List<FeatureReference> references) {
189
        if (store == null || references == null) {
190
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
191
        }
192
        try {
193
            DynFormManager formManager = DynFormLocator.getDynFormManager();
194
            if (definition == null) {
195
                DefaultDataSwingManager manager = (DefaultDataSwingManager) DALSwingLocator.getSwingManager();
196
                definition = manager.featureType2DynClass(store, store.getDefaultFeatureType());
197
            }
198
            this.store = store;
199
            this.definition = formManager.getDefinition(definition);
200
            this.setFeatures(references);
201
            
202
        } catch (Exception ex) {
203
            throw new RuntimeException("Can't bind features of '" + store.getName() + "' to form", ex);
204
        }
205
    }
206

    
207
    @Override
208
    public void dispose() {
209
        this.panel = null;
210
        this.formset = null;
211
        this.features = null;
212
        this.definition = null;
213
    }
214

    
215
    @Override
216
    public JDynFormSet getFormset() {
217
        if (this.formset == null) {
218
            DynFormManager formManager = DynFormLocator.getDynFormManager();
219
            this.formset = formManager.createJDynFormSet(
220
                    new DefaultFeaturesFormContext(this.store) {
221
                        @Override
222
                        public Feature getCurrentFeature() {    
223
                            return DefaultJFeatureReferencesForm.this.getCurrentFeature();
224
                        }
225
                    },
226
                    this.definition,
227
                    null
228
            );
229

    
230
            List<String> groups = this.definition.getGroups();
231
            if (groups.size() == 1 && groups.get(0) == null) {
232
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
233
            } else {
234
                this.formset.setLayoutMode(JDynForm.USE_TABS);
235
            }
236
            this.formset.setAllowNew(false);
237
            this.formset.setAllowDelete(false);
238
            this.formset.setAllowUpdate(true);
239
            this.formset.setAllowClose(true);
240
            this.formset.setAllowSearch(false);
241
            this.formset.setAutosave(true);
242

    
243
            this.formset.addAction(new RefreshAction());
244

    
245
            this.formset.addListener(new FormSetListener());
246
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
247
                @Override
248
                public void message(String string) {
249
                }
250

    
251
                @Override
252
                public void fieldChanged(JDynFormField jdff) {
253
                    updateButtonEnabledStatus();
254
                }
255
            });
256

    
257
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
258
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
259
            this.panel.revalidate();
260
            ToolsSwingUtils.ensureRowsCols(this.panel, 8, 70, 25, 100);
261

    
262
        }
263
        updateButtonEnabledStatus();
264
        return this.formset;
265
    }
266

    
267
    @Override
268
    public long getCurrentIndex() {
269
        if (this.formset == null) {
270
            return -1;
271
        }
272
        return this.formset.getCurrentIndex();
273
    }
274

    
275
    @Override
276
    public Feature get(long index) {
277
        if (this.formset == null || this.features == null) {
278
            return null;
279
        }
280
        return this.features.get((int)index); 
281
    }
282

    
283
    private class RefreshAction extends AbstractAction {
284

    
285
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
286
        public RefreshAction() {
287
            I18nManager i18nManager = ToolsLocator.getI18nManager();
288
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
289

    
290
            this.putValue(NAME, null);
291
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
292
            this.putValue(SMALL_ICON, iconTheme.get("form-refresh-data"));
293
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
294
            this.setEnabled(!formset.isInNewState());
295
        }
296

    
297
        @Override
298
        public void actionPerformed(ActionEvent ae) {
299
            try {
300
                I18nManager i18n = ToolsLocator.getI18nManager();
301
                formset.message(i18n.getTranslation("_Form_reloaded"));
302
                int x = formset.getCurrentIndex();
303
                updateForm();
304
                formset.setCurrentIndex(x);
305
            } catch (Exception ex) {
306
                LOGGER.warn("Can't reload form", ex);
307
            }
308
        }
309
    }
310

    
311
    @Override
312
    public void showForm(MODE mode) {
313
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
314
        String title = this.definition.getLabel();
315
        winmgr.showWindow(this.asJComponent(), title, mode);
316
    }
317

    
318
    private void saveChanges(JDynFormSet theFormSet) {
319
        I18nManager i18n = ToolsLocator.getI18nManager();
320
        try {
321
            int index = theFormSet.getCurrentIndex();
322
            DynObject currentElement = theFormSet.get(index);
323
            theFormSet.getFormValues(currentElement);            
324
            store.update(((FacadeOfAFeature) currentElement).getEditableFeature());
325
            this.formset.message(i18n.getTranslation("_Record_saved"));
326
            try {
327
                this.formset.setCurrentIndex(index);
328
            } catch (Exception ex) {
329
                LOGGER.warn("Can't reload form data after insert.", ex);
330
            }
331
        } catch (Exception ex) {
332
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
333
            throw new RuntimeException("Can't save values", ex);
334

    
335
        } finally {
336
            updateButtonEnabledStatus();
337
        }
338

    
339
    }
340

    
341
    @Override
342
    public void saveChanges() {
343
        if (this.formset != null && this.formset.countValues() > 0) {
344
            this.saveChanges(this.formset);
345
        }
346
    }
347

    
348
    private void updateButtonEnabledStatus() {
349
        if (this.formset == null) {
350
            return;
351
        }
352
        if (this.store == null || store.isBroken() || this.references == null) {
353
            this.formset.setReadOnly(true);
354
            formset.setActionEnabled(ACTION_SAVE, false);
355
            formset.setActionEnabled(REFRESHFORM_ACTION, false);
356
            formset.setActionEnabled(ACTION_NAVIGATION, false);
357
            return;
358
        }
359
        this.formset.setReadOnly(false);
360
        if (this.features != null && this.features.isEmpty()) {
361
            formset.getForm().setReadOnly(true);
362
            formset.setActionEnabled(ACTION_SAVE, false);
363
            formset.setActionEnabled(REFRESHFORM_ACTION, false);
364
            formset.setActionEnabled(ACTION_NAVIGATION, false);
365

    
366
        } else if (formset.getForm().isModified()) {
367
            formset.setActionEnabled(ACTION_SAVE, true);
368
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
369
            formset.setActionEnabled(ACTION_NAVIGATION, true);
370

    
371
        } else {
372
            formset.setActionEnabled(ACTION_SAVE, false);
373
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
374
            formset.setActionEnabled(ACTION_NAVIGATION, true);
375
        }
376
    }
377

    
378
    private void clearUniqueFields() {
379
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
380
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
381
                JDynFormField field = formset.getForm().getField(attr.getName());
382
                if (field != null) {
383
                    field.clear();
384
                }
385
            }
386
        }
387
    }
388

    
389
    private void setEnabledUniqueFields(boolean enabled) {
390
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
391
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
392
                JDynFormField field = formset.getForm().getField(attr.getName());
393
                if (field != null) {
394
                    field.setReadOnly(!enabled);
395
                }
396
            }
397
        }
398
    }
399

    
400
    @Override
401
    public long getDataSetSize() {
402
        if (this.references != null) {
403
            return references.size();
404
        }
405
        return 0;
406
    }
407

    
408
    @Override
409
    public FeatureStore getFeatureStore() {
410
        return this.store;
411
    }
412

    
413
    private class FormSetListener implements JDynFormSetListener {
414

    
415
        @Override
416
        public void formMessage(String message) {
417
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
418
        }
419

    
420
        @Override
421
        public void formClose() {
422
            panel.setVisible(false);
423
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
424
        }
425

    
426
        @Override
427
        public void formMovedTo(int currentPosition) throws AbortActionException {
428
            LOGGER.trace("formMovedTo " + currentPosition);
429
            updateButtonEnabledStatus();
430
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
431
        }
432

    
433
        @Override
434
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
435
            LOGGER.trace("formBeforeSave");
436
            saveChanges(dynformSet);
437
            updateButtonEnabledStatus();
438
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
439
        }
440

    
441
        @Override
442
        public void formBeforeNew(JDynFormSet dynformSet) throws AbortActionException {
443
            LOGGER.trace("formBeforeNew");
444
            clearUniqueFields();
445
            updateButtonEnabledStatus();
446
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeNew"));
447
        }
448

    
449
        @Override
450
        public void formBeforeDelete(JDynFormSet dynformSet) throws AbortActionException {
451
            LOGGER.trace("formBeforeDelete");
452
            updateButtonEnabledStatus();
453
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeDelete"));
454
        }
455

    
456
        @Override
457
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
458
            LOGGER.trace("formAfterSave");
459
            updateButtonEnabledStatus();
460
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
461
        }
462

    
463
        @Override
464
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
465
            LOGGER.trace("formAfterNew");
466
            updateButtonEnabledStatus();
467
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
468
        }
469

    
470
        @Override
471
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
472
            LOGGER.trace("formAfterDelete");
473
        }
474

    
475
        @Override
476
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
477
            LOGGER.trace("formBeforeSearch");
478
        }
479

    
480
        @Override
481
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
482
            LOGGER.trace("formAfterSearch");
483
        }
484

    
485
        @Override
486
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
487
            LOGGER.trace("formBeforeCancelNew");
488
            updateButtonEnabledStatus();
489
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
490
        }
491

    
492
        @Override
493
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
494
            LOGGER.trace("formAfterCancelNew");
495
            updateButtonEnabledStatus();
496
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
497
        }
498
    }
499

    
500
    @Override
501
    public void addActionListener(ActionListener listener) {
502
        this.actionListeners.addActionListener(listener);
503
    }
504

    
505
    @Override
506
    public ActionListener[] getActionListeners() {
507
        return this.actionListeners.getActionListeners();
508
    }
509

    
510
    @Override
511
    public void removeActionListener(ActionListener listener) {
512
        this.actionListeners.removeActionListener(listener);
513
    }
514

    
515
    @Override
516
    public void removeAllActionListener() {
517
        this.actionListeners.removeAllActionListener();
518
    }
519

    
520
    @Override
521
    public void fireActionEvent(ActionEvent event) {
522
        this.actionListeners.fireActionEvent(event);
523
    }
524

    
525
    @Override
526
    public boolean hasActionListeners() {
527
        return this.actionListeners.hasActionListeners();
528
    }
529

    
530
    @Override
531
    public void setFeatures(List<FeatureReference> references) {
532
        this.references = references;
533
        this.features = new FeaturesList(references);
534
        this.dynobjects = new DynObjectsList(references);
535
        if (formset != null) {
536
            this.panel.remove(formset.asJComponent());
537
            this.panel.revalidate();
538
            this.formset = null;
539
        }
540
        this.updateForm();
541
    }
542

    
543
    @Override
544
    public Feature getCurrentFeature() {
545
        long index = getCurrentIndex();
546
        if( index<0 ) {
547
            return null;
548
        }
549
        Feature f = get(index);
550
        try {
551
            DynObject adapter = f.getAsDynObject();
552
            this.getFormset().getForm().getValues(adapter);
553
            f = ((FacadeOfAFeature)adapter).getFeature();
554
            return f;
555
        } catch(Exception ex) {
556
            return f;
557
        }
558
    }
559

    
560
}