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 / AbstractJDynFormFieldWithValueList.java @ 2544

History | View | Annotate | Download (17.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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.tools.dynform.spi.dynformfield;
25

    
26
import java.awt.event.ActionEvent;
27
import java.awt.event.ActionListener;
28
import java.awt.event.FocusListener;
29
import java.awt.event.ItemEvent;
30
import java.awt.event.KeyAdapter;
31
import java.awt.event.KeyEvent;
32
import java.util.Objects;
33
import javax.swing.BorderFactory;
34
import javax.swing.ComboBoxModel;
35
import javax.swing.DefaultComboBoxModel;
36

    
37
import javax.swing.JComboBox;
38
import javax.swing.JLabel;
39
import javax.swing.JSpinner;
40
import javax.swing.JTextField;
41
import javax.swing.UIManager;
42
import javax.swing.event.ChangeEvent;
43
import javax.swing.event.DocumentEvent;
44
import javax.swing.event.DocumentListener;
45
import javax.swing.text.JTextComponent;
46
import org.apache.commons.lang3.StringUtils;
47

    
48
import org.gvsig.tools.dataTypes.CoercionException;
49
import org.gvsig.tools.dataTypes.DataType;
50
import org.gvsig.tools.dataTypes.DataTypes;
51
import org.gvsig.tools.dynform.DynFormFieldDefinition;
52
import org.gvsig.tools.dynform.JDynFormField;
53
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
54
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
55
import static org.gvsig.tools.dynform.spi.DynFormSPIManager.TAG_DYNFORM_DROPDOWN;
56
import org.gvsig.tools.dynform.spi.dynformfield.AbstractJDynFormField.IllegalFieldValue;
57
import org.gvsig.tools.dynobject.DynField;
58
import org.gvsig.tools.dynobject.DynField_v2;
59
import org.gvsig.tools.dynobject.DynObject;
60
import org.gvsig.tools.dynobject.DynObjectValueItem;
61
import org.gvsig.tools.swing.api.DropDown;
62
import org.gvsig.tools.swing.api.ToolsSwingLocator;
63
import org.gvsig.tools.swing.api.ToolsSwingManager;
64

    
65
public abstract class AbstractJDynFormFieldWithValueList extends AbstractJDynFormField implements JDynFormField, FocusListener {
66

    
67
    protected Object assignedValue = null;
68
    protected DropDown dropDown = null;
69

    
70
    public AbstractJDynFormFieldWithValueList(
71
            DynFormSPIManager serviceManager,
72
            ComponentsFactory componentsFactory,
73
            JDynFormFieldFactory factory,
74
            DynFormFieldDefinition definition,
75
            Object value
76
    ) {
77
        super(serviceManager, componentsFactory, factory, definition, value);
78
        this.assignedValue = value;
79
    }
80

    
81
    @Override
82
    public Object getAssignedValue() {
83
        return this.assignedValue;
84
    }
85

    
86
    protected JTextField getJTextField() {
87
        if (this.contents instanceof JTextField) {
88
            return (JTextField) this.contents;
89
        }
90
        return null;
91
    }
92

    
93
    protected JSpinner getJSpinnerField() {
94
        if (this.contents instanceof JSpinner) {
95
            return (JSpinner) this.contents;
96
        }
97
        return null;
98
    }
99

    
100
    protected DropDown getDropDown() {
101
        return this.dropDown;
102
    }
103

    
104
    protected DynObjectValueItem[] getAvailableValues() {
105
        DynFormFieldDefinition theDefinition = this.getDefinition();
106
        if( theDefinition == null ) {
107
            return null;
108
        }
109
        if(  theDefinition instanceof DynField_v2 ) {
110
            DynObject context = this.getForm().getDefinition().createElement();
111
            DynField[] fields = context.getDynClass().getDynFields();
112
            for (DynField field : fields) {
113
                String name = field.getName();
114
                JDynFormField jfield = (JDynFormField) this.getForm().getField(name);
115
                if (jfield != null ) {
116
                    try {
117
                        jfield.fetch(context);
118
                    } catch (Exception ex) {
119
//                        LOGGER.warn("Can't get value of field '" + name + "'.", ex);
120
                          // No deberia ser un error. Estamos cogiendo los valores
121
                          // del formulario para rellenar otros campos, puede
122
                          // que aun no se hayan rellenado valores obligatorios
123
                          // en el formulario.
124
                    }
125
                }
126
            }
127
            return theDefinition.getAvailableValues(context);
128
        }
129
        return theDefinition.getAvailableValues();
130
    }
131

    
132
    @Override
133
    public void initComponent() {
134
        ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
135
        ComponentsFactory theFactory = this.getComponentsFactory();
136
        if (theFactory.containsJComboBox(this.getDefinition(), null)) {
137
            JComboBox combo = this.getComponentsFactory().getJComboBox(this.getDefinition(), null);
138
            this.dropDown = ToolsSwingLocator.getToolsSwingManager().createDropDown(combo);
139
            if( this.getDefinition().isAvailableValuesCalculated() ) {
140
                this.dropDown.addDropdownListener((ActionEvent e) -> {
141
                    dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
142
                });
143
            } else {
144
                this.dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
145
            }
146
            this.contents = combo;
147
            this.fixPreferredWidth(this.contents);
148
            this.dropDown.addItemListener((ItemEvent e) -> {
149
                if (e.getStateChange() == ItemEvent.SELECTED) {
150
                    fireFieldChangedEvent();
151
                }
152
            });
153

    
154
        } else if (theFactory.containsJLabel(this.getDefinition(), "Ddn")) {
155
            JLabel label = this.getComponentsFactory().getJLabel(this.getDefinition(), "Ddn");
156
            this.dropDown = ToolsSwingLocator.getToolsSwingManager().createDropDown(label);
157
            if( this.getDefinition().isAvailableValuesCalculated() ) {
158
                this.dropDown.addDropdownListener((ActionEvent e) -> {
159
                    dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
160
                });
161
            } else {
162
                this.dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
163
            }
164
            this.dropDown.setVisibleDropdownArrow(true);
165
            this.contents = label;
166
            this.fixPreferredWidth(this.contents);
167
            this.dropDown.addItemListener((ItemEvent e) -> {
168
                if (e.getStateChange() == ItemEvent.SELECTED) {
169
                    fireFieldChangedEvent();
170
                }
171
            });
172

    
173
        } else if (theFactory.containsJSpinner(this.getDefinition(), null)) {
174
            JSpinner spinner = this.getComponentsFactory().getJSpinner(this.getDefinition(), null);
175
            DataType dataType = this.getDefinition().getDataType();
176
            if (dataType.isNumeric()) {
177
                spinner = ToolsSwingLocator.getToolsSwingManager().spinnerOfNumber(spinner, dataType.getDefaultClass());
178
            } else if (this.getDefinition().getDataType().getType()==DataTypes.TIME) {
179
                spinner = ToolsSwingLocator.getToolsSwingManager().spinnerOfTime(spinner, null);
180
            } 
181
            this.contents = spinner;
182
            this.fixPreferredWidth(this.contents);
183
            this.dropDown = null;
184
            spinner.addChangeListener((ChangeEvent e) -> {
185
                fireFieldChangedEvent();
186
            });
187

    
188
        } else if (theFactory.containsJTextField(this.getDefinition(), null)) {
189
            JTextComponent text = theFactory.getJTextField(this.getDefinition(), null);
190
            this.contents = text;
191
            toolsSwingManager.addClearButton(text);
192
            this.fixPreferredWidth(this.contents);
193
            this.dropDown = null;
194
            text.getDocument().addDocumentListener(new DocumentListener() {
195
                @Override
196
                public void insertUpdate(DocumentEvent e) {
197
                    fireFieldChangedEvent();
198
                }
199

    
200
                @Override
201
                public void removeUpdate(DocumentEvent e) {
202
                    fireFieldChangedEvent();
203
                }
204

    
205
                @Override
206
                public void changedUpdate(DocumentEvent e) {
207
                    fireFieldChangedEvent();
208
                }
209
            });
210
        } else {
211
            DynObjectValueItem[] availableValues = this.getAvailableValues();
212
            if (availableValues == null) {
213
                this.dropDown = null;
214
                JTextComponent text = this.getComponentsFactory().getJTextField(this.getDefinition(), null);
215
                this.contents = text;
216
                toolsSwingManager.addClearButton(text);
217
                this.fixPreferredWidth(this.contents);
218
                text.getDocument().addDocumentListener(new DocumentListener() {
219
                    @Override
220
                    public void insertUpdate(DocumentEvent e) {
221
                        fireFieldChangedEvent();
222
                    }
223

    
224
                    @Override
225
                    public void removeUpdate(DocumentEvent e) {
226
                        fireFieldChangedEvent();
227
                    }
228

    
229
                    @Override
230
                    public void changedUpdate(DocumentEvent e) {
231
                        fireFieldChangedEvent();
232
                    }
233
                });
234
            } else {
235
                String dropdownType = this.getTagValueAsString(TAG_DYNFORM_DROPDOWN,
236
                        availableValues.length <= 20 ? "label" : "combo"
237
                ).toLowerCase().trim();
238
                switch (dropdownType) {
239
                    case "label": {
240
                        JLabel label = this.getComponentsFactory().getJLabel(this.getDefinition(), "Ddn");
241
                        this.dropDown = ToolsSwingLocator.getToolsSwingManager().createDropDown(label);
242
                        this.dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
243
                        if( this.getDefinition().isAvailableValuesCalculated() ) {
244
                            this.dropDown.addDropdownListener((ActionEvent e) -> {
245
                                dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
246
                            });
247
                        }
248
                        this.dropDown.setVisibleDropdownArrow(true);
249
                        label.setBorder(BorderFactory.createLineBorder(UIManager.getColor("TextField.darkShadow")));
250
                        label.setForeground(UIManager.getColor("TextField.foreground"));
251
                        label.setBackground(UIManager.getColor("TextField.background"));
252
                        label.setOpaque(true);
253
                        this.contents = label;
254
                        this.fixPreferredWidth(this.contents);
255
                        break;
256
                    }
257
                    default:
258
                    case "combo": {
259
                        JComboBox combo = this.getComponentsFactory().getJComboBox(this.getDefinition(), null);
260
                        this.dropDown = ToolsSwingLocator.getToolsSwingManager().createDropDown(combo);
261
                        this.dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
262
                        if( this.getDefinition().isAvailableValuesCalculated() ) {
263
                            this.dropDown.addDropdownListener((ActionEvent e) -> {
264
                                dropDown.setModel(new DefaultComboBoxModel(this.getAvailableValues()));
265
                            });
266
                        }
267
                        this.contents = combo;
268
                        this.fixPreferredWidth(this.contents);
269
                        break;
270
                    }
271
                }
272
                this.dropDown.addItemListener((ItemEvent e) -> {
273
                    if (e.getStateChange() == ItemEvent.SELECTED) {
274
                        fireFieldChangedEvent();
275
                    }
276
                });
277
            }
278
        }
279
        this.contents.addFocusListener(this);
280
        this.setReadOnly(readOnly); // Forzamos a actualiza rel estado del component
281
        //component dont have support to set null values
282

    
283
        this.setValue(this.assignedValue);
284
        
285
    }
286
    
287
    @Override
288
    public void setReadOnly(boolean readonly) {
289
        if (!readonly && this.isForcedReadOnly()) {
290
            readonly = true;
291
        }
292
        if (this.dropDown == null) {
293
            super.setReadOnly(readonly);
294
        } else {
295
            this.readOnly = readonly;
296
            if (jlabel != null) {
297
                this.jlabel.setEnabled(!readonly);
298
            }
299
            this.dropDown.setReadOnly(readonly);
300
        }
301
    }
302

    
303
    protected String getValueFromJComponent() {
304
        String s;
305
        if (this.dropDown == null) {
306
            JTextField jtext = this.getJTextField();
307
            if (jtext == null) {
308
                s = null;
309
            } else {
310
                s = jtext.getText();
311
            }
312
        } else {
313
            DynObjectValueItem value = (DynObjectValueItem) this.dropDown.getSelectedItem();
314
            if (value == null) {
315
                s = null;
316
            } else {
317
                s = Objects.toString(value.getValue(), null);
318
            }
319
        }
320
        if (StringUtils.isBlank(s) && this.translateEmptyToNull()) {
321
            return null;
322
        }
323
        return s;
324
    }
325

    
326
    @Override
327
    public void setValue(Object value) {
328
        if (this.dropDown == null) {
329
            JTextField jtext = this.getJTextField();
330
            if (jtext != null) {
331
                this.setTranslateEmptyToNull(value == null);
332
//                String s;
333
//                if (value == null) {
334
//                    this.setTranslateEmptyToNull(true);
335
//                    value = this.getDefinition().getDefaultValue();
336
//                    if (value == null) {
337
//                        s = this.getDefaultValue();
338
//                    } else {
339
//                        s = value.toString();
340
//                    }
341
//                } else {
342
//                    this.setTranslateEmptyToNull(false);
343
//                    s = value.toString();
344
//                    try {
345
//                        this.getDefinition().validate(value);
346
//                        this.problemIndicator().clear();
347
//                    } catch (DynFieldValidateException e) {
348
//                        this.problemIndicator().set(e.getLocalizedMessage());
349
//                    }
350
//                }
351
                jtext.setText(Objects.toString(value, ""));
352
                this.fixPreferredWidth(jtext);
353
            } else if (this.contents instanceof JSpinner) {
354
                JSpinner jspinner = this.getJSpinnerField();
355
                this.setTranslateEmptyToNull(value == null);
356
                jspinner.setValue(value);
357
            }
358
        } else {
359
            if (value == null) {
360
                this.dropDown.setSelectedIndex(-1);
361
            } else {
362
                this.dropDown.setValue(value);
363
            }
364
        }
365
        this.assignedValue = value;
366
    }
367

    
368
    /* 
369
         * M?todos espec?ficos de cada tipo de datos
370
     */
371
    protected String getDefaultValue() {
372
        return "";
373
    }
374

    
375
    @Override
376
    public Object getValue() {
377
        Object value = null;
378
        String s = this.getValueFromJComponent();
379
        try {
380
            value = this.getDefinition().coerce(s);
381
        } catch (CoercionException e) {
382
            throw new IllegalFieldValue(this, "Can't convert value '" + s + "' to '" + this.getDefinition().getDataType().getName() + "'.");
383
        }
384
        this.problemIndicator().clear();
385
        return value;
386
    }
387

    
388
    @SuppressWarnings("unused")
389
    @Override
390
    public boolean hasValidValue() {
391
        try {
392
            Object value = this.getValue();
393
        } catch (Exception e) {
394
            return false;
395
        }
396
        return true;
397
    }
398

    
399
//
400
// Estos metodos los he movido a la superclase.
401
//
402
//    @Override
403
//    public void focusGained(FocusEvent arg0) {
404
//        fireFieldEnterEvent();
405
//        this.problemIndicator().restore();
406
//    }
407
//
408
//    @Override
409
//    public void focusLost(FocusEvent arg0) {
410
//        if (this.hasValidValue()) {
411
//            this.problemIndicator().clear();
412
//        } else {
413
//            try {
414
//                Object value = this.getValue();
415
//            } catch (Exception e) {
416
//                this.problemIndicator().set(e.getLocalizedMessage());
417
//            }
418
//        }
419
//        fireFieldExitEvent();
420
//    }
421
//
422
    /**
423
     * Este m?todo es por si se quiere a?adir una expresi?n regular al
424
     * JTextField Por defecto, se puede escribir cualquier cosa, pero se puede
425
     * sobreescribir este m?todo en la clase que lo requiera para a?adir
426
     * restricciones (p.ej: en los num?ricos)
427
     *
428
     * @return expresi?n regular que filtra el contenido del JTextField
429
     */
430
    public String getJTextFieldRegex() {
431
        return "[*]";
432
    }
433

    
434
    public class KeyAdapterRegEx extends KeyAdapter {
435

    
436
        /**
437
         * Key released on field.
438
         *
439
         * @param e
440
         */
441
        @Override
442
        public void keyReleased(KeyEvent e) {
443
            String curText = ((JTextComponent) e.getSource()).getText();
444
            curText = curText.replaceAll(getJTextFieldRegex(), "");
445

    
446
            ((JTextComponent) e.getSource()).setText(curText);
447
        }
448
    }
449
}