Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.dynform / org.gvsig.tools.dynform.impl / src / main / java / org / gvsig / tools / dynform / impl / DefaultJDynForm.java @ 1881

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.impl;
24

    
25
import org.gvsig.tools.dynform.spi.dynform.AbstractJDynForm;
26
import java.util.ArrayList;
27
import java.util.HashMap;
28
import java.util.Iterator;
29
import java.util.List;
30
import java.util.Map;
31

    
32
import javax.swing.Action;
33
import javax.swing.JComponent;
34
import javax.swing.JTabbedPane;
35

    
36
import org.apache.commons.lang3.StringUtils;
37
import org.gvsig.tools.ToolsLocator;
38
import org.gvsig.tools.dataTypes.CoercionException;
39
import org.gvsig.tools.dataTypes.DataType;
40
import org.gvsig.tools.dataTypes.DataTypes;
41
import org.gvsig.tools.dynform.DynFormDefinition;
42
import org.gvsig.tools.dynform.DynFormFieldDefinition;
43
import org.gvsig.tools.dynform.JDynFormField;
44
import org.gvsig.tools.dynform.JDynFormField.JDynFormFieldListener;
45
import org.gvsig.tools.dynform.spi.dynformfield.SupportPopupMenu;
46
import org.gvsig.tools.dynobject.DynClass;
47
import org.gvsig.tools.dynobject.DynField;
48
import org.gvsig.tools.dynobject.DynField_v2;
49
import org.gvsig.tools.dynobject.DynObject;
50
import org.gvsig.tools.service.ServiceException;
51

    
52
import com.jgoodies.forms.builder.DefaultFormBuilder;
53
import com.jgoodies.forms.layout.FormLayout;
54
import com.jgoodies.forms.layout.RowSpec;
55
import java.util.Collection;
56
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
57
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
58
import org.gvsig.tools.dynform.spi.dynform.JDynFormFactory;
59
import org.gvsig.tools.dynform.spi.dynformfield.JDynFormFieldFactory;
60
import org.gvsig.tools.dynform.spi.dynformfield.AbstractJDynFormField;
61

    
62
@SuppressWarnings("UseSpecificCatch")
63
public class DefaultJDynForm extends AbstractJDynForm implements JDynFormFieldListener {
64

    
65
    private Map components = null;
66
    private ComponentsFactory componentsFactory;
67

    
68
    public DefaultJDynForm(
69
            DynFormSPIManager manager, 
70
            JDynFormFactory factory,
71
            DynFormDefinition definition,
72
            DynFormContext context
73
        ) {
74
        super(manager, factory, definition, context);
75
        this.components = new HashMap();
76
        this.componentsFactory = manager.createDefaultComponentsFactory();
77
    }
78

    
79
    @Override
80
    protected JComponent getFieldsContainer() {
81

    
82
        try {
83
            JComponent component;
84
            switch (this.getLayoutMode()) {
85
                case USE_PLAIN:
86
                case USE_TREE:
87
                default:
88
                    component = getFieldsContainerPlain();
89
                    break;
90
                case USE_TABS:
91
                    component = getFieldsContainerUseTabs();
92
                    break;
93
                case USE_SEPARATORS:
94
                    component = getFieldsContainerUseSeparators();
95
                    break;
96
            }
97
            return component;
98
        } catch (ServiceException ex) {
99
            throw new RuntimeException(ex);
100
        }
101
    }
102

    
103
    private JComponent getFieldsContainerPlain() throws ServiceException {
104
        FormLayout layout = new FormLayout(
105
                "left:pref,  8px,  fill:80dlu:grow", "pref");
106

    
107
        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
108
        builder.setDefaultRowSpec(new RowSpec(
109
                RowSpec.TOP,
110
                builder.getLayout().getRowSpec(1).getSize(),
111
                builder.getLayout().getRowSpec(1).getResizeWeight()));
112

    
113
        List fields = this.getDefinition().getDefinitions();
114
        Iterator it = fields.iterator();
115
        while (it.hasNext()) {
116
            DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
117
            if (fieldDefinition.isHidden()) {
118
                continue;
119
            }
120
            JDynFormFieldFactory factory = getServiceManager().getJDynFormFieldFactory(fieldDefinition);
121
            JDynFormField jfield = factory.create(
122
                    getServiceManager(), 
123
                    this.componentsFactory,
124
                    fieldDefinition, 
125
                    null
126
            );
127
            if (jfield instanceof AbstractJDynFormField) {
128
                ((AbstractJDynFormField) jfield).setForm(this);
129
            }
130
            if (this.isReadOnly()) {
131
                jfield.setReadOnly(true);
132
            } else {
133
                jfield.setReadOnly(fieldDefinition.isReadOnly());
134
            }
135
            jfield.addListener(this);
136
            builder.append(jfield.getJLabel(), jfield.asJComponent());
137

    
138
            this.components.put(jfield.getName(), jfield);
139
        }
140
        return builder.getPanel();
141
    }
142

    
143
    private JComponent getFieldsContainerUseSeparators() throws ServiceException {
144
        List<String> groups = this.getDefinition().getGroups();
145

    
146
        FormLayout layout = new FormLayout(
147
                "left:pref,  8px,  fill:80dlu:grow", "pref");
148

    
149
        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
150
        builder.setDefaultRowSpec(new RowSpec(
151
                RowSpec.TOP,
152
                builder.getLayout().getRowSpec(1).getSize(),
153
                builder.getLayout().getRowSpec(1).getResizeWeight()));
154

    
155
        for (String group : groups) {
156
            boolean firstfield = true;
157
            List fields = this.getDefinition().getDefinitions(group);
158
            Iterator it = fields.iterator();
159
            while (it.hasNext()) {
160
                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
161
                if (fieldDefinition.isHidden()) {
162
                    continue;
163
                }
164
                JDynFormFieldFactory factory = getServiceManager().getJDynFormFieldFactory(fieldDefinition);
165
                JDynFormField jfield = factory.create(
166
                        getServiceManager(), 
167
                        this.componentsFactory,
168
                        fieldDefinition, 
169
                        null
170
                );
171
                if (jfield instanceof AbstractJDynFormField) {
172
                    ((AbstractJDynFormField) jfield).setForm(this);
173
                }
174
                jfield.addListener(this);
175
                if (this.isReadOnly()) {
176
                    jfield.setReadOnly(this.isReadOnly());
177
                }
178

    
179
                List<Action> customActions = getCustomFields(fieldDefinition.getDataType());
180

    
181
                if (customActions != null && !customActions.isEmpty()) {
182
                    Iterator it2 = customActions.iterator();
183
                    while (it2.hasNext()) {
184
                        Object obj = it2.next();
185
                        if (obj != null) {
186
                            Action act = (Action) obj;
187
                            jfield.addActionToPopupMenu((String) act.getValue(Action.NAME), act);
188
                        } else {
189
                            jfield.addSeparatorToPopupMenu();
190
                        }
191
                    }
192
                }
193
                if( firstfield ) {
194
                    firstfield = false;
195
                    builder.appendSeparator(group);
196
                }
197
                builder.append(jfield.getJLabel(), jfield.asJComponent());
198

    
199
                this.components.put(jfield.getName(), jfield);
200
            }
201
        }
202
        return builder.getPanel();
203
    }
204

    
205
    private JComponent getFieldsContainerUseTabs() throws ServiceException {
206

    
207
        JTabbedPane tabbedPane = new JTabbedPane();
208
        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
209
        if (this.getDefinition().getTags().has("TabPlacement")) {
210
            try {
211
                tabbedPane.setTabPlacement(this.getDefinition().getTags().getInt("TabPlacement"));
212
            } catch (Exception e) {
213
                // Ignorada
214
            }
215
        }
216
        List<String> groups = this.getDefinition().getGroups();
217

    
218
        for (String group : groups) {
219
            FormLayout layout = new FormLayout(
220
                    "left:pref,  8px,  fill:80dlu:grow", "pref");
221
            DefaultFormBuilder builder = new DefaultFormBuilder(layout);
222
            builder.defaultRowSpec(new RowSpec(
223
                    RowSpec.TOP,
224
                    builder.getLayout().getRowSpec(1).getSize(),
225
                    builder.getLayout().getRowSpec(1).getResizeWeight()));
226
            List fields = this.getDefinition().getDefinitions(group);
227
            boolean hasFields = false;
228
            Iterator it = fields.iterator();
229
            while (it.hasNext()) {
230
                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
231
                if (fieldDefinition.isHidden()) {
232
                    continue;
233
                }
234
                JDynFormFieldFactory factory = getServiceManager().getJDynFormFieldFactory(fieldDefinition);
235
                JDynFormField jfield = factory.create(
236
                        getServiceManager(), 
237
                        this.componentsFactory,
238
                        fieldDefinition, 
239
                        null
240
                );
241
                if (jfield instanceof AbstractJDynFormField) {
242
                    ((AbstractJDynFormField) jfield).setForm(this);
243
                }
244
                jfield.setReadOnly(this.isReadOnly());
245
                jfield.addListener(this);
246
                if (this.isReadOnly()) {
247
                    jfield.setReadOnly(this.isReadOnly());
248
                }
249
                hasFields = true;
250
                builder.append(jfield.getJLabel(), jfield.asJComponent());
251

    
252
                this.components.put(jfield.getName(), jfield);
253
            }
254
            if( hasFields ) {
255
                String tablabel = group;
256
                if (StringUtils.isEmpty(tablabel)) {
257
                    tablabel = ToolsLocator.getI18nManager().getTranslation("General");
258
                }
259
                tabbedPane.addTab(tablabel, builder.getPanel());
260
            }
261
        }
262

    
263
        try {
264
            String defaultGroupName = (String) this.getDefinition().getTags().get("defaultGroup", DataTypes.STRING);
265
            List<String> groupsNames = this.getDefinition().getGroups();
266
            int groupIndex = groupsNames.indexOf(defaultGroupName);
267
            if (groupIndex >= 0) {
268
                tabbedPane.setSelectedIndex(groupIndex);
269
            }
270
        } catch (Exception ex) {
271
            // Ignore errors and don't set a tab by default
272
        }
273

    
274
        return tabbedPane;
275
    }
276

    
277
    @Override
278
    public void setReadOnly(boolean readOnly) {
279
        if( this.isReadOnly() == readOnly ) {
280
            return;
281
        }
282
        super.setReadOnly(readOnly);
283
        if (this.isContentsInitialized()) {
284
            Iterator it = this.getFieldsIterator();
285
            while (it.hasNext()) {
286
                JDynFormField field = (JDynFormField) it.next();
287
                if( readOnly ) {
288
                    field.setReadOnly(true);
289
                } else if( field.getDefinition().isReadOnly() ) {
290
                    field.setReadOnly(true);
291
                } else {
292
                    field.setReadOnly(false);
293
                }
294
            }
295
        }
296
    }
297

    
298
    @Override
299
    public void setValues(DynObject values) {
300
        /*
301
         * TODO: Probablemente fuese mas acertado recorrer los controles de
302
         * components y a partir de ellos acceder a los valores del DynObject
303
         * recibido. Eso permitiria trabajar mejor con herencia de DynObject.
304
         * Habria que hacer lo mismo con el getValues.
305
         */
306
        if (!this.isContentsInitialized()) {
307
            this.values = values;
308
            return;
309
        }
310
        DynClass def = values.getDynClass();
311
        DynField[] fields = def.getDynFields();
312
        for (int i = 0; i < fields.length; i++) {
313
            String name = fields[i].getName();
314
            if (name == null || name.isEmpty()) {
315
                LOGGER.warn("Field name " + i + " of '" + def.getFullName() + "' is null or empty ");
316
                continue;
317
            }
318
            JDynFormField jfield = (JDynFormField) this.getField(name);
319
            if (jfield == null) {
320
                LOGGER.warn("Can't retrieve form field asociated to the field '" + name + "' of class '" + def.getFullName() + "'.");
321
                continue;
322
            }
323
            if (values.getDynValue(name) == null) {
324
                if (fields[i].getDataType().getType() == DataTypes.LIST) {
325
                    try {
326
                        if (((DynField_v2) fields[i]).getDynClassOfItems() != null) {
327
                            values.setDynValue(name, new ArrayList<>());
328
                        }
329
                    } catch (Exception e) {
330
                        LOGGER.warn("Problems initializing the DynObject List", e);
331
                    }
332
                }
333
            }
334
            jfield.setValue(values.getDynValue(name));
335
        }
336
    }
337

    
338
    @Override
339
    public void getValues(DynObject values) {
340
        if (values == null) {
341
            return;
342
        }
343
        DynField[] fields = values.getDynClass().getDynFields();
344
        for (DynField field : fields) {
345
            String name = field.getName();
346
            JDynFormField jfield = (JDynFormField) this.getField(name);
347
            if (jfield != null && !jfield.isReadOnly()) {
348
                try {
349
                    jfield.fetch(values);
350
                } catch (Exception ex) {
351
                    LOGGER.warn("Can't get value of field '" + name + "'.", ex);
352
                }
353
            }
354
        }
355
    }
356

    
357
    @Override
358
    public boolean hasValidValues() {
359
        Iterator it = this.getFieldsIterator();
360
        while (it.hasNext()) {
361
            JDynFormField jfield = (JDynFormField) it.next();
362
            if (!jfield.hasValidValue()) {
363
                return false;
364
            }
365
        }
366
        return true;
367
    }
368

    
369
    @Override
370
    public boolean hasValidValues(List<String> fieldsName) {
371
        if (fieldsName == null) {
372
            fieldsName = new ArrayList<>();
373
        }
374
        Iterator it = this.getFieldsIterator();
375
        while (it.hasNext()) {
376
            JDynFormField jfield = (JDynFormField) it.next();
377
            if (!jfield.hasValidValue()) {
378
                fieldsName.add(jfield.getName());
379
            }
380
        }
381
        return fieldsName.isEmpty();
382
    }
383

    
384
    @Override
385
    public Object getValue(String fieldName) {
386
        JDynFormField field = (JDynFormField) this.getField(fieldName);
387
        return field.getValue();
388
    }
389

    
390
    @Override
391
    public void setValue(String fieldName, Object value) {
392
        JDynFormField field = (JDynFormField) this.getField(fieldName);
393
        try {
394
            value = field.getDefinition().getDataType().coerce(value);
395
        } catch (CoercionException e) {
396
            String msg = "Invalid value '" + ((value == null) ? "(null)" : value.toString()) + "' for field '" + fieldName + "'.";
397
            LOGGER.warn(msg, e);
398
            throw new RuntimeException(msg, e);
399
        }
400
        field.setValue(value);
401
    }
402

    
403
    @Override
404
    public boolean isModified() {
405
        Iterator it = this.getFieldsIterator();
406
        while (it.hasNext()) {
407
            JDynFormField jfield = (JDynFormField) it.next();
408
            if (jfield.isModified()) {
409
                return true;
410
            }
411
        }
412
        return false;
413
    }
414

    
415
    @Override
416
    public void fieldEnter(JDynFormField field) {
417
        message(field.getDefinition().getDescription());
418
    }
419

    
420
    @Override
421
    public void fieldExit(JDynFormField field) {
422
        message();
423
    }
424

    
425
    @Override
426
    public void message(JDynFormField field, String message) {
427
        message(message);
428
    }
429

    
430
    @Override
431
    public void fieldChanged(JDynFormField field) {
432
        fireFieldChangeEvent(field);
433
    }
434

    
435
    @Override
436
    public JDynFormField getField(String fieldName) {
437
        JDynFormField field = (JDynFormField) this.components.get(fieldName);
438
        return field;
439
    }
440

    
441
    public Iterator getFieldsIterator() {
442
        if (!this.isContentsInitialized()) {
443
            this.initComponents();
444
        }
445
        return this.components.values().iterator();
446
    }
447

    
448
    public Collection getShowFields() {
449
        return this.components.values();
450
    }
451

    
452
    @Override
453
    public void clear() {
454
        Iterator it = this.components.entrySet().iterator();
455
        while (it.hasNext()) {
456
            Map.Entry entry = (Map.Entry) it.next();
457
            ((JDynFormField) (entry.getValue())).clear();
458
        }
459
    }
460

    
461
    @Override
462
    public void addActionToPopupMenu(DataType tipo, String name, Action action) {
463
        super.addActionToPopupMenu(tipo, name, action);
464
        if ( this.isContentsInitialized() ) {
465
            Iterator it = this.components.keySet().iterator();
466
            while (it.hasNext()) {
467
                String key = (String) it.next();
468
                Object obj = this.components.get(key);
469
                if (obj instanceof JDynFormField) {
470
                    JDynFormField field = (JDynFormField) obj;
471
                    if (tipo == field.getDefinition().getDataType()) {
472
                        if (field.asJComponent() instanceof SupportPopupMenu) {
473
                            field.addActionToPopupMenu(name, action);
474
                        }
475
                    }
476
                }
477
            }
478
        }
479
    }
480

    
481
    @Override
482
    public void addSeparatorToPopupMenu(DataType tipo) {
483
        super.addSeparatorToPopupMenu(tipo);
484
        if ( this.isContentsInitialized() ) {
485
            Iterator it = this.components.keySet().iterator();
486
            while (it.hasNext()) {
487
                String key = (String) it.next();
488
                Object obj = this.components.get(key);
489
                if (obj instanceof JDynFormField) {
490
                    JDynFormField field = (JDynFormField) obj;
491
                    if (tipo == field.getDefinition().getDataType()) {
492
                        if (field.asJComponent() instanceof SupportPopupMenu) {
493
                            ((SupportPopupMenu) field.asJComponent()).addSeparatorToPopupMenu();
494
                        }
495
                    }
496
                }
497
            }
498
        }
499
    }
500

    
501
    @Override
502
    public void setBorder(boolean border) {
503
        super.setBorder(border && this.getShowFields().size() >1);
504
    }
505

    
506
}