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

History | View | Annotate | Download (16.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.impl;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Component;
28
import java.awt.Dimension;
29
import java.awt.event.MouseAdapter;
30
import java.awt.event.MouseEvent;
31
import java.util.ArrayList;
32
import java.util.HashMap;
33
import java.util.HashSet;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Map;
37
import java.util.Set;
38

    
39
import javax.swing.Action;
40
import javax.swing.BorderFactory;
41
import javax.swing.JComponent;
42
import javax.swing.JLabel;
43
import javax.swing.JOptionPane;
44
import javax.swing.JPanel;
45
import javax.swing.JScrollPane;
46
import javax.swing.JTabbedPane;
47
import javax.swing.JViewport;
48

    
49
import org.gvsig.tools.dataTypes.CoercionException;
50
import org.gvsig.tools.dataTypes.DataType;
51
import org.gvsig.tools.dynform.DynFormDefinition;
52
import org.gvsig.tools.dynform.DynFormFieldDefinition;
53
import org.gvsig.tools.dynform.JDynForm;
54
import org.gvsig.tools.dynform.JDynFormField;
55
import org.gvsig.tools.dynform.JDynFormField.JDynFormFieldListener;
56
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
57
import org.gvsig.tools.dynform.spi.dynformfield.SupportPopupMenu;
58
import org.gvsig.tools.dynobject.DynClass;
59
import org.gvsig.tools.dynobject.DynField;
60
import org.gvsig.tools.dynobject.DynObject;
61
import org.gvsig.tools.service.ServiceException;
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
import com.jgoodies.forms.builder.DefaultFormBuilder;
66
import com.jgoodies.forms.layout.FormLayout;
67
import com.jgoodies.forms.layout.RowSpec;
68

    
69
@SuppressWarnings({ "unchecked", "rawtypes" })
70
public class DefaultJDynForm implements JDynForm, JDynFormFieldListener {
71

    
72
        protected static final Logger logger = LoggerFactory
73
                        .getLogger(DefaultJDynForm.class);
74
        
75
        private int formWidth= 320;
76
        private int formHeight = 540;
77
        
78
        private DefaultDynFormManager manager = null;
79
        private DynFormDefinition definition = null;
80
        private int layoutMode = USE_PLAIN;
81
        private JComponent contents = null;
82
        private Map components = null;
83
        private JLabel jlabel_messages = null;
84
        private boolean readOnly = false;
85
        private Set listeners = null;
86
        private DynObject values = null;
87

    
88
        private Map customActions;
89

    
90
        public DefaultJDynForm(DefaultDynFormManager manager, DynFormDefinition definition) throws ServiceException {
91
                this.manager = manager;
92
                this.definition = definition;
93
                this.components = new HashMap();
94
                this.listeners = new HashSet();
95
                this.customActions = new HashMap<String,List<Action>>();
96
        }
97

    
98
        public DynFormSPIManager getServiceManager() {
99
                return this.manager.getServiceManager();
100
        }
101
        
102
        public JComponent asJComponent() {
103
                if( this.contents == null ) {
104
                        try {
105
                                this.initComponents();
106
                        } catch (ServiceException e) {
107
                                throw new RuntimeException(e.getLocalizedMessage(),e);
108
                        }
109
                }
110
                return this.contents;
111
        }
112

    
113
        public void addListener(JDynFormListener listener) {
114
                this.listeners.add(listener);
115
        }
116

    
117
        public void removeListener(JDynFormListener listener) {
118
                this.listeners.remove(listener);
119
        }
120
        
121
        protected void fireMessageEvent(String message) {
122
                Iterator it = this.listeners.iterator();
123
                while (it.hasNext()) {
124
                        JDynFormListener listener = (JDynFormListener) it.next();
125
                        try {
126
                        listener.message(message);
127
                        } catch (Exception ex) {
128
                                logger.info("Error calling listener " + listener.toString()
129
                                                + "(" + listener.getClass().getName() + ") from "
130
                                                + this.toString() + "(" + this.getClass().getName()
131
                                                + ").", ex);
132
                        }
133
                }
134
        }
135

    
136
        
137
        public JLabel getMessagesJLabel() {
138
                if( this.jlabel_messages == null ) {
139
                        this.jlabel_messages = new JLabel();
140
                        this.jlabel_messages.addMouseListener(new MouseAdapter()  {
141
                    public void mouseClicked(MouseEvent evt) {
142
                        int count = evt.getClickCount();
143
                        if (count == 2) {
144
                            JOptionPane.showMessageDialog(contents,jlabel_messages.getText(),"Status",JOptionPane.INFORMATION_MESSAGE);
145
                        }
146
                    }
147
                });
148
                }
149
                return this.jlabel_messages;
150
        }
151
        
152
        public void setShowMessageStatus(boolean showMessageStatus) {
153
                this.getMessagesJLabel().setVisible(showMessageStatus);
154
        }
155
        
156
        public boolean isShowMessageStatus() {
157
                return this.getMessagesJLabel().isVisible();
158
        }
159
        
160
        public void message() {
161
                this.getMessagesJLabel().setText(" ");
162
        }
163
        
164
        public void message(String msg) {
165
                this.getMessagesJLabel().setText(msg);
166
                fireMessageEvent(msg);
167
        }
168
        
169
        private void initComponents() throws ServiceException {
170
                switch(this.layoutMode) {
171
                case USE_PLAIN:
172
                default:
173
                        initComponentsPlain();
174
                        break;
175
                case USE_TABS:
176
                        initComponentsUseTabs();
177
                        break;
178
                case USE_SEPARATORS:
179
                        initComponentsUseSeparators();
180
                        break;
181
                }
182
                if( this.values != null ) {
183
                        this.setValues(values);
184
                }
185
                message();
186
        }
187
        
188
        private void initComponentsPlain() throws ServiceException {
189
                 FormLayout layout = new FormLayout(
190
                                   "left:pref,  8px,  fill:80dlu:grow", "pref");
191
                 
192
            DefaultFormBuilder builder = new DefaultFormBuilder(layout);
193
            
194
                List fields = this.definition.getDefinitions();
195
                Iterator it = fields.iterator();
196
                while( it.hasNext() ) {
197
                        DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
198
                        JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
199
                        jfield.setReadOnly(this.readOnly);
200
                        jfield.addListener(this);
201
                        if( this.readOnly ) {
202
                                jfield.setReadOnly(readOnly);
203
                        }
204
                        builder.append(jfield.getJLabel(),   jfield.asJComponent());
205
                        
206
                        this.components.put(jfield.getName(), jfield);
207
                }
208
                this.contents = addScrollsAndMessageBar(builder.getPanel());
209
        }
210

    
211
        private void initComponentsUseSeparators() throws ServiceException {
212
                List groups = this.definition.getGroups();
213
                
214
                FormLayout layout = new FormLayout(
215
                              "left:pref,  8px,  fill:80dlu:grow", "pref");
216
                
217
            DefaultFormBuilder builder = new DefaultFormBuilder(layout);
218
            builder.setDefaultRowSpec(new RowSpec(
219
                                RowSpec.TOP,
220
                                builder.getLayout().getRowSpec(1).getSize(),
221
                                builder.getLayout().getRowSpec(1).getResizeWeight()));
222
            
223
            for( int i=0; i<groups.size(); i++ ) {
224
                    String group = (String) groups.get(i);
225
                    builder.appendSeparator(group);
226
                        List fields = this.definition.getDefinitions(group);
227
                        Iterator it = fields.iterator();
228
                        while( it.hasNext() ) {
229
                                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
230
                                JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
231
                                jfield.addListener(this);
232
                                if( this.readOnly ) {
233
                                        jfield.setReadOnly(readOnly);
234
                                }
235
                                
236
                                List<Action> customActions = getCustomFields(fieldDefinition.getDataType());
237
                                
238
                            if(customActions!= null && !customActions.isEmpty()){
239
                                    Iterator it2 = customActions.iterator();
240
                                    while(it2.hasNext()){
241
                                            Object obj = it2.next();
242
                                            if(obj != null){
243
                                                    Action act = (Action)obj;
244
                                                    jfield.addActionToPopupMenu((String) act.getValue(Action.NAME), act);
245
                                            }else{
246
                                                    jfield.addSeparatorToPopupMenu();
247
                                            }
248
                                    }
249
                            }
250
                                
251
                                builder.append(jfield.getJLabel(),   jfield.asJComponent());
252
                                
253
                                this.components.put(jfield.getName(), jfield);
254
                        }
255
            }
256
                this.contents = addScrollsAndMessageBar(builder.getPanel());
257
        }
258

    
259
        private void initComponentsUseTabs() throws ServiceException {
260

    
261
                JTabbedPane tabbedPane = new JTabbedPane();
262
                
263
                List groups = this.definition.getGroups();
264
                
265
            for( int i=0; i<groups.size(); i++ ) {
266
                    String group = (String) groups.get(i);
267
                    
268
                        FormLayout layout = new FormLayout(
269
                                      "left:pref,  8px,  fill:80dlu:grow", "pref");
270
                        
271
                    DefaultFormBuilder builder = new DefaultFormBuilder(layout);
272
                        builder.setDefaultRowSpec(new RowSpec(
273
                                        RowSpec.TOP,
274
                                        builder.getLayout().getRowSpec(1).getSize(),
275
                                        builder.getLayout().getRowSpec(1).getResizeWeight()));
276
                        
277
                        List fields = this.definition.getDefinitions(group);
278
                        Iterator it = fields.iterator();
279
                        while( it.hasNext() ) {
280
                                DynFormFieldDefinition fieldDefinition = (DynFormFieldDefinition) it.next();
281
                                JDynFormField jfield = getServiceManager().createJDynFormField(fieldDefinition, null);
282
                                jfield.setReadOnly(this.readOnly);
283
                                jfield.addListener(this);
284
                                if( this.readOnly ) {
285
                                        jfield.setReadOnly(readOnly);
286
                                }
287
                                
288
                                builder.append(jfield.getJLabel(),   jfield.asJComponent());
289
                                
290
                                this.components.put(jfield.getName(), jfield);
291
                        }
292
                    tabbedPane.addTab(group, builder.getPanel());
293
            }
294
                this.contents = addScrollsAndMessageBar(tabbedPane);
295
        }
296
        
297
        private List<Action> getCustomFields(DataType dataType) {
298
                return (List<Action>) customActions.get(dataType.getName());
299
        }
300

    
301
        private JPanel addScrollsAndMessageBar(JComponent formPanel) {
302
                formPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
303
                JScrollPane scroll = new JScrollPane(formPanel);
304
                scroll.setPreferredSize(new Dimension(formWidth, formHeight));
305
                scroll.setBorder(BorderFactory.createEmptyBorder());
306

    
307
                JPanel jpanel = new JPanel();
308
                jpanel.setLayout(new BorderLayout());
309
                jpanel.add(scroll, BorderLayout.CENTER);
310
                jpanel.add(getMessagesJLabel(), BorderLayout.PAGE_END);
311

    
312
                return jpanel;
313
        }
314
        
315
        public int getLayoutMode() {
316
                return this.layoutMode;
317
        }
318
        
319
        public void setLayoutMode(int layoutMode) {
320
                if( layoutMode<0 || layoutMode>USE_SEPARATORS) {
321
                        throw new IllegalArgumentException("layoutMode ("+layoutMode+") out of range. Valid values are 0 .. "+ USE_SEPARATORS+".");
322
                }
323
                this.layoutMode = layoutMode;
324
        }
325
        
326
        public void setValues(DynObject values) {
327
                /*
328
                 * TODO: Probablemente fuese mas acertado recorrer los controles de
329
                 * components y a partir de ellos acceder a los valores del DynObject
330
                 * recivido. Eso permitiria trabajar mejor con herencia de DynObject.
331
                 * Habria que hacer lo mismo con el getValues. 
332
                 */
333
                if( this.contents == null ) {
334
                        this.values = values;
335
                        return;
336
                }
337
                DynClass def = values.getDynClass();
338
                DynField[] fields = def.getDynFields();
339
                for( int i=0; i<fields.length; i++ ) {
340
                        String name = fields[i].getName();
341
                        if( name == null || name.isEmpty() ) {
342
                                logger.warn("Field name "+i+" of '"+ def.getFullName() +"' is null or empty ");
343
                                continue;
344
                        }
345
                        JDynFormField jfield = (JDynFormField) this.getField(name);
346
                        if( jfield == null ) {
347
                                logger.warn("Can't retrieve form field asociated to the field '"+name+"' of class '"+ def.getFullName() +"'.");
348
                                continue;
349
                        }
350
                        jfield.setValue(values.getDynValue(name));
351
                }
352
        }
353

    
354
        public void getValues(DynObject values) {
355
                DynField[] fields = values.getDynClass().getDynFields();
356
                for( int i=0; i<fields.length; i++ ) {
357
                        String name = fields[i].getName();
358
                        JDynFormField jfield = (JDynFormField) this.getField(name);
359
                        try {
360
                                Object value = jfield.getValue();
361
                                values.setDynValue(name,value);
362
                                
363
                        } catch(Exception ex) {
364
                                logger.info(ex.getLocalizedMessage(), ex);
365
                        }
366
                }
367
        }
368

    
369
        public boolean haveValidValues() {
370
                Iterator it = this.getFieldsIterator();
371
                while( it.hasNext() ) {
372
                        JDynFormField jfield = (JDynFormField) it.next();
373
                        if( ! jfield.hasValidValue() ) {
374
                                return false;
375
                        }
376
                }
377
                
378
                return true;
379
        }
380
        
381
        public boolean haveValidValues(List<String> fieldsName) {
382
                if(fieldsName == null){
383
                        fieldsName = new ArrayList<String>();
384
                }
385
                
386
                Iterator it = this.getFieldsIterator();
387
                while( it.hasNext() ) {
388
                        JDynFormField jfield = (JDynFormField) it.next();
389
                        if( ! jfield.hasValidValue() ) {
390
                                fieldsName.add(jfield.getName());
391
                        }
392
                }
393
                
394
                if(!fieldsName.isEmpty()){
395
                        return false;
396
                }else
397
                        return true;
398
        }
399
        
400
        public boolean isModified() {
401
                Iterator it = this.getFieldsIterator();
402
                while( it.hasNext() ) {
403
                        JDynFormField jfield = (JDynFormField) it.next();
404
                        if( jfield.isModified() ) {
405
                                return true;
406
                        }
407
                }
408
                return false;
409
        }
410

    
411
        public void fieldEnter(JDynFormField field) {
412
                message(field.getDefinition().getDescription());
413
        }
414

    
415
        public void fieldExit(JDynFormField field) {
416
                message();
417
        }
418

    
419
        public void message(JDynFormField field, String message) {
420
                message(message);
421
        }
422

    
423
        public void fieldChanged(JDynFormField field) {
424
                // TODO Auto-generated method stub
425
        }
426

    
427
        public boolean isReadOnly() {
428
                return readOnly;
429
        }
430
        
431
        public void setReadOnly(boolean readOnly) {
432
                this.readOnly = readOnly;
433
                if( this.contents != null ) {
434
                        Iterator it = this.getFieldsIterator();
435
                        while( it.hasNext() ) {
436
                                JDynFormField field = (JDynFormField) it.next();
437
                                field.setReadOnly(readOnly);
438
                        }
439
                }
440
        }
441

    
442
        public int getFormWidth() {
443
                if(this.contents == null){
444
                        return this.formWidth;
445
                }else{
446
                        JViewport port = ((JScrollPane)this.asJComponent()).getViewport();
447
                        Component comp = (Component) port.getView();
448
                        return comp.getWidth();
449
                }
450
        }
451

    
452
        public int getFormHeight() {
453
                if(this.contents == null){
454
                        return this.formHeight;
455
                }else{
456
                        JViewport port = ((JScrollPane)this.asJComponent()).getViewport();
457
                        Component comp = (Component) port.getView();
458
                        return comp.getHeight();
459
                }
460
        }
461

    
462
        public void setFormSize(int width, int height) {
463
                this.formHeight = height;
464
                this.formWidth = width;
465
                if( this.contents != null ){
466
                        this.asJComponent().setPreferredSize(new Dimension(width, height));
467
                }
468
        }
469

    
470
        public void addActionToPopupMenu(DataType tipo, String name, Action action) {
471
                if(this.contents==null){
472
                        List<Action> acts = this.getCustomFields(tipo);
473
                        action.putValue(Action.NAME, name);
474
                        if(acts == null){
475
                                List aux = new ArrayList<Action>();
476
                                aux.add(action);
477
                                customActions.put(tipo.getName(), aux);
478
                        }else{
479
                                acts.add(action);
480
                        }
481
                }else{
482
                        Iterator it = this.components.keySet().iterator();
483
                        while(it.hasNext()){
484
                                String key = (String) it.next();
485
                                Object obj = this.components.get(key);
486
                                if (obj instanceof JDynFormField){
487
                                        JDynFormField field = (JDynFormField) obj;
488
                                        if(tipo == field.getDefinition().getDataType()){
489
                                                if(field.asJComponent() instanceof SupportPopupMenu){
490
                                                        field.addActionToPopupMenu(
491
                                                                        name, 
492
                                                                        action);
493
                                                }
494
                                        }
495
                                }
496
                        }
497
                }
498
        }
499

    
500
        public void addSeparatorToPopupMenu(DataType tipo) {
501
                if(this.contents==null){
502
                        List<Action> acts = this.getCustomFields(tipo);
503
                        if(acts == null){
504
                                List aux = new ArrayList<Action>();
505
                                aux.add(null);
506
                                customActions.put(tipo.getName(), aux);
507
                        }else{
508
                                acts.add(null);
509
                        }
510
                }else{
511
                        Iterator it = this.components.keySet().iterator();
512
                        while(it.hasNext()){
513
                                String key = (String) it.next();
514
                                Object obj = this.components.get(key);
515
                                if (obj instanceof JDynFormField){
516
                                        JDynFormField field = (JDynFormField) obj;
517
                                        if(tipo == field.getDefinition().getDataType()){
518
                                                if(field.asJComponent() instanceof SupportPopupMenu){
519
                                                        ((SupportPopupMenu)field.asJComponent()).addSeparatorToPopupMenu();
520
                                                }
521
                                        }
522
                                }
523
                        }
524
                }
525
        }
526
        
527
        public Object getValue(String fieldName) {
528
                JDynFormField field = (JDynFormField) this.getField(fieldName);
529
                return field.getValue();
530
        }
531
        
532
        public void setValue(String fieldName, Object value) {
533
                JDynFormField field = (JDynFormField) this.getField(fieldName);
534
                try {
535
                        value = field.getDefinition().getDataType().coerce(value);
536
                } catch (CoercionException e) {
537
                        String msg = "Invalid value '"+((value==null)?"(null)":value.toString())+"' for field '"+fieldName+"'.";
538
                        logger.warn(msg,e);
539
                        throw new RuntimeException(msg, e);
540
                }
541
                field.setValue(value);
542
        }
543
        
544
        public JDynFormField getField(String fieldName) {
545
                if( this.contents == null ) {
546
                        try {
547
                                this.initComponents();
548
                        } catch (ServiceException e) {
549
                                throw new RuntimeException(e.getLocalizedMessage(),e);
550
                        }
551
                }
552
                JDynFormField field = (JDynFormField) this.components.get(fieldName);
553
                return field;
554
        }
555

    
556
        public Iterator getFieldsIterator() {
557
                if( this.contents == null ) {
558
                        try {
559
                                this.initComponents();
560
                        } catch (ServiceException e) {
561
                                throw new RuntimeException(e.getLocalizedMessage(),e);
562
                        }
563
                }
564
                return this.components.values().iterator();
565
        }
566

    
567
        public DynFormDefinition getDefinition() {
568
                return this.definition;
569
        }
570

    
571
}