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 / fmap / dal / swing / impl / featuretype / DefaultFeatureTypePanel.java @ 44678

History | View | Annotate | Download (20.2 KB)

1
package org.gvsig.fmap.dal.swing.impl.featuretype;
2

    
3
import org.gvsig.fmap.dal.swing.featuretype.FeatureTypePanel;
4
import java.awt.BorderLayout;
5
import java.awt.Dimension;
6
import java.awt.event.ActionEvent;
7
import java.awt.event.ActionListener;
8
import java.util.ArrayList;
9
import java.util.Objects;
10
import javax.swing.JComponent;
11
import javax.swing.JOptionPane;
12
import javax.swing.event.ChangeListener;
13
import javax.swing.event.ListSelectionEvent;
14
import javax.swing.event.ListSelectionListener;
15
import javax.swing.event.TableModelEvent;
16
import javax.swing.table.AbstractTableModel;
17
import org.apache.commons.lang3.StringUtils;
18
import org.gvsig.configurableactions.ConfigurableActionsMamager;
19
import org.gvsig.expressionevaluator.ExpressionUtils;
20
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
21
import org.gvsig.fmap.dal.feature.EditableFeatureType;
22
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
23
import org.gvsig.fmap.dal.feature.FeatureStore;
24
import org.gvsig.fmap.dal.feature.FeatureType;
25
import org.gvsig.tools.ToolsLocator;
26
import org.gvsig.tools.dataTypes.DataType;
27
import org.gvsig.tools.dataTypes.DataTypes;
28
import org.gvsig.tools.dynobject.DynStruct_v2;
29
import org.gvsig.tools.i18n.I18nManager;
30
import org.gvsig.tools.swing.api.ChangeListenerHelper;
31
import org.gvsig.tools.swing.api.ToolsSwingLocator;
32
import org.gvsig.tools.swing.api.ToolsSwingManager;
33
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
34
import org.gvsig.tools.util.ToolsUtilLocator;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
/**
39
 *
40
 * @author jjdelcerro
41
 */
42
public class DefaultFeatureTypePanel 
43
        extends FeatureTypePanelView
44
        implements FeatureTypePanel
45
    {
46

    
47
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureTypePanel.class);
48
    private FeatureType originalFeatureType = null;
49

    
50
    private class FeatureTypeTableModel extends AbstractTableModel {
51

    
52
        private final FeatureType featureType;
53
        private final String[] columnNames = new String[] {
54
          "Name",
55
          "Type",
56
          "Size",
57
          "Precision",
58
          "Scale",
59
          "Default value",
60
          "Calculated"
61
        };
62
        private final Class[] columnClasses = new Class[] {
63
          String.class,
64
          String.class,
65
          Integer.class,
66
          Integer.class,
67
          Integer.class,
68
          String.class,
69
          Boolean.class
70
        };
71
        
72
        public FeatureTypeTableModel() {
73
            this.featureType = null;
74
        }
75
        
76
        public FeatureTypeTableModel(FeatureType featureType) {
77
            this.featureType = featureType;
78
        }
79
        
80
        @Override
81
        public int getRowCount() {
82
            if( this.featureType==null ) {
83
                return 0;
84
            }
85
            return this.featureType.size();
86
        }
87

    
88
        @Override
89
        public int getColumnCount() {
90
            if( this.featureType==null ) {
91
                return 0;
92
            }
93
            return this.columnNames.length;
94
        }
95

    
96
        @Override
97
        public String getColumnName(int columnIndex) {
98
            if( this.featureType==null ) {
99
                return "";
100
            }
101
            return this.columnNames[columnIndex];
102
        }
103

    
104
        @Override
105
        public Class<?> getColumnClass(int columnIndex) {
106
            if( this.featureType==null ) {
107
                return String.class;
108
            }
109
            return this.columnClasses[columnIndex];
110
        }
111

    
112
        @Override
113
        public boolean isCellEditable(int rowIndex, int columnIndex) {
114
            return false;
115
        }
116

    
117
        @Override
118
        public Object getValueAt(int rowIndex, int columnIndex) {
119
            if( this.featureType==null ) {
120
                return "";
121
            }
122
            FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(rowIndex);
123
            DataType dataType = descriptor.getDataType();
124
            switch(columnIndex) {
125
                case 0:
126
                    return descriptor.getName();
127
                case 1:
128
                    return descriptor.getDataTypeName();
129
                case 2:
130
                    if( dataType.supportSize() ) {
131
                      return descriptor.getSize();
132
                    }
133
                    return null;
134
                case 3:
135
                    if( dataType.supportPrecision()) {
136
                      return descriptor.getPrecision();
137
                    }
138
                    return null;
139
                case 4:
140
                    if( dataType.supportScale()) {
141
                      return descriptor.getScale();
142
                    }
143
                    if( dataType.isNumeric() ) {
144
                      return 0;
145
                    }
146
                    return null;
147
                case 5:
148
                    return Objects.toString(descriptor.getDefaultValue(),"");
149
                case 6:
150
                    return descriptor.isComputed();
151
                default:
152
                    return "";
153
            }
154
        }
155

    
156
        @Override
157
        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
158
        }
