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

History | View | Annotate | Download (18.5 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 String getSeparatorTitleToUseBefore() {
165
        String separatorTitle = this.getTagValueAsString(
166
                DynFormSPIManager.TAG_DYNFORM_SEPARATOR, 
167
                null
168
        );
169
        return separatorTitle;
170
    }
171
    
172
    @Override
173
    public boolean useEmptyLabel() {
174
        boolean useEmpty = getTagValueAsBoolean(
175
                DynFormSPIManager.TAG_DYNFORM_LABEL_EMPTY, 
176
                false
177
        );
178
        return useEmpty;
179
    }
180
    
181
    @Override
182
    public JComponent getJLabel() {
183
        if (this.jlabel == null) {
184
            this.jlabel = this.getComponentsFactory().getJLabel(definition, null);
185
            if( this.jlabel==null ) {
186
                this.jlabel = new JLabel();
187
            }
188
            if (!this.useEmptyLabel() ) {
189
                this.jlabel.setText(this.getLabel());
190
            }
191
            this.jlabel.setLabelFor(this.contents);
192
            if (this.getDefinition().isMandatory()) {
193
                this.jlabel.setForeground(Color.red.darker());
194
            }
195
            this.jlabelpanel = new JPanel();
196
            this.jlabelpanel.setLayout(new BorderLayout());
197
            this.jlabelpanel.add(jlabel, BorderLayout.CENTER);
198
            this.jlabelpanel.add(problemIndicator.asJComponent(), BorderLayout.LINE_END);
199
        }
200
        return this.jlabelpanel;
201
    }
202

    
203
    @Override
204
    public DynFormFieldDefinition getDefinition() {
205
        return this.definition;
206
    }
207
    
208
    public DynFormSPIManager getServiceManager() {
209
        return this.manager;
210
    }
211

    
212
    @Override
213
    public void addListener(JDynFormFieldListener listener) {
214
        this.listeners.add(listener);
215
    }
216

    
217
    @Override
218
    public void removeListener(JDynFormFieldListener listener) {
219
        this.listeners.remove(listener);
220
    }
221

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

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

    
255
    protected void fireFieldExitEvent() {
256
        Iterator it = this.listeners.iterator();
257
        while (it.hasNext()) {
258
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
259
            try {
260
                listener.fieldExit(this);
261
            } catch (Exception ex) {
262
                LOGGER.info("Error calling listener " + listener.toString()
263
                        + "(" + listener.getClass().getName() + ") from "
264
                        + this.toString() + "(" + this.getClass().getName()
265
                        + ").", ex);
266
            }
267
        }
268
    }
269

    
270
    @Override
271
    public void fireMessageEvent(String message) {
272
        Iterator it = this.listeners.iterator();
273
        while (it.hasNext()) {
274
            JDynFormFieldListener listener = (JDynFormFieldListener) it.next();
275
            try {
276
                listener.message(this, message);
277
            } catch (Exception ex) {
278
                LOGGER.info("Error calling listener " + listener.toString()
279
                        + "(" + listener.getClass().getName() + ") from "
280
                        + this.toString() + "(" + this.getClass().getName()
281
                        + ").", ex);
282
            }
283
        }
284
    }
285

    
286
    @Override
287
    public boolean isReadOnly() {
288
        return this.readOnly;
289
    }
290
    
291
    protected boolean isForcedReadOnly() {
292
        return this.getTagValueAsBoolean(DynFormSPIManager.TAG_DYNFORM_READONLY, false);
293
    }
294

    
295
    @Override
296
    public void setReadOnly(boolean readonly) {
297
        // FIXME: Implememtacion por defecto, sobreescribirla en las subclases
298
        // segun convenga para cada componente.
299
        if( !readonly && this.isForcedReadOnly() ) {
300
            readonly = true;
301
        }
302
        this.readOnly = readonly;
303
        if (jlabel != null) {
304
            this.jlabel.setEnabled(!readonly);
305
        }
306
        if (this.contents != null) {
307
            if (this.contents instanceof JTextComponent) {
308
                JTextComponent x = (JTextComponent) this.contents;
309
                x.setEditable(!readonly);
310

    
311
            } else if (this.contents instanceof JComboBox ) {
312
                JComboBox x = (JComboBox) this.contents;
313
                x.setEnabled(!readonly);
314
                
315
            } else if (this.contents instanceof JScrollPane) {
316
                try {
317
                    JViewport port = ((JScrollPane) this.contents).getViewport();
318
                    JTextComponent x = (JTextComponent) port.getView();
319
                    x.setEditable(!readonly);
320
                } catch (Exception ex) {
321
                    this.contents.setEnabled(!readOnly);
322
                }
323
            } else {
324
                this.contents.setEnabled(!readOnly);
325
            }
326
        }
327
    }
328

    
329
    public JProblemIndicator problemIndicator() {
330
        return this.problemIndicator;
331
    }
332

    
333
    public class IllegalFieldValue extends RuntimeException {
334

    
335
        /**
336
         *
337
         */
338
        private static final long serialVersionUID = -4409236610055983438L;
339

    
340
        public IllegalFieldValue(JDynFormField field, String message) {
341
            super("The value of field '" + field.getLabel() + "' is not valid. " + message);
342
        }
343
    }
344

    
345
    @Override
346
    public String toString() {
347
        return super.toString() + "{" + this.getName() + "}";
348
    }
349

    
350
    @Override
351
    public boolean isModified() {
352
        boolean modified = false;
353
        try {
354
            if (!this.isReadOnly()) {
355
                Object value = this.getValue();
356
                if (value == null) {
357
                    if (value != this.getAssignedValue()) {
358
                        modified = true;
359
                    }
360
                } else {
361
                    if (!value.equals(this.getAssignedValue())) {
362
                        modified = true;
363
                    }
364
                }
365
            }
366
        } catch (IllegalFieldValue ex) {
367
            // Si es incorrecto el valor del campo decimos a capom que esta modificado.
368
            modified = true;
369
        }
370
        return modified;
371
    }
372

    
373
    private void addPopupComponents() {
374
        Iterator it = this.customActions.iterator();
375
        while (it.hasNext()) {
376
            Object obj = it.next();
377
            if (obj != null) {
378
                Action act = (Action) obj;
379
                if (contents instanceof SupportPopupMenu) {
380
                    DynFormFieldAction sact = new DynFormFieldAction(this, act);
381
                    ((SupportPopupMenu) this.contents).addActionToPopupMenu(
382
                            sact.getName(),
383
                            sact);
384
                }
385
            } else {
386
                if (contents instanceof SupportPopupMenu) {
387
                    ((SupportPopupMenu) this.contents).addSeparatorToPopupMenu();
388
                }
389
            }
390

    
391
        }
392
    }
393

    
394
    @Override
395
    public void addActionToPopupMenu(String name, Action action) {
396
        if (contents != null) {
397
            if (contents instanceof SupportPopupMenu) {
398
                DynFormFieldAction sact = new DynFormFieldAction(this, action);
399
                ((SupportPopupMenu) this.contents).addActionToPopupMenu(
400
                        sact.getName(),
401
                        sact);
402
            }
403
        } else {
404
            this.customActions.add(action);
405
        }
406
    }
407

    
408
    @Override
409
    public void addSeparatorToPopupMenu() {
410
        if (contents != null) {
411
            if (contents instanceof SupportPopupMenu) {
412
                ((SupportPopupMenu) this.contents).addSeparatorToPopupMenu();
413
            }
414
        } else {
415
            this.customActions.add(null);
416
        }
417
    }
418

    
419
    public void setTranslateEmptyToNull(boolean emptyToNull) {
420
        this.emptyToNull = emptyToNull;
421
    }
422

    
423
    public boolean translateEmptyToNull() {
424
        return this.emptyToNull;
425
    }
426

    
427
    @SuppressWarnings("UnnecessaryReturnStatement")
428
    @Override
429
    public void clear() {
430
        if (this.contents == null) {
431
            return;
432
        }
433
        if (this.contents instanceof JTextField) {
434
            Object value = this.getDefinition().getDefaultValue();
435
            if (value != null) {
436
                value = value.toString();
437
            } else {
438
                value = "";
439
            }
440
            ((JTextField) this.contents).setText((String) value);
441
            return;
442
        }
443
        if (this.contents instanceof JSpinner) {
444
            Object value = this.getDefinition().getDefaultValue();
445
            if (value==null) {
446
                ((JSpinner) this.contents).setValue(0);
447
                return;
448
            }
449
            ((JSpinner) this.contents).setValue(value);
450
            return;
451
        }
452
        if (this.contents instanceof JList) {
453
            ((JList) this.contents).setSelectedIndex(-1);
454
            return;
455
        }
456
        if (this.contents instanceof JComboBox) {
457
            ((JComboBox) this.contents).setSelectedIndex(-1);
458
            return;
459
        }
460
    }
461

    
462
    public void setForm(JDynForm form) {
463
        this.form = form;
464
    }
465

    
466
    @Override
467
    public JDynForm getForm() {
468
        return this.form;
469
    }
470

    
471
    @Override
472
    public void fetch(DynObject container) {
473
        if( this.isReadOnly() ) {
474
            return;
475
        }
476
        Object value = this.getValue();
477
        DynClass dynclass = container.getDynClass();
478
        if( dynclass!=null ) {
479
            DynField dynfield = dynclass.getDynField(this.getName());
480
            if( dynfield!=null && dynfield.isReadOnly() ) {
481
                return;
482
            }
483
        }
484
        container.setDynValue(this.getName(), value);
485
    }
486

    
487
    protected int getTagValueAsInt(String tagname, int defaultVaue) {
488
        return getTagValueAsInt(tagname, null, defaultVaue);
489
    }
490

    
491
    protected int getTagValueAsInt(String tagname1, String tagname2, int defaultVaue) {
492
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
493
        String tagname;
494
        if (fielddef.getTags().has(tagname1)) {
495
            tagname = tagname1;
496
        } else if (fielddef.getTags().has(tagname2)) {
497
            tagname = tagname2;
498
        } else {
499
            return defaultVaue;
500
        }
501
        try {
502
            int value = fielddef.getTags().getInt(tagname);
503
            return value;
504
        } catch (CoercionException ex) {
505
            LOGGER.warn("Can't parse tag '" + tagname + "' as int for field '" + fielddef.getName() + "'.", ex);
506
        }
507
        return defaultVaue;
508
    }
509

    
510
    protected boolean getTagValueAsBoolean(String tagname, boolean defaultVaue) {
511
        return getTagValueAsBoolean(tagname, null, defaultVaue);
512
    }
513

    
514
    protected boolean getTagValueAsBoolean(String tagname1, String tagname2, boolean defaultVaue) {
515
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
516
        String tagname;
517
        if (fielddef.getTags().has(tagname1)) {
518
            tagname = tagname1;
519
        } else if (fielddef.getTags().has(tagname2)) {
520
            tagname = tagname2;
521
        } else {
522
            return defaultVaue;
523
        }
524
        try {
525
            boolean value = fielddef.getTags().getBoolean(tagname);
526
            return value;
527
        } catch (CoercionException ex) {
528
            LOGGER.warn("Can't parse tag '" + tagname + "' as boolean for field '" + fielddef.getName() + "'.", ex);
529
        }
530
        return defaultVaue;
531
    }
532

    
533
    protected String getTagValueAsString(String tagname, String defaultVaue) {
534
        return getTagValueAsString(tagname, null, defaultVaue);
535
    }
536

    
537
    protected String getTagValueAsString(String tagname1, String tagname2, String defaultVaue) {
538
        DynField_v2 fielddef = (DynField_v2) this.getDefinition();
539
        String tagname;
540
        if (fielddef.getTags().has(tagname1)) {
541
            tagname = tagname1;
542
        } else if (fielddef.getTags().has(tagname2)) {
543
            tagname = tagname2;
544
        } else {
545
            return defaultVaue;
546
        }
547
        try {
548
            String value = (String) fielddef.getTags().get(tagname, DataTypes.STRING);
549
            return value;
550
        } catch (CoercionException ex) {
551
            LOGGER.warn("Can't parse tag '" + tagname + "' as string for field '" + fielddef.getName() + "'.", ex);
552
        }
553
        return defaultVaue;
554
    }
555

    
556
    @Override
557
    public double getResizeWeight() {
558
        Tags tags = this.getDefinition().getTags();
559
        int resizeWeight = tags.getInt(DynFormSPIManager.TAG_DYNFORM_RESIZEWEIGHT, 0);
560
        if( resizeWeight<1 ) {
561
            return 0;
562
        }
563
        if( resizeWeight>100 ) {
564
            return 1;
565
        }
566
        return resizeWeight / 100.0;
567
    }
568

    
569
    
570
}