Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.dynform / org.gvsig.tools.dynform.spi / src / main / java / org / gvsig / tools / dynform / spi / dynformfield / AbstractJDynFormField.java @ 2031

History | View | Annotate | Download (18.1 KB)

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

    
25
import java.awt.BorderLayout;
26
import java.awt.Color;
27
import java.util.ArrayList;
28
import java.util.HashSet;
29
import java.util.Iterator;
30
import java.util.List;
31
import java.util.Set;
32

    
33
import javax.swing.Action;
34
import javax.swing.JComboBox;
35
import javax.swing.JComponent;
36
import javax.swing.JLabel;
37
import javax.swing.JList;
38
import javax.swing.JPanel;
39
import javax.swing.JScrollPane;
40
import javax.swing.JSpinner;
41
import javax.swing.JTextField;
42
import javax.swing.JViewport;
43
import javax.swing.text.JTextComponent;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dataTypes.CoercionException;
46
import org.gvsig.tools.dataTypes.DataTypes;
47

    
48
import org.gvsig.tools.dynform.DynFormFieldDefinition;
49
import org.gvsig.tools.dynform.JDynForm;
50
import org.gvsig.tools.dynform.JDynFormField;
51
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
52
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
53
import org.gvsig.tools.dynobject.DynClass;
54
import org.gvsig.tools.dynobject.DynField;
55
import org.gvsig.tools.dynobject.DynField_v2;
56
import org.gvsig.tools.dynobject.DynObject;
57
import org.gvsig.tools.dynobject.Tags;
58
import org.slf4j.Logger;
59
import org.slf4j.LoggerFactory;
60

    
61
@SuppressWarnings({"rawtypes", "unchecked"})
62
public abstract class AbstractJDynFormField implements JDynFormField {
63

    
64
    protected static final Logger LOGGER = LoggerFactory
65
            .getLogger(AbstractJDynFormField.class);
66

    
67
    private final DynFormSPIManager manager;
68
    private final JDynFormFieldFactory factory;
69
    private final DynFormFieldDefinition definition;
70
    private final ComponentsFactory componentsFactory;
71

    
72
    private JDynForm form;
73
    
74
    protected JLabel jlabel = null;
75
    private JPanel jlabelpanel = null;
76
    private Set listeners = null;
77
    private JProblemIndicator problemIndicator = null;
78

    
79
    protected JComponent contents = null;
80

    
81
    protected boolean readOnly = false;
82
    private final List customActions;
83
    protected boolean emptyToNull = false;
84

    
85
    public AbstractJDynFormField(
86
            DynFormSPIManager serviceManager, 
87
            ComponentsFactory componentsFactory,
88
            JDynFormFieldFactory factory, 
89
            DynFormFieldDefinition definition,
90
            Object value
91
        ) {
92
        this.manager = serviceManager;
93
        this.factory = factory;
94
        this.definition = definition;
95
        this.componentsFactory = componentsFactory;
96
        this.listeners = new HashSet();
97
        this.problemIndicator = this.manager.createProblemIndicator(this);
98
        this.customActions = new ArrayList<>();
99
        if(this.definition != null){
100
                this.readOnly = this.definition.isReadOnly();
101
                this.loadDefaultValuesFromTags(definition.getTags());
102
        }
103
    }
104

    
105
    public ComponentsFactory getComponentsFactory() {
106
        return this.componentsFactory;
107
    }
108
    
109
    public void loadDefaultValuesFromTags(Tags tags) {
110
        try {
111
            this.readOnly = tags.getBoolean(DynFormSPIManager.TAG_DYNFORM_READONLY);
112
        } catch (CoercionException ex) {
113
        }
114
        try {
115
            this.emptyToNull = tags.getBoolean(DynFormSPIManager.TAG_DYNFORM_TRANSLATE_EMPTY_TO_NULL);
116
        } catch (CoercionException ex) {
117
        }
118
    }
119

    
120
    public abstract void initComponent();
121

    
122
    public abstract Object getAssignedValue();
123

    
124
//    public Object getParameterValue() {
125
//        return this.parameters.getDynValue(DynFormSPIManager.FIELD_VALUE);
126
//    }
127
//
128
    @Override
129
    public JComponent asJComponent() {
130
        if (this.contents == null) {
131
            try {
132
                this.initComponent();
133
            } catch(Throwable th) {
134
                this.contents = new JLabel("##ERROR##");
135
                this.problemIndicator().set("Can't create component");
136
            }
137
            if (!this.customActions.isEmpty()) {
138
                addPopupComponents();
139
            }
140
            if (this.readOnly) {
141
                this.setReadOnly(readOnly);
142
            }
143
        }
144
        return this.contents;
145
    }
146

    
147
    @Override
148
    public String getName() {
149
        return this.definition.getName();
150
    }
151

    
152
    @Override
153
    public String getLabel() {
154
        if (definition.getLabel() != null) {
155
            String label = definition.getLabel();
156
            label = ToolsLocator.getI18nManager().getTranslation(label);
157
            return label;
158
        } else {
159
            return this.getName();
160
        }
161
    }
162

    
163
    @Override
164
    public JComponent getJLabel() {
165
        if (this.jlabel == null) {
166
            this.jlabel = this.getComponentsFactory().getJLabel(definition, null);
167
            if( this.jlabel==null ) {
168
                this.jlabel = new JLabel();
169
            }
170
            if (!getTagValueAsBoolean(DynFormSPIManager.TAG_DYNFORM_LABEL_EMPTY, false)) {
171
                this.jlabel.setText(this.getLabel());
172
            }
173
            this.jlabel.setLabelFor(this.contents);
174
            if (this.getDefinition().isMandatory()) {
175
                this.jlabel.setForeground(Color.red.darker());
176
            }
177
            this.jlabelpanel = new JPanel();
178
            this.jlabelpanel.setLayout(new BorderLayout());
179
            this.jlabelpanel.add(jlabel, BorderLayout.CENTER);
180
            this.jlabelpanel.add(problemIndicator.asJComponent(), BorderLayout.LINE_END);
181
        }
182
        return this.jlabelpanel;
183
    }
184

    
185
    @Override
186
    public DynFormFieldDefinition getDefinition() {
187
        return this.definition;
188
    }
189
    
190
    public DynFormSPIManager getServiceManager() {
191
        return this.manager;
192
    }
193

    
194
    @Override
195
    public void addListener(JDynFormFieldListener listener) {
196
        this.listeners.add(listener);
197
    }
198

    
199
    @Override
200
    public void removeListener(JDynFormFieldListener listener) {
201
        this.listeners.remove(listener);
202
    }
203

    
204
    protected void fireFieldChangedEvent() {
205
        if( this.isReadOnly() ) {
206
            return;
207
        }
208
        Iterator it = this.listeners.iterator();
209
        while (it.hasNext()) {
210
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
211
            try {
212
                listener.fieldChanged(this);
213
            } catch (Exception ex) {
214
                LOGGER.info("Error calling listener " + listener.toString()
215
                        + "(" + listener.getClass().getName() + ") from "
216
                        + this.toString() + "(" + this.getClass().getName()
217
                        + ").", ex);
218
            }
219
        }
220
    }
221

    
222
    protected void fireFieldEnterEvent() {
223
        Iterator it = this.listeners.iterator();
224
        while (it.hasNext()) {
225
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
226
            try {
227
                listener.fieldEnter(this);
228
            } catch (Exception ex) {
229
                LOGGER.info("Error calling listener " + listener.toString()
230
                        + "(" + listener.getClass().getName() + ") from "
231
                        + this.toString() + "(" + this.getClass().getName()
232
                        + ").", ex);
233
            }
234
        }
235
    }
236

    
237
    protected void fireFieldExitEvent() {
238
        Iterator it = this.listeners.iterator();
239
        while (it.hasNext()) {
240
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
241
            try {
242
                listener.fieldExit(this);
243
            } catch (Exception ex) {
244
                LOGGER.info("Error calling listener " + listener.toString()
245
                        + "(" + listener.getClass().getName() + ") from "
246
                        + this.toString() + "(" + this.getClass().getName()
247
                        + ").", ex);
248
            }
249
        }
250
    }
251

    
252
    @Override
253
    public void fireMessageEvent(String message) {
254
        Iterator it = this.listeners.iterator();
255
        while (it.hasNext()) {
256
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
257
            try {
258
                listener.message(this, message);
259
            } catch (Exception ex) {
260
                LOGGER.info("Error calling listener " + listener.toString()
261
                        + "(" + listener.getClass().getName() + ") from "
262
                        + this.toString() + "(" + this.getClass().getName()
263
                        + ").", ex);
264
            }
265
        }
266
    }
267

    
268
    @Override
269
    public boolean isReadOnly() {
270
        return this.readOnly;
271
    }
272
    
273
    protected boolean isForcedReadOnly() {
274
        return this.getTagValueAsBoolean(DynFormSPIManager.TAG_DYNFORM_READONLY, false);
275
    }
276

    
277
    @Override
278
    public void setReadOnly(boolean readonly) {
279
        // FIXME: Implememtacion por defecto, sobreescribirla en las subclases
280
        // segun convenga para cada componente.
281
        if( !readonly && this.isForcedReadOnly() ) {
282
            readonly = true;
283
        }
284
        this.readOnly = readonly;
285
        if (jlabel != null) {
286
            this.jlabel.setEnabled(!readonly);
287
        }
288
        if (this.contents != null) {
289
            if (this.contents instanceof JTextComponent) {
290
                JTextComponent x = (JTextComponent) this.contents;
291
                x.setEditable(!readonly);
292

    
293
            } else if (this.contents instanceof JComboBox ) {
294
                JComboBox x = (JComboBox) this.contents;
295
                x.setEnabled(!readonly);
296
                
297
            } else if (this.contents instanceof JScrollPane) {
298
                try {
299
                    JViewport port = ((JScrollPane) this.contents).getViewport();
300
                    JTextComponent x = (JTextComponent) port.getView();
301
                    x.setEditable(!readonly);
302
                } catch (Exception ex) {
303
                    this.contents.setEnabled(!readOnly);
304
                }
305
            } else {
306
                this.contents.setEnabled(!readOnly);
307
            }
308
        }
309
    }
310

    
311
    public JProblemIndicator problemIndicator() {
312
        return this.problemIndicator;
313
    }
314

    
315
    public class IllegalFieldValue extends RuntimeException {
316

    
317
        /**
318
         *
319
         */
320
        private static final long serialVersionUID = -4409236610055983438L;
321

    
322
        public IllegalFieldValue(JDynFormField field, String message) {
323
            super("The value of field '" + field.getLabel() + "' is not valid. " + message);
324
        }
325
    }
326

    
327
    @Override
328
    public String toString() {
329
        return super.toString() + "{" + this.getName() + "}";
330
    }
331

    
332
    @Override
333
    public boolean isModified() {
334
        boolean modified = false;
335
        try {
336
            if (!this.isReadOnly()) {
337
                Object value = this.getValue();
338
                if (value == null) {
339
                    if (value != this.getAssignedValue()) {
340
                        modified = true;
341
                    }
342
                } else {
343
                    if (!value.equals(this.getAssignedValue())) {
344
                        modified = true;
345
                    }
346
                }
347
            }
348
        } catch (IllegalFieldValue ex) {
349
            // Si es incorrecto el valor del campo decimos a capom que esta modificado.
350
            modified = true;
351
        }
352
        return modified;
353
    }
354

    
355
    private void addPopupComponents() {
356
        Iterator it = this.customActions.iterator();
357
        while (it.hasNext()) {
358
            Object obj = it.next();
359
            if (obj != null) {
360
                Action act = (Action) obj;
361
                if (contents instanceof SupportPopupMenu) {
362
                    DynFormFieldAction sact = new DynFormFieldAction(this, act);
363
                    ((SupportPopupMenu) this.contents).addActionToPopupMenu(
364
                            sact.getName(),
365
                            sact);
366
                }
367
            } else {
368
                if (contents instanceof SupportPopupMenu) {
369
                    ((SupportPopupMenu) this.contents).addSeparatorToPopupMenu();
370
                }
371
            }
372

    
373
        }
374
    }
375

    
376
    @Override
377
    public void addActionToPopupMenu(String name, Action action) {
378
        if (contents != null) {
379
            if (contents instanceof SupportPopupMenu) {
380
                DynFormFieldAction sact = new DynFormFieldAction(this, action);
381
                ((SupportPopupMenu) this.contents).addActionToPopupMenu(
382
                        sact.getName(),
383
                        sact);
384
            }
385
        } else {
386
            this.customActions.add(action);
387
        }
388
    }
389

    
390
    @Override
391
    public void addSeparatorToPopupMenu() {
392
        if (contents != null) {
393
            if (contents instanceof SupportPopupMenu) {
394
                ((SupportPopupMenu) this.contents).addSeparatorToPopupMenu();
395
            }
396
        } else {
397
            this.customActions.add(null);
398
        }
399
    }
400

    
401
    public void setTranslateEmptyToNull(boolean emptyToNull) {
402
        this.emptyToNull = emptyToNull;
403
    }
404

    
405
    public boolean translateEmptyToNull() {
406
        return this.emptyToNull;
407
    }
408

    
409
    @SuppressWarnings("UnnecessaryReturnStatement")
410
    @Override
411
    public void clear() {
412
        if (this.contents == null) {
413
            return;
414
        }
415
        if (this.contents instanceof JTextField) {
416
            Object value = this.getDefinition().getDefaultValue();
417
            if (value != null) {
418
                value = value.toString();
419
            } else {
420
                value = "";
421
            }
422
            ((JTextField) this.contents).setText((String) value);
423
            return;
424
        }
425
        if (this.contents instanceof JSpinner) {
426
            Object value = this.getDefinition().getDefaultValue();
427
            if (value==null) {
428
                ((JSpinner) this.contents).setValue(0);
429
                return;
430
            }
431
            ((JSpinner) this.contents).setValue(value);
432
            return;
433
        }
434
        if (this.contents instanceof JList) {
435
            ((JList) this.contents).setSelectedIndex(-1);
436
            return;
437
        }
438
        if (this.contents instanceof JComboBox) {
439
            ((JComboBox) this.contents).setSelectedIndex(-1);
440
            return;
441
        }
442
    }
443

    
444
    public void setForm(JDynForm form) {
445
        this.form = form;
446
    }
447

    
448
    @Override
449
    public JDynForm getForm() {
450
        return this.form;
451
    }
452

    
453
    @Override
454
    public void fetch(DynObject container) {
455
        if( this.isReadOnly() ) {
456
            return;
457
        }
458
        Object value = this.getValue();
459
        DynClass dynclass = container.getDynClass();
460
        if( dynclass!=null ) {
461
            DynField dynfield = dynclass.getDynField(this.getName());
462
            if( dynfield!=null && dynfield.isReadOnly() ) {
463
                return;
464
            }
465
        }
466
        container.setDynValue(this.getName(), value);
467
    }
468

    
469
    protected int getTagValueAsInt(String tagname, int defaultVaue) {
470
        return getTagValueAsInt(tagname, null, defaultVaue);
471
    }
472

    
473
    protected int getTagValueAsInt(String tagname1, String tagname2, int defaultVaue) {
474
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
475
        String tagname;
476
        if (fielddef.getTags().has(tagname1)) {
477
            tagname = tagname1;
478
        } else if (fielddef.getTags().has(tagname2)) {
479
            tagname = tagname2;
480
        } else {
481
            return defaultVaue;
482
        }
483
        try {
484
            int value = fielddef.getTags().getInt(tagname);
485
            return value;
486
        } catch (CoercionException ex) {
487
            LOGGER.warn("Can't parse tag '" + tagname + "' as int for field '" + fielddef.getName() + "'.", ex);
488
        }
489
        return defaultVaue;
490
    }
491

    
492
    protected boolean getTagValueAsBoolean(String tagname, boolean defaultVaue) {
493
        return getTagValueAsBoolean(tagname, null, defaultVaue);
494
    }
495

    
496
    protected boolean getTagValueAsBoolean(String tagname1, String tagname2, boolean defaultVaue) {
497
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
498
        String tagname;
499
        if (fielddef.getTags().has(tagname1)) {
500
            tagname = tagname1;
501
        } else if (fielddef.getTags().has(tagname2)) {
502
            tagname = tagname2;
503
        } else {
504
            return defaultVaue;
505
        }
506
        try {
507
            boolean value = fielddef.getTags().getBoolean(tagname);
508
            return value;
509
        } catch (CoercionException ex) {
510
            LOGGER.warn("Can't parse tag '" + tagname + "' as boolean for field '" + fielddef.getName() + "'.", ex);
511
        }
512
        return defaultVaue;
513
    }
514

    
515
    protected String getTagValueAsString(String tagname, String defaultVaue) {
516
        return getTagValueAsString(tagname, null, defaultVaue);
517
    }
518

    
519
    protected String getTagValueAsString(String tagname1, String tagname2, String defaultVaue) {
520
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
521
        String tagname;
522
        if (fielddef.getTags().has(tagname1)) {
523
            tagname = tagname1;
524
        } else if (fielddef.getTags().has(tagname2)) {
525
            tagname = tagname2;
526
        } else {
527
            return defaultVaue;
528
        }
529
        try {
530
            String value = (String) fielddef.getTags().get(tagname, DataTypes.STRING);
531
            return value;
532
        } catch (CoercionException ex) {
533
            LOGGER.warn("Can't parse tag '" + tagname + "' as string for field '" + fielddef.getName() + "'.", ex);
534
        }
535
        return defaultVaue;
536
    }
537

    
538
    @Override
539
    public double getResizeWeight() {
540
        Tags tags = this.getDefinition().getTags();
541
        int resizeWeight = tags.getInt(DynFormSPIManager.TAG_DYNFORM_RESIZEWEIGHT, 0);
542
        if( resizeWeight<1 ) {
543
            return 0;
544
        }
545
        if( resizeWeight>100 ) {
546
            return 1;
547
        }
548
        return resizeWeight / 100.0;
549
    }
550

    
551
    
552
}