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

History | View | Annotate | Download (17.1 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
import org.apache.commons.lang3.StringUtils;
69
import org.gvsig.tools.ToolsLocator;
70

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

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

    
91
        private Map customActions;
92

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

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

    
116
        public void addListener(JDynFormListener listener) {
117
                this.listeners.add(listener);
118
        }
119

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

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

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

    
263
        private void initComponentsUseTabs() throws ServiceException {
264

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

    
309
        private JPanel addScrollsAndMessageBar(JComponent formPanel) {
310
                formPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
311
                JScrollPane scroll = new JScrollPane(formPanel);
312
                if(useScrollBars){
313
                        scroll.setPreferredSize(new Dimension(formWidth, formHeight));
314
                }else{
315
                        scroll.setPreferredSize(formPanel.getPreferredSize());
316
                }
317
                scroll.setBorder(BorderFactory.createEmptyBorder());
318

    
319
                JPanel jpanel = new JPanel();
320
                jpanel.setLayout(new BorderLayout());
321
                jpanel.add(scroll, BorderLayout.CENTER);
322
                jpanel.add(getMessagesJLabel(), BorderLayout.PAGE_END);
323

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

    
366
        public void getValues(DynObject values) {
367
                DynField[] fields = values.getDynClass().getDynFields();
368
                for( int i=0; i<fields.length; i++ ) {
369
                        String name = fields[i].getName();
370
                        JDynFormField jfield = (JDynFormField) this.getField(name);
371
                        try {
372
                                Object value = jfield.getValue();
373
                                values.setDynValue(name,value);
374
                                
375
                        } catch(Exception ex) {
376
                                logger.info(ex.getLocalizedMessage(), ex);
377
                        }
378
                }
379
        }
380

    
381
        public boolean haveValidValues() {
382
                Iterator it = this.getFieldsIterator();
383
                while( it.hasNext() ) {
384
                        JDynFormField jfield = (JDynFormField) it.next();
385
                        if( ! jfield.hasValidValue() ) {
386
                                return false;
387
                        }
388
                }
389
                
390
                return true;
391
        }
392
        
393
        public boolean haveValidValues(List<String> fieldsName) {
394
                if(fieldsName == null){
395
                        fieldsName = new ArrayList<String>();
396
                }
397
                
398
                Iterator it = this.getFieldsIterator();
399
                while( it.hasNext() ) {
400
                        JDynFormField jfield = (JDynFormField) it.next();
401
                        if( ! jfield.hasValidValue() ) {
402
                                fieldsName.add(jfield.getName());
403
                        }
404
                }
405
                
406
                if(!fieldsName.isEmpty()){
407
                        return false;
408
                }else
409
                        return true;
410
        }
411
        
412
        public boolean isModified() {
413
                Iterator it = this.getFieldsIterator();
414
                while( it.hasNext() ) {
415
                        JDynFormField jfield = (JDynFormField) it.next();
416
                        if( jfield.isModified() ) {
417
                                return true;
418
                        }
419
                }
420
                return false;
421
        }
422

    
423
        public void fieldEnter(JDynFormField field) {
424
                message(field.getDefinition().getDescription());
425
        }
426

    
427
        public void fieldExit(JDynFormField field) {
428
                message();
429
        }
430

    
431
        public void message(JDynFormField field, String message) {
432
                message(message);
433
        }
434

    
435
        public void fieldChanged(JDynFormField field) {
436
                // TODO Auto-generated method stub
437
        }
438

    
439
        public boolean isReadOnly() {
440
                return readOnly;
441
        }
442
        
443
        public void setReadOnly(boolean readOnly) {
444
                this.readOnly = readOnly;
445
                if( this.contents != null ) {
446
                        Iterator it = this.getFieldsIterator();
447
                        while( it.hasNext() ) {
448
                                JDynFormField field = (JDynFormField) it.next();
449
                                field.setReadOnly(readOnly);
450
                        }
451
                }
452
        }
453

    
454
        public int getFormWidth() {
455
                if(this.contents == null){
456
                        return this.formWidth;
457
                }else{
458
                        JViewport port = ((JScrollPane)this.asJComponent()).getViewport();
459
                        Component comp = (Component) port.getView();
460
                        return comp.getWidth();
461
                }
462
        }
463

    
464
        public int getFormHeight() {
465
                if(this.contents == null){
466
                        return this.formHeight;
467
                }else{
468
                        JViewport port = ((JScrollPane)this.asJComponent()).getViewport();
469
                        Component comp = (Component) port.getView();
470
                        return comp.getHeight();
471
                }
472
        }
473

    
474
        public void setFormSize(int width, int height) {
475
                this.formHeight = height;
476
                this.formWidth = width;
477
                if( this.contents != null ){
478
                        this.asJComponent().setPreferredSize(new Dimension(width, height));
479
                }
480
        }
481

    
482
        public void addActionToPopupMenu(DataType tipo, String name, Action action) {
483
                if(this.contents==null){
484
                        List<Action> acts = this.getCustomFields(tipo);
485
                        action.putValue(Action.NAME, name);
486
                        if(acts == null){
487
                                List aux = new ArrayList<Action>();
488
                                aux.add(action);
489
                                customActions.put(tipo.getName(), aux);
490
                        }else{
491
                                acts.add(action);
492
                        }
493
                }else{
494
                        Iterator it = this.components.keySet().iterator();
495
                        while(it.hasNext()){
496
                                String key = (String) it.next();
497
                                Object obj = this.components.get(key);
498
                                if (obj instanceof JDynFormField){
499
                                        JDynFormField field = (JDynFormField) obj;
500
                                        if(tipo == field.getDefinition().getDataType()){
501
                                                if(field.asJComponent() instanceof SupportPopupMenu){
502
                                                        field.addActionToPopupMenu(
503
                                                                        name, 
504
                                                                        action);
505
                                                }
506
                                        }
507
                                }
508
                        }
509
                }
510
        }
511

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

    
568
        public Iterator getFieldsIterator() {
569
                if( this.contents == null ) {
570
                        try {
571
                                this.initComponents();
572
                        } catch (ServiceException e) {
573
                                throw new RuntimeException(e.getLocalizedMessage(),e);
574
                        }
575
                }
576
                return this.components.values().iterator();
577
        }
578

    
579
        public DynFormDefinition getDefinition() {
580
                return this.definition;
581
        }
582

    
583
        public void setUseScrollBars(boolean usesScrolls) {
584
                this.useScrollBars = usesScrolls;
585
        }
586

    
587
        public boolean getUseScrollBars() {
588
                return useScrollBars;
589
        }
590

    
591
}