159
    
160
        public void fireUpdateEvent() {
161
            this.fireTableChanged(new TableModelEvent(this));
162
        }
163
    }
164
    
165
    private DefaultFeatureTypeAttributePanel descriptorPanel;
166
    private EditableFeatureType featureType;
167
    private int mode;
168
    private FeatureTypeTableModel tableModel;
169
    private FeatureStore store;
170
    private int currentRow;
171
    private boolean fieldSelectionAllowed;
172
    private TagsController tagsController;
173
    private ChangeListenerHelper changeListenerHelper;
174
        
175
    public DefaultFeatureTypePanel() {
176
        this.mode = MODE_SHOW_ONLY;
177
        this.currentRow = -1;
178
        this.fieldSelectionAllowed = true;
179
        this.initComponents();
180
    }
181

    
182
    @SuppressWarnings("Convert2Lambda")
183
    private void initComponents() {
184
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
185
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
186
        JComponent c = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
187
        this.pnlCfgActions.setLayout(new BorderLayout(0,0));
188
        this.pnlCfgActions.add(c, BorderLayout.CENTER);
189

    
190
        this.changeListenerHelper = swingManager.createChangeListenerHelper();
191
        
192
        swingManager.translate(this.btnDelete);
193
        swingManager.translate(this.btnFormFieldAccept);
194
        swingManager.translate(this.btnFormFieldDiscard);
195
        swingManager.translate(this.btnFormFieldModify);
196
        swingManager.translate(this.btnNew);
197
        swingManager.translate(this.lblLabel);
198
        swingManager.translate(this.lblDescription);
199
        swingManager.translate(this.lblTags);
200
        swingManager.translate(this.tabFeatureType);
201
                
202
        this.tableModel = new FeatureTypeTableModel();
203
        this.tblFields.setModel(this.tableModel);
204
        this.tblFields.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
205
            @Override
206
            public void valueChanged(ListSelectionEvent e) {
207
                if( e.getValueIsAdjusting() ) {
208
                    return;
209
                }
210
                doChangeFieldSelection();
211
            }
212
        });
213
        this.descriptorPanel = new DefaultFeatureTypeAttributePanel();
214
        this.pnlField.setLayout(new BorderLayout());
215
        this.pnlField.add(this.descriptorPanel, BorderLayout.CENTER);
216
        this.descriptorPanel.setEnabled(false);
217

    
218
        this.btnFormFieldModify.addActionListener(new ActionListener() {
219
            @Override
220
            public void actionPerformed(ActionEvent e) {
221
                doFormFieldModify();
222
            }
223
        });
224
        this.btnFormFieldDiscard.addActionListener(new ActionListener() {
225
            @Override
226
            public void actionPerformed(ActionEvent e) {
227
                doFormFieldDiscard();
228
            }
229
        });
230
        this.btnFormFieldAccept.addActionListener(new ActionListener() {
231
            @Override
232
            public void actionPerformed(ActionEvent e) {
233
                doFormFieldAccept();
234
            }
235
        });
236
        this.btnNew.addActionListener(new ActionListener() {
237
            @Override
238
            public void actionPerformed(ActionEvent e) {
239
                doNewField();
240
            }
241
        });
242
        this.btnDelete.addActionListener(new ActionListener() {
243
            @Override
244
            public void actionPerformed(ActionEvent e) {
245
                doDeleteField();
246
            }
247
        });
248
        
249
        this.tagsController = new TagsController(
250
                tblTags, 
251
                cboTagsName, 
252
                cboTagsValue, 
253
                btnTagsAdd, 
254
                btnTagsUpdate, 
255
                btnTagsRemove,
256
                lblTagsDescription
257
        );
258

    
259
        
260
        this.setPreferredSize(new Dimension(700, 500));
261
        if( this.tblFields.getRowCount()>0 ) {
262
            this.tblFields.getSelectionModel().setSelectionInterval(0, 0);
263
            doFormFieldPut();
264
        }
265
    }
266
       
267
    private boolean doFormFieldFetch() {
268
        int row = this.tblFields.getSelectedRow();
269
        if (row < 0) {
270
            return true;
271
        }
272
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
273
        int previousType = descriptor.getType();
274
        if (descriptor instanceof EditableFeatureAttributeDescriptor) {
275
            if (this.descriptorPanel.fetch((EditableFeatureAttributeDescriptor) descriptor) == null) {
276
                return false;
277
            }
278
            this.tableModel.fireUpdateEvent();
279
        }
280
        FeatureAttributeDescriptor oldDescriptor = null;
281
        if (this.originalFeatureType != null) {
282
            oldDescriptor = this.originalFeatureType.getAttributeDescriptor(descriptor.getName());
283
        }
284
        if (oldDescriptor != null
285
                && oldDescriptor.getDataType() != descriptor.getDataType()
286
                && previousType != descriptor.getType()) {
287
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
288
            I18nManager i18manager = ToolsLocator.getI18nManager();
289
            StringBuilder message = new StringBuilder();
290

    
291
            String[] messageArgs = new String[]{oldDescriptor.getName()};
292
            message.append(i18manager.getTranslation("_Already_existed_a_field_named_XfieldnameX_but_with_different_data_type", messageArgs));
293
            message.append(".\n");
294
            message.append(i18manager.getTranslation("_Values_of_data_will_try_to_coerce_to_this_type"));
295
            dialogs.messageDialog(
296
                    message.toString(),
297
                    null,
298
                    i18manager.getTranslation("_Values_will_change"),
299
                    JOptionPane.INFORMATION_MESSAGE,
300
                    "feature-type-manager-field-already-exist-in-previous-schema");
301
        }
302

    
303
        return true;
304
    }
305
    
306
    private void doFormFieldPut() {
307
        int row = this.tblFields.getSelectedRow();
308
        if( row<0 ) {
309
            return;
310
        }
311
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
312
        this.currentRow = row;
313
        this.descriptorPanel.put(descriptor);
314
        updateButtonState();
315
        if( descriptor instanceof EditableFeatureAttributeDescriptor ) {
316
            this.btnFormFieldModify.setEnabled((this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA) && this.tblFields.getSelectedRowCount()==1);
317
        } else {
318
            this.btnFormFieldModify.setEnabled(false);
319
        }
320
    }
321
    
322
    private void updateButtonState() {
323
        this.descriptorPanel.setEnabled(true);
324
        this.descriptorPanel.setMode(MODE_SHOW_ONLY);
325
        this.btnFormFieldAccept.setEnabled(false);
326
        this.btnFormFieldDiscard.setEnabled(false);
327
        
328
        switch(this.mode) {
329
            case MODE_EDIT_ALL:
330
                this.btnDelete.setEnabled(true);
331
                this.btnFormFieldModify.setEnabled(true);
332
                this.btnNew.setEnabled(true);
333
                this.tagsController.setEditable(true);
334
                this.txtLabel.setEditable(true);
335
                this.txtDescription.setEditable(true);
336
                break;
337
            case MODE_EDIT_ONLY_METADATA:
338
                this.btnDelete.setEnabled(this.descriptorPanel.isVirtualField());
339
                this.btnFormFieldModify.setEnabled(true);
340
                this.btnNew.setEnabled(true);
341
                this.tagsController.setEditable(true);
342
                this.txtLabel.setEditable(true);
343
                this.txtDescription.setEditable(true);
344
                break;
345
            case MODE_SHOW_ONLY:
346
                this.btnDelete.setEnabled(false);
347
                this.btnFormFieldModify.setEnabled(false);
348
                this.btnNew.setEnabled(false);
349
                this.tagsController.setEditable(false);
350
                this.txtLabel.setEditable(false);
351
                this.txtDescription.setEditable(false);
352
                break;
353
        }
354
    }
355
    
356
    private void doFormFieldModify() {
357
        int row = this.tblFields.getSelectedRow();
358
        if( row<0 ) {
359
            return;
360
        }
361
        FeatureAttributeDescriptor descriptor = this.featureType.getAttributeDescriptor(row);
362
        this.descriptorPanel.put(descriptor);
363
        this.descriptorPanel.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
364
        this.btnFormFieldAccept.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
365
        this.btnFormFieldDiscard.setEnabled(this.mode==MODE_EDIT_ALL || this.mode==MODE_EDIT_ONLY_METADATA);
366
        this.btnFormFieldModify.setEnabled(false);
367
        this.btnNew.setEnabled(false);
368
        this.btnDelete.setEnabled(false);
369
        if( descriptor instanceof EditableFeatureAttributeDescriptor ) {
370
            this.descriptorPanel.setMode(this.mode);
371
        } else {
372
            this.descriptorPanel.setMode(MODE_SHOW_ONLY);
373
        }
374
        this.fieldSelectionAllowed = false;
375
        this.changeListenerHelper.fireEvent();
376
    }
377
    
378
    @Override
379
    public boolean isModifyingAField() {
380
        return btnFormFieldAccept.isEnabled();
381
    }
382
    
383
    private void doFormFieldAccept() {
384
        int row = this.tblFields.getSelectedRow();
385
        if( row<0 ) {
386
            return;
387
        }
388
        if( doFormFieldFetch() ) {
389
            this.updateButtonState();
390
            this.tblFields.getSelectionModel().setSelectionInterval(row, row);
391
            this.tblFields.scrollRectToVisible(this.tblFields.getCellRect(row, 0, true));
392
            this.fieldSelectionAllowed = true;
393
        }
394
        this.changeListenerHelper.fireEvent();
395
    }
396
    
397
    private void doFormFieldDiscard() {
398
        doFormFieldPut();
399
        this.updateButtonState();
400
        this.fieldSelectionAllowed = true;
401
        this.changeListenerHelper.fireEvent();
402
    }
403

    
404
    private void doChangeFieldSelection() {
405
        int row = this.tblFields.getSelectedRow();
406
        if( row<0 ) {
407
            return;
408
        }
409
        if( !this.fieldSelectionAllowed ) {
410
            if( row !=this.currentRow ) {
411
                I18nManager i18n = ToolsLocator.getI18nManager();
412
                JOptionPane.showMessageDialog(
413
                    this, 
414
                    i18n.getTranslation("_Before_changing_field_accept_or_discard_the_changes"), 
415
                    i18n.getTranslation("_Warning"), 
416
                    JOptionPane.WARNING_MESSAGE
417
                );
418
                this.tblFields.getSelectionModel().setSelectionInterval(
419
                        this.currentRow, 
420
                        this.currentRow
421
                );
422
            }
423
            return;
424
        }
425
        doFormFieldPut();   
426
    }
427
    
428
    @Override
429
    public JComponent asJComponent() {
430
        return this;
431
    }
432

    
433
    @Override
434
    public int getMode() {
435
        return this.mode;
436
    }
437
    
438
    @Override
439
    public void setMode(int mode) {
440
        this.mode = mode;
441
        updateButtonState();
442
    }
443

    
444
    @Override
445
    public EditableFeatureType fetch(EditableFeatureType type) {
446
        if( type == null ) {
447
            type = (EditableFeatureType) this.featureType.getCopy();
448
        } else {
449
            type.removeAll();
450
            type.copyFrom(this.featureType);
451
        }
452
        type.setLabel(
453
            StringUtils.defaultIfBlank(this.txtLabel.getText(), null)
454
        );
455
        type.setDescription(
456
            StringUtils.defaultIfBlank(this.txtDescription.getText(), null)
457
        );
458
        this.tagsController.fetch(type.getTags());
459
        return type;
460
    }
461

    
462
    @Override
463
    public void put(FeatureType type) {
464
        this.featureType = null;
465
        this.originalFeatureType = null;
466
        if (type == null) {
467
            this.store = null;
468
        } else {
469
            FeatureType ftypeToCompare = type.getOriginalFeatureType();
470
            if (ftypeToCompare == null) {
471
                ftypeToCompare = type;
472
            }
473
            this.originalFeatureType = ftypeToCompare.getCopy();
474
            this.featureType = (EditableFeatureType) type.getCopy();
475
            // Nos quedamos una referencia para evitar que se destruya, ya que
476
            // el featureType se guarda solo una WeakReference.
477
            this.store = type.getStore();
478
            this.txtLabel.setText(
479
                    StringUtils.defaultIfBlank(((DynStruct_v2) type).getLabel(), "")
480
            );
481
            this.txtDescription.setText(
482
                    StringUtils.defaultIfBlank(((DynStruct_v2) type).getDescription(), "")
483
            );
484
            this.tagsController.set(((DynStruct_v2) type).getTags());
485
        }
486
        if( !(type instanceof EditableFeatureType) ) {
487
            this.setMode(MODE_SHOW_ONLY);
488
        }
489
        this.tableModel = new FeatureTypeTableModel(this.featureType);
490
        this.tblFields.setModel(this.tableModel);
491
        if( type!=null && !type.isEmpty() ) {
492
            this.tblFields.getSelectionModel().setSelectionInterval(0, 0);
493
        }
494
        updateButtonState();
495
        doFormFieldPut();       
496
    }
497

    
498
    private void doNewField() {
499
        EditableFeatureType eft = (EditableFeatureType)this.featureType;
500
        EditableFeatureAttributeDescriptor descriptor = eft.add(
501
                this.featureType.getNewFieldName(), 
502
                DataTypes.STRING,
503
                50
504
        );
505
        if( this.mode == MODE_EDIT_ONLY_METADATA ) {
506
            descriptor.setFeatureAttributeEmulator(ExpressionUtils.createExpression("NULL"));
507
        }
508
        this.tableModel.fireUpdateEvent();
509
        int row = descriptor.getIndex();
510
        this.tblFields.getSelectionModel().addSelectionInterval(row,row);
511
        this.tblFields.scrollRectToVisible(this.tblFields.getCellRect(row, 0, true));
512
        updateButtonState();
513
        doFormFieldModify();    
514
        this.changeListenerHelper.fireEvent();
515
    }
516
    
517
    private void doDeleteField() {
518
        int row = this.tblFields.getSelectedRow();
519
        int[] rows = this.tblFields.getSelectedRows();
520
        ArrayList FeatureAttributeDescriptor;
521
        ArrayList<String> descriptors = new ArrayList<>();
522
        for (int rowDescriptor : rows) {
523
            if (rowDescriptor < 0) {
524
                continue;
525
            }
526
            descriptors.add(this.featureType.getAttributeDescriptor(rowDescriptor).getName());
527
        }
528
        for (String descriptor : descriptors) {
529
            ((EditableFeatureType)this.featureType).remove(descriptor);
530
        }
531
        this.tableModel.fireUpdateEvent();
532
        if( row >= this.tblFields.getRowCount()) {
533
            row = this.tblFields.getRowCount()-1;
534
        }
535
        this.tblFields.getSelectionModel().addSelectionInterval(row,row);
536
        updateButtonState();
537
        doFormFieldPut();       
538
        this.changeListenerHelper.fireEvent();
539
    }
540

    
541
    @Override
542
    public void addChangeListener(ChangeListener listener) {
543
        this.changeListenerHelper.addChangeListener(listener);
544
    }
545

    
546
    @Override
547
    public ChangeListener[] getChangeListeners() {
548
        return this.changeListenerHelper.getChangeListeners();
549
    }
550

    
551
    @Override
552
    public void removeChangeListener(ChangeListener listener) {
553
        this.changeListenerHelper.removeChangeListener(listener);
554
    }
555

    
556
    @Override
557
    public void removeAllChangeListener() {
558
        this.changeListenerHelper.removeAllChangeListener();
559
    }
560

    
561
    @Override
562
    public boolean hasChangeListeners() {
563
        return this.changeListenerHelper.hasChangeListeners();
564
    }
565
    
566
}