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

History | View | Annotate | Download (20 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.expressionevaluator.ExpressionEvaluatorLocator;
41
import org.gvsig.featureform.swing.JFeatureReferencesForm;
42
import org.gvsig.fmap.dal.StoresRepository;
43
import org.gvsig.fmap.dal.exception.DataException;
44
import org.gvsig.fmap.dal.feature.FacadeOfAFeature;
45
import org.gvsig.fmap.dal.feature.Feature;
46
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
47
import org.gvsig.fmap.dal.feature.FeatureReference;
48
import org.gvsig.fmap.dal.feature.FeatureStore;
49
import org.gvsig.fmap.dal.feature.FeatureType;
50
import org.gvsig.fmap.dal.swing.DALSwingLocator;
51
import org.gvsig.fmap.dal.swing.impl.DefaultDataSwingManager;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dispose.Disposable;
54
import org.gvsig.tools.dynform.AbortActionException;
55
import org.gvsig.tools.dynform.DynFormDefinition;
56
import org.gvsig.tools.dynform.DynFormLocator;
57
import org.gvsig.tools.dynform.DynFormManager;
58
import org.gvsig.tools.dynform.JDynForm;
59
import org.gvsig.tools.dynform.JDynFormField;
60
import org.gvsig.tools.dynform.JDynFormSet;
61
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_NAVIGATION;
62
import static org.gvsig.tools.dynform.JDynFormSet.ACTION_SAVE;
63
import org.gvsig.tools.dynform.JDynFormSet.JDynFormSetListener;
64
import org.gvsig.tools.dynobject.DynClass;
65
import org.gvsig.tools.dynobject.DynObject;
66
import org.gvsig.tools.i18n.I18nManager;
67
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
68
import org.gvsig.tools.script.ScriptManager;
69
import org.gvsig.tools.swing.api.ActionListenerSupport;
70
import org.gvsig.tools.swing.api.ToolsSwingLocator;
71
import org.gvsig.tools.swing.api.ToolsSwingUtils;
72
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
73
import org.gvsig.tools.swing.api.windowmanager.WindowManager.MODE;
74
import org.gvsig.tools.swing.icontheme.IconTheme;
75
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
77

    
78
/**
79
 * @author fdiaz
80
 *
81
 */
82
@SuppressWarnings("UseSpecificCatch")
83
public class DefaultJFeatureReferencesForm implements Disposable, JFeatureReferencesForm {
84

    
85
    private final String REFRESHFORM_ACTION = "refreshForm";
86

    
87
    public static class FeaturesList extends AbstractList<Feature> {
88

    
89
        private final List<FeatureReference> references;
90

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

    
104
        @Override
105
        public int size() {
106
            return this.references.size();
107
        }
108
        
109
    }
110
    
111
    public static class DynObjectsList extends AbstractList<DynObject> {
112

    
113
        private final List<FeatureReference> references;
114

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

    
129
        @Override
130
        public int size() {
131
            return this.references.size();
132
        }
133
        
134
    }
135
    
136
    public class DefaultFeaturesFormContext implements FeaturesFormContext {
137

    
138
        private DefaultFeaturesFormContext() {
139

    
140
        }
141

    
142
        @Override
143
        public FeatureStore getFeatureStore() {
144
            return store;
145
        }
146

    
147
        @Override
148
        public FeatureType getFeatureType() {
149
            try {
150
                return store.getDefaultFeatureType();
151
            } catch (DataException ex) {
152
                return null;
153
            }
154
        }
155

    
156
        @Override
157
        public ResourcesStorage getResourcesStorage() {
158
            if (store == null) {
159
                return null;
160
            }
161
            return store.getResourcesStorage();
162
        }
163

    
164
        @Override
165
        public StoresRepository getStoresRepository() {
166
            if (store == null) {
167
                return null;
168
            }
169
            return store.getStoresRepository();
170
        }
171

    
172
        @Override
173
        public ScriptManager getScriptManager() {
174
            return ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
175
        }
176

    
177
    }
178

    
179
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultJFeatureReferencesForm.class);
180

    
181
    private JPanel panel;
182
    private JDynFormSet formset;
183
    private DynFormDefinition definition = null;
184
    private final ActionListenerSupport actionListeners;
185
    private List<FeatureReference> references;
186
    private List<Feature> features;
187
    private List<DynObject> dynobjects;
188
    private FeatureStore store;
189
    
190

    
191
    public DefaultJFeatureReferencesForm() {
192
        this.panel = new JPanel(new BorderLayout());
193
        this.panel.addComponentListener(new ComponentAdapter() {
194
            @Override
195
            public void componentHidden(ComponentEvent e) {
196
                dispose();
197
            }
198
        });
199
        this.actionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
200
    }
201

    
202
    @Override
203
    public void setPreferredSize(Dimension dimension) {
204
        panel.setPreferredSize(dimension);
205
    }
206

    
207
    private void updateForm() {
208
        if (this.formset == null) {
209
            this.getFormset();
210
        }
211
        try {
212
            this.formset.setValues(this.dynobjects);
213
        } catch (Exception ex) {
214
            throw new RuntimeException("Can't update form", ex);
215
        }
216
        updateButtonEnabledStatus();
217
    }
218

    
219
    @Override
220
    public JComponent asJComponent() {
221
//        if (this.features == null) {
222
//            try {
223
                updateForm();
224
//            } catch (Exception ex) {
225
//                throw new RuntimeException(ex);
226
//            }
227
//        }
228
        return this.panel;
229
    }
230

    
231
    @Override
232
    public void bind(FeatureStore store, List<FeatureReference> references) {
233
        this.bind(store, null, references);
234
    }
235
    
236
    public void bind(FeatureStore store, DynClass definition, List<FeatureReference> references) {
237
        if (store == null || references == null) {
238
            throw new IllegalArgumentException("bind need a store as parameter, not a null.");
239
        }
240
        try {
241
            DynFormManager formManager = DynFormLocator.getDynFormManager();
242
            if (definition == null) {
243
                DefaultDataSwingManager manager = (DefaultDataSwingManager) DALSwingLocator.getSwingManager();
244
                definition = manager.featureType2DynClass(store, store.getDefaultFeatureType());
245
            }
246
            this.store = store;
247
            this.definition = formManager.getDefinition(definition);
248
            this.setFeatures(references);
249
            
250
        } catch (Exception ex) {
251
            throw new RuntimeException("Can't bind features of '" + store.getName() + "' to form", ex);
252
        }
253
    }
254

    
255
    @Override
256
    public void dispose() {
257
        this.panel = null;
258
        this.formset = null;
259
        this.features = null;
260
        this.definition = null;
261
    }
262

    
263
    @Override
264
    public JDynFormSet getFormset() {
265
        if (this.formset == null) {
266
            DynFormManager formManager = DynFormLocator.getDynFormManager();
267
            this.formset = formManager.createJDynFormSet(
268
                    new DefaultFeaturesFormContext(),
269
                    this.definition,
270
                    null
271
            );
272

    
273
            List<String> groups = this.definition.getGroups();
274
            if (groups.size() == 1 && groups.get(0) == null) {
275
                this.formset.setLayoutMode(JDynForm.USE_PLAIN);
276
            } else {
277
                this.formset.setLayoutMode(JDynForm.USE_TABS);
278
            }
279
            this.formset.setAllowNew(false);
280
            this.formset.setAllowDelete(false);
281
            this.formset.setAllowUpdate(true);
282
            this.formset.setAllowClose(true);
283
            this.formset.setAllowSearch(false);
284
            this.formset.setAutosave(true);
285

    
286
            this.formset.addAction(new RefreshAction());
287

    
288
            this.formset.addListener(new FormSetListener());
289
            this.formset.getForm().addListener(new JDynForm.JDynFormListener() {
290
                @Override
291
                public void message(String string) {
292
                }
293

    
294
                @Override
295
                public void fieldChanged(JDynFormField jdff) {
296
                    updateButtonEnabledStatus();
297
                }
298
            });
299

    
300
            ToolsSwingLocator.getToolsSwingManager().removeBorder(this.formset.asJComponent());
301
            this.panel.add(this.formset.asJComponent(), BorderLayout.CENTER);
302
            this.panel.revalidate();
303
            ToolsSwingUtils.ensureRowsCols(this.panel, 8, 70, 25, 100);
304

    
305
        }
306
        updateButtonEnabledStatus();
307
        return this.formset;
308
    }
309

    
310
    @Override
311
    public long getCurrentIndex() {
312
        if (this.formset == null) {
313
            return -1;
314
        }
315
        return this.formset.getCurrentIndex();
316
    }
317

    
318
    @Override
319
    public Feature get(long index) {
320
        if (this.formset == null || this.features == null) {
321
            return null;
322
        }
323
        return this.features.get((int)index); 
324
    }
325

    
326
    private class RefreshAction extends AbstractAction {
327

    
328
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
329
        public RefreshAction() {
330
            I18nManager i18nManager = ToolsLocator.getI18nManager();
331
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getDefault();
332

    
333
            this.putValue(NAME, null);
334
            this.putValue(SHORT_DESCRIPTION, i18nManager.getTranslation("_Reload_data"));
335
            this.putValue(SMALL_ICON, iconTheme.get("form-refresh-data"));
336
            this.putValue(ACTION_COMMAND_KEY, REFRESHFORM_ACTION);
337
            this.setEnabled(!formset.isInNewState());
338
        }
339

    
340
        @Override
341
        public void actionPerformed(ActionEvent ae) {
342
            try {
343
                I18nManager i18n = ToolsLocator.getI18nManager();
344
                formset.message(i18n.getTranslation("_Form_reloaded"));
345
                int x = formset.getCurrentIndex();
346
                updateForm();
347
                formset.setCurrentIndex(x);
348
            } catch (Exception ex) {
349
                LOGGER.warn("Can't reload form", ex);
350
            }
351
        }
352
    }
353

    
354
    @Override
355
    public void showForm(MODE mode) {
356
        WindowManager winmgr = ToolsSwingLocator.getWindowManager();
357
        String title = this.definition.getLabel();
358
        winmgr.showWindow(this.asJComponent(), title, mode);
359
    }
360

    
361
    private void saveChanges(JDynFormSet theFormSet) {
362
        I18nManager i18n = ToolsLocator.getI18nManager();
363
        try {
364
            int index = theFormSet.getCurrentIndex();
365
            DynObject currentElement = theFormSet.get(index);
366
            theFormSet.getFormValues(currentElement);            
367
            store.update(((FacadeOfAFeature) currentElement).getEditableFeature());
368
            this.formset.message(i18n.getTranslation("_Record_saved"));
369
            try {
370
                this.formset.setCurrentIndex(index);
371
            } catch (Exception ex) {
372
                LOGGER.warn("Can't reload form data after insert.", ex);
373
            }
374
        } catch (Exception ex) {
375
            theFormSet.message(i18n.getTranslation("error_saving_data_will_not_save"));
376
            throw new RuntimeException("Can't save values", ex);
377

    
378
        } finally {
379
            updateButtonEnabledStatus();
380
        }
381

    
382
    }
383

    
384
    @Override
385
    public void saveChanges() {
386
        if (this.formset != null && this.formset.countValues() > 0) {
387
            this.saveChanges(this.formset);
388
        }
389
    }
390

    
391
    private void updateButtonEnabledStatus() {
392
        if (this.formset == null) {
393
            return;
394
        }
395
        if (this.store == null || store.isBroken() || this.references == null) {
396
            this.formset.setReadOnly(true);
397
            formset.setActionEnabled(ACTION_SAVE, false);
398
            formset.setActionEnabled(REFRESHFORM_ACTION, false);
399
            formset.setActionEnabled(ACTION_NAVIGATION, false);
400
            return;
401
        }
402
        this.formset.setReadOnly(false);
403
        if (this.features != null && this.features.isEmpty()) {
404
            formset.getForm().setReadOnly(true);
405
            formset.setActionEnabled(ACTION_SAVE, false);
406
            formset.setActionEnabled(REFRESHFORM_ACTION, false);
407
            formset.setActionEnabled(ACTION_NAVIGATION, false);
408

    
409
        } else if (formset.getForm().isModified()) {
410
            formset.setActionEnabled(ACTION_SAVE, true);
411
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
412
            formset.setActionEnabled(ACTION_NAVIGATION, true);
413

    
414
        } else {
415
            formset.setActionEnabled(ACTION_SAVE, false);
416
            formset.setActionEnabled(REFRESHFORM_ACTION, true);
417
            formset.setActionEnabled(ACTION_NAVIGATION, true);
418
        }
419
    }
420

    
421
    private void clearUniqueFields() {
422
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
423
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
424
                JDynFormField field = formset.getForm().getField(attr.getName());
425
                if (field != null) {
426
                    field.clear();
427
                }
428
            }
429
        }
430
    }
431

    
432
    private void setEnabledUniqueFields(boolean enabled) {
433
        for (FeatureAttributeDescriptor attr : this.store.getDefaultFeatureTypeQuietly()) {
434
            if ((attr.isPrimaryKey() && !attr.isAutomatic()) || (attr.isIndexed() && !attr.allowIndexDuplicateds())) {
435
                JDynFormField field = formset.getForm().getField(attr.getName());
436
                if (field != null) {
437
                    field.setReadOnly(!enabled);
438
                }
439
            }
440
        }
441
    }
442

    
443
    @Override
444
    public long getDataSetSize() {
445
        if (this.references != null) {
446
            return references.size();
447
        }
448
        return 0;
449
    }
450

    
451
    @Override
452
    public FeatureStore getFeatureStore() {
453
        return this.store;
454
    }
455

    
456
    private class FormSetListener implements JDynFormSetListener {
457

    
458
        @Override
459
        public void formMessage(String message) {
460
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMessage"));
461
        }
462

    
463
        @Override
464
        public void formClose() {
465
            panel.setVisible(false);
466
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formClose"));
467
        }
468

    
469
        @Override
470
        public void formMovedTo(int currentPosition) throws AbortActionException {
471
            LOGGER.trace("formMovedTo " + currentPosition);
472
            updateButtonEnabledStatus();
473
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formMovedTo"));
474
        }
475

    
476
        @Override
477
        public void formBeforeSave(JDynFormSet dynformSet) throws AbortActionException {
478
            LOGGER.trace("formBeforeSave");
479
            saveChanges(dynformSet);
480
            updateButtonEnabledStatus();
481
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeSave"));
482
        }
483

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

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

    
499
        @Override
500
        public void formAfterSave(JDynFormSet dynformSet) throws AbortActionException {
501
            LOGGER.trace("formAfterSave");
502
            updateButtonEnabledStatus();
503
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterSave"));
504
        }
505

    
506
        @Override
507
        public void formAfterNew(JDynFormSet dynformSet) throws AbortActionException {
508
            LOGGER.trace("formAfterNew");
509
            updateButtonEnabledStatus();
510
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterNew"));
511
        }
512

    
513
        @Override
514
        public void formAfterDelete(JDynFormSet dynformSet) throws AbortActionException {
515
            LOGGER.trace("formAfterDelete");
516
        }
517

    
518
        @Override
519
        public void formBeforeSearch(JDynFormSet dynformSet) throws AbortActionException {
520
            LOGGER.trace("formBeforeSearch");
521
        }
522

    
523
        @Override
524
        public void formAfterSearch(JDynFormSet dynformSet) throws AbortActionException {
525
            LOGGER.trace("formAfterSearch");
526
        }
527

    
528
        @Override
529
        public void formBeforeCancelNew(JDynFormSet dynformSet) throws AbortActionException {
530
            LOGGER.trace("formBeforeCancelNew");
531
            updateButtonEnabledStatus();
532
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formBeforeCancelNew"));
533
        }
534

    
535
        @Override
536
        public void formAfterCancelNew(JDynFormSet dynformSet) throws AbortActionException {
537
            LOGGER.trace("formAfterCancelNew");
538
            updateButtonEnabledStatus();
539
            actionListeners.fireActionEvent(new ActionEvent(this, 1, "formAfterCancelNew"));
540
        }
541
    }
542

    
543
    @Override
544
    public void addActionListener(ActionListener listener) {
545
        this.actionListeners.addActionListener(listener);
546
    }
547

    
548
    @Override
549
    public ActionListener[] getActionListeners() {
550
        return this.actionListeners.getActionListeners();
551
    }
552

    
553
    @Override
554
    public void removeActionListener(ActionListener listener) {
555
        this.actionListeners.removeActionListener(listener);
556
    }
557

    
558
    @Override
559
    public void removeAllActionListener() {
560
        this.actionListeners.removeAllActionListener();
561
    }
562

    
563
    @Override
564
    public void fireActionEvent(ActionEvent event) {
565
        this.actionListeners.fireActionEvent(event);
566
    }
567

    
568
    @Override
569
    public boolean hasActionListeners() {
570
        return this.actionListeners.hasActionListeners();
571
    }
572

    
573
    @Override
574
    public void setFeatures(List<FeatureReference> references) {
575
        this.references = references;
576
        this.features = new FeaturesList(references);
577
        this.dynobjects = new DynObjectsList(references);
578
        if (formset != null) {
579
            this.panel.remove(formset.asJComponent());
580
            this.panel.revalidate();
581
            this.formset = null;
582
        }
583
        this.updateForm();
584
    }
585

    
586
}