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

History | View | Annotate | Download (17.3 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.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.dynformfield.AbstractJDynFormField;
57

    
58
@SuppressWarnings({"unchecked", "rawtypes"})
59
public class DefaultJDynForm extends AbstractJDynForm implements JDynFormFieldListener {
60

    
61
    private Map components = null;
62

    
63
    public DefaultJDynForm(
64
            DefaultDynFormManager manager, 
65
            DynFormDefinition definition,
66
            DynFormContext context
67
        ) throws ServiceException {
68
        super(manager,definition, context);
69
        this.components = new HashMap();
70
    }
71

    
72
    @Override
73
    protected JComponent getFieldsContainer() {
74

    
75
        try {
76
            JComponent component;
77
            switch (this.getLayoutMode()) {
78
                case USE_PLAIN:
79
                case USE_TREE:
80
                default:
81
                    component = getFieldsContainerPlain();
82
                    break;
83
                case USE_TABS:
84
                    component = getFieldsContainerUseTabs();
85
                    break;
86
                case USE_SEPARATORS:
87
                    component = getFieldsContainerUseSeparators();
88
                    break;
89
            }
90
            return component;
91
        } catch (ServiceException ex) {
92
            throw new RuntimeException(ex);
93
        }
94
    }
95

    
96
    private JComponent getFieldsContainerPlain() throws ServiceException {
97
        FormLayout layout = new FormLayout(
98
                "left:pref,  8px,  fill:80dlu:grow", "pref");
99

    
100
        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
101
        builder.setDefaultRowSpec(new RowSpec(
102
                RowSpec.TOP,
103
                builder.getLayout().getRowSpec(1).getSize(),
104
                builder.getLayout().getRowSpec(1).getResizeWeight()));
105

    
106
        List fields = this.getDefinition().getDefinitions();
107
        Iterator it = fields.iterator();
108
        while (it.hasNext()) {
109
            DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
110
            if (fieldDefinition.isHidden()) {
111
                continue;
112
            }
113
            JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
114
            if (jfield instanceof AbstractJDynFormField) {
115
                ((AbstractJDynFormField) jfield).setForm(this);
116
            }
117
            jfield.setReadOnly(fieldDefinition.isReadOnly());
118
            jfield.addListener(this);
119
            if (this.isReadOnly()) {
120
                jfield.setReadOnly(this.isReadOnly());
121
            }
122
            builder.append(jfield.getJLabel(), jfield.asJComponent());
123

    
124
            this.components.put(jfield.getName(), jfield);
125
        }
126
        return builder.getPanel();
127
    }
128

    
129
    private JComponent getFieldsContainerUseSeparators() throws ServiceException {
130
        List<String> groups = this.getDefinition().getGroups();
131

    
132
        FormLayout layout = new FormLayout(
133
                "left:pref,  8px,  fill:80dlu:grow", "pref");
134

    
135
        DefaultFormBuilder builder = new DefaultFormBuilder(layout);
136
        builder.setDefaultRowSpec(new RowSpec(
137
                RowSpec.TOP,
138
                builder.getLayout().getRowSpec(1).getSize(),
139
                builder.getLayout().getRowSpec(1).getResizeWeight()));
140

    
141
        for (String group : groups) {
142
            boolean firstfield = true;
143
            List fields = this.getDefinition().getDefinitions(group);
144
            Iterator it = fields.iterator();
145
            while (it.hasNext()) {
146
                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
147
                if (fieldDefinition.isHidden()) {
148
                    continue;
149
                }
150
                JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
151
                if (jfield instanceof AbstractJDynFormField) {
152
                    ((AbstractJDynFormField) jfield).setForm(this);
153
                }
154
                jfield.addListener(this);
155
                if (this.isReadOnly()) {
156
                    jfield.setReadOnly(this.isReadOnly());
157
                }
158

    
159
                List<Action> customActions = getCustomFields(fieldDefinition.getDataType());
160

    
161
                if (customActions != null && !customActions.isEmpty()) {
162
                    Iterator it2 = customActions.iterator();
163
                    while (it2.hasNext()) {
164
                        Object obj = it2.next();
165
                        if (obj != null) {
166
                            Action act = (Action) obj;
167
                            jfield.addActionToPopupMenu((String) act.getValue(Action.NAME), act);
168
                        } else {
169
                            jfield.addSeparatorToPopupMenu();
170
                        }
171
                    }
172
                }
173
                if( firstfield ) {
174
                    firstfield = false;
175
                    builder.appendSeparator(group);
176
                }
177
                builder.append(jfield.getJLabel(), jfield.asJComponent());
178

    
179
                this.components.put(jfield.getName(), jfield);
180
            }
181
        }
182
        return builder.getPanel();
183
    }
184

    
185
    private JComponent getFieldsContainerUseTabs() throws ServiceException {
186

    
187
        JTabbedPane tabbedPane = new JTabbedPane();
188
        if (this.getDefinition().getTags().has("TabPlacement")) {
189
            try {
190
                tabbedPane.setTabPlacement(this.getDefinition().getTags().getInt("TabPlacement"));
191
            } catch (Exception e) {
192
                // Ignorada
193
            }
194
        }
195
        List<String> groups = this.getDefinition().getGroups();
196

    
197
        for (String group : groups) {
198
            FormLayout layout = new FormLayout(
199
                    "left:pref,  8px,  fill:80dlu:grow", "pref");
200
            DefaultFormBuilder builder = new DefaultFormBuilder(layout);
201
            builder.defaultRowSpec(new RowSpec(
202
                    RowSpec.TOP,
203
                    builder.getLayout().getRowSpec(1).getSize(),
204
                    builder.getLayout().getRowSpec(1).getResizeWeight()));
205
            List fields = this.getDefinition().getDefinitions(group);
206
            boolean hasFields = false;
207
            Iterator it = fields.iterator();
208
            while (it.hasNext()) {
209
                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
210
                if (fieldDefinition.isHidden()) {
211
                    continue;
212
                }
213
                JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
214
                if (jfield instanceof AbstractJDynFormField) {
215
                    ((AbstractJDynFormField) jfield).setForm(this);
216
                }
217
                jfield.setReadOnly(this.isReadOnly());
218
                jfield.addListener(this);
219
                if (this.isReadOnly()) {
220
                    jfield.setReadOnly(this.isReadOnly());
221
                }
222
                hasFields = true;
223
                builder.append(jfield.getJLabel(), jfield.asJComponent());
224

    
225
                this.components.put(jfield.getName(), jfield);
226
            }
227
            if( hasFields ) {
228
                String tablabel = group;
229
                if (StringUtils.isEmpty(tablabel)) {
230
                    tablabel = ToolsLocator.getI18nManager().getTranslation("General");
231
                }
232
                tabbedPane.addTab(tablabel, builder.getPanel());
233
            }
234
        }
235

    
236
        try {
237
            String defaultGroupName = (String) this.getDefinition().getTags().get("defaultGroup", DataTypes.STRING);
238
            List<String> groupsNames = this.getDefinition().getGroups();
239
            int groupIndex = groupsNames.indexOf(defaultGroupName);
240
            if (groupIndex >= 0) {
241
                tabbedPane.setSelectedIndex(groupIndex);
242
            }
243
        } catch (Exception ex) {
244
            // Ignore errors and don't set a tab by default
245
        }
246

    
247
        return tabbedPane;
248
    }
249

    
250
    @Override
251
    public void setReadOnly(boolean readOnly) {
252
        super.setReadOnly(readOnly);
253
        if (this.isContentsInitialized()) {
254
            Iterator it = this.getFieldsIterator();
255
            while (it.hasNext()) {
256
                JDynFormField field = (JDynFormField) it.next();
257
                if( readOnly ) {
258
                    field.setReadOnly(true);
259
                } else if( field.getDefinition().isReadOnly() ) {
260
                    field.setReadOnly(true);
261
                } else {
262
                    field.setReadOnly(false);
263
                }
264
            }
265
        }
266
    }
267

    
268
    @Override
269
    public void setValues(DynObject values) {
270
        /*
271
         * TODO: Probablemente fuese mas acertado recorrer los controles de
272
         * components y a partir de ellos acceder a los valores del DynObject
273
         * recibido. Eso permitiria trabajar mejor con herencia de DynObject.
274
         * Habria que hacer lo mismo con el getValues.
275
         */
276
        if (!this.isContentsInitialized()) {
277
            this.values = values;
278
            return;
279
        }
280
        DynClass def = values.getDynClass();
281
        DynField[] fields = def.getDynFields();
282
        for (int i = 0; i < fields.length; i++) {
283
            String name = fields[i].getName();
284
            if (name == null || name.isEmpty()) {
285
                logger.warn("Field name " + i + " of '" + def.getFullName() + "' is null or empty ");
286
                continue;
287
            }
288
            JDynFormField jfield = (JDynFormField) this.getField(name);
289
            if (jfield == null) {
290
                logger.warn("Can't retrieve form field asociated to the field '" + name + "' of class '" + def.getFullName() + "'.");
291
                continue;
292
            }
293
            if (values.getDynValue(name) == null) {
294
                if (fields[i].getDataType().getType() == DataTypes.LIST) {
295
                    try {
296
                        if (((DynField_v2) fields[i]).getDynClassOfItems() != null) {
297
                            values.setDynValue(name, new ArrayList<DynObject>());
298
                        }
299
                    } catch (Exception e) {
300
                        logger.warn("Problems initializing the DynObject List", e);
301
                    }
302
                }
303
            }
304
            jfield.setValue(values.getDynValue(name));
305
        }
306
    }
307

    
308
    @Override
309
    public void getValues(DynObject values) {
310
        if (values == null) {
311
            return;
312
        }
313
        DynField[] fields = values.getDynClass().getDynFields();
314
        for (DynField field : fields) {
315
            String name = field.getName();
316
            JDynFormField jfield = (JDynFormField) this.getField(name);
317
            if (jfield != null && !jfield.isReadOnly()) {
318
                try {
319
                    jfield.fetch(values);
320
                } catch (Exception ex) {
321
                    logger.warn("Can't get value of field '" + name + "'.", ex);
322
                }
323
            }
324
        }
325
    }
326

    
327
    @Override
328
    public boolean hasValidValues() {
329
        Iterator it = this.getFieldsIterator();
330
        while (it.hasNext()) {
331
            JDynFormField jfield = (JDynFormField) it.next();
332
            if (!jfield.hasValidValue()) {
333
                return false;
334
            }
335
        }
336
        return true;
337
    }
338

    
339
    @Override
340
    public boolean hasValidValues(List<String> fieldsName) {
341
        if (fieldsName == null) {
342
            fieldsName = new ArrayList<>();
343
        }
344
        Iterator it = this.getFieldsIterator();
345
        while (it.hasNext()) {
346
            JDynFormField jfield = (JDynFormField) it.next();
347
            if (!jfield.hasValidValue()) {
348
                fieldsName.add(jfield.getName());
349
            }
350
        }
351
        return fieldsName.isEmpty();
352
    }
353

    
354
    @Override
355
    public Object getValue(String fieldName) {
356
        JDynFormField field = (JDynFormField) this.getField(fieldName);
357
        return field.getValue();
358
    }
359

    
360
    @Override
361
    public void setValue(String fieldName, Object value) {
362
        JDynFormField field = (JDynFormField) this.getField(fieldName);
363
        try {
364
            value = field.getDefinition().getDataType().coerce(value);
365
        } catch (CoercionException e) {
366
            String msg = "Invalid value '" + ((value == null) ? "(null)" : value.toString()) + "' for field '" + fieldName + "'.";
367
            logger.warn(msg, e);
368
            throw new RuntimeException(msg, e);
369
        }
370
        field.setValue(value);
371
    }
372

    
373
    @Override
374
    public boolean isModified() {
375
        Iterator it = this.getFieldsIterator();
376
        while (it.hasNext()) {
377
            JDynFormField jfield = (JDynFormField) it.next();
378
            if (jfield.isModified()) {
379
                return true;
380
            }
381
        }
382
        return false;
383
    }
384

    
385
    @Override
386
    public void fieldEnter(JDynFormField field) {
387
        message(field.getDefinition().getDescription());
388
    }
389

    
390
    @Override
391
    public void fieldExit(JDynFormField field) {
392
        message();
393
    }
394

    
395
    @Override
396
    public void message(JDynFormField field, String message) {
397
        message(message);
398
    }
399

    
400
    @Override
401
    public void fieldChanged(JDynFormField field) {
402
        fireFieldChangeEvent(field);
403
    }
404

    
405
    public JDynFormField getField(String fieldName) {
406
        JDynFormField field = (JDynFormField) this.components.get(fieldName);
407
        return field;
408
    }
409

    
410
    public Iterator getFieldsIterator() {
411
        if (!this.isContentsInitialized()) {
412
            this.initComponents();
413
        }
414
        return this.components.values().iterator();
415
    }
416

    
417
    public Collection getShowFields() {
418
        return this.components.values();
419
    }
420

    
421
    @Override
422
    public void clear() {
423
        Iterator it = this.components.entrySet().iterator();
424
        while (it.hasNext()) {
425
            Map.Entry entry = (Map.Entry) it.next();
426
            ((JDynFormField) (entry.getValue())).clear();
427
        }
428
    }
429

    
430
    @Override
431
    public void addActionToPopupMenu(DataType tipo, String name, Action action) {
432
        super.addActionToPopupMenu(tipo, name, action);
433
        if ( this.isContentsInitialized() ) {
434
            Iterator it = this.components.keySet().iterator();
435
            while (it.hasNext()) {
436
                String key = (String) it.next();
437
                Object obj = this.components.get(key);
438
                if (obj instanceof JDynFormField) {
439
                    JDynFormField field = (JDynFormField) obj;
440
                    if (tipo == field.getDefinition().getDataType()) {
441
                        if (field.asJComponent() instanceof SupportPopupMenu) {
442
                            field.addActionToPopupMenu(name, action);
443
                        }
444
                    }
445
                }
446
            }
447
        }
448
    }
449

    
450
    @Override
451
    public void addSeparatorToPopupMenu(DataType tipo) {
452
        super.addSeparatorToPopupMenu(tipo);
453
        if ( this.isContentsInitialized() ) {
454
            Iterator it = this.components.keySet().iterator();
455
            while (it.hasNext()) {
456
                String key = (String) it.next();
457
                Object obj = this.components.get(key);
458
                if (obj instanceof JDynFormField) {
459
                    JDynFormField field = (JDynFormField) obj;
460
                    if (tipo == field.getDefinition().getDataType()) {
461
                        if (field.asJComponent() instanceof SupportPopupMenu) {
462
                            ((SupportPopupMenu) field.asJComponent()).addSeparatorToPopupMenu();
463
                        }
464
                    }
465
                }
466
            }
467
        }
468
    }
469

    
470
    @Override
471
    public void setBorder(boolean border) {
472
        super.setBorder(border && this.getShowFields().size() >1);
473
    }
474

    
475
}