Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / featureform / swing / impl / dynformfield / linkforeingkey / JDynFormFieldForeingKey.java @ 47213

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 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.featureform.swing.impl.dynformfield.linkforeingkey;
24

    
25
import java.awt.Dimension;
26
import java.awt.GridBagConstraints;
27
import java.awt.GridBagLayout;
28
import java.awt.event.ActionEvent;
29
import java.awt.event.FocusEvent;
30
import java.awt.event.FocusListener;
31
import java.util.List;
32
import java.util.Objects;
33
import javax.swing.JButton;
34
import javax.swing.JComponent;
35
import javax.swing.JList;
36
import javax.swing.JPanel;
37
import javax.swing.JScrollPane;
38
import javax.swing.JTextField;
39
import javax.swing.ListModel;
40
import javax.swing.event.ListDataListener;
41
import javax.swing.text.JTextComponent;
42
import org.apache.commons.lang3.ArrayUtils;
43
import org.apache.commons.text.StringEscapeUtils;
44
import org.gvsig.featureform.swing.JFeaturesForm;
45
import org.gvsig.featureform.swing.FeaturesFormContext;
46
import org.gvsig.fmap.dal.feature.Feature;
47
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
48
import org.gvsig.fmap.dal.feature.FeatureQuery;
49
import org.gvsig.fmap.dal.feature.FeatureType;
50
import org.gvsig.fmap.dal.feature.ForeingKey;
51
import org.gvsig.fmap.dal.feature.ForeingKey.ContextForeingKey;
52
import org.gvsig.fmap.dal.swing.DALSwingLocator;
53
import org.gvsig.fmap.dal.swing.DataSwingManager;
54
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
55
import org.gvsig.tools.dispose.DisposeUtils;
56
import org.gvsig.tools.dynform.DynFormFieldDefinition;
57
import org.gvsig.tools.dynform.JDynForm;
58

    
59
import org.gvsig.tools.dynform.JDynFormField;
60
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
61
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
62
import org.gvsig.tools.dynform.spi.dynformfield.AbstractJDynFormField;
63
import org.gvsig.tools.dynform.spi.dynformfield.JDynFormFieldFactory;
64
import org.gvsig.tools.dynobject.DynObject;
65
import org.gvsig.tools.swing.api.ToolsSwingLocator;
66
import org.gvsig.tools.swing.api.ToolsSwingUtils;
67
import org.gvsig.tools.swing.api.windowmanager.Dialog;
68
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
69
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
70

    
71
@SuppressWarnings("UseSpecificCatch")
72
public class JDynFormFieldForeingKey extends AbstractJDynFormField implements JDynFormField {
73

    
74
    private Object assignedValue = null;
75
    private Object value = null;
76
    private Feature relatedFeature = null;
77
    private JTextComponent txtDescription = null;
78
    private JButton btnLink = null;
79
    private JButton btnUnlink = null;
80
    private JButton btnEdit = null;
81

    
82
    public JDynFormFieldForeingKey(
83
            DynFormSPIManager serviceManager,
84
            DynFormSPIManager.ComponentsFactory componentsFactory,
85
            JDynFormFieldFactory factory,
86
            DynFormFieldDefinition definition,
87
            Object value
88
    ) {
89
        super(serviceManager, componentsFactory, factory, definition, value);
90
        if (value != null) {
91
            this.assignedValue = (DynObject) value;
92
        }
93
    }
94

    
95
    @Override
96
    public Object getAssignedValue() {
97
        return this.assignedValue;
98
    }
99

    
100
    public void initComponentIfNeed() {
101
        if (this.contents == null) {
102
            this.initComponent();
103
        }
104
    }
105

    
106
    @Override
107
    public void initComponent() { 
108
        ComponentsFactory components = this.getComponentsFactory();
109
        FocusListener focusListener = new FocusListener() {
110
            @Override
111
            public void focusGained(FocusEvent e) {
112
                fireFieldEnterEvent();
113
            }
114

    
115
            @Override
116
            public void focusLost(FocusEvent e) {
117
                fireFieldExitEvent();
118
            }
119
        };
120
        this.txtDescription = components.getJTextField(this.getDefinition(), null);
121
        if( this.txtDescription==null ) {
122
            this.txtDescription = new JTextField();
123
        }
124
        this.btnLink = components.getJButton(this.getDefinition(), "Link");
125
        if( this.btnLink==null ) {
126
            this.btnLink = new JButton();
127
        }
128
        this.btnUnlink = components.getJButton(this.getDefinition(), "Unlink");
129
        if( this.btnUnlink==null ) {
130
            this.btnUnlink = new JButton();
131
        }
132
        this.btnEdit = components.getJButton(this.getDefinition(), "Edit");
133
        if( this.btnEdit==null ) {
134
            this.btnEdit = new JButton();
135
        }
136
        ToolsSwingUtils.configurePickersButton(
137
                btnLink, 
138
                "_Select_related_item", 
139
                "picker-foreingkey-link", 
140
                (ActionEvent ae) -> {doLink();},
141
                focusListener
142
        );
143
        ToolsSwingUtils.configurePickersButton(
144
                btnUnlink, 
145
                "_Remove_relation", 
146
                "picker-foreingkey-unlink", 
147
                (ActionEvent ae) -> {doUnlink();},
148
                focusListener
149
        );
150
        ToolsSwingUtils.configurePickersButton(
151
                btnEdit, 
152
                "_See_related_item", 
153
                "picker-foreingkey-showform", 
154
                (ActionEvent ae) -> {doEdit();},
155
                focusListener
156
        );
157

    
158
        this.txtDescription.setText("");
159
        this.txtDescription.addFocusListener(focusListener);
160
        this.txtDescription.setEnabled(true);
161
        this.txtDescription.setEditable(false);
162
        this.txtDescription.setFocusable(true);
163

    
164
        boolean enabled = !this.isReadOnly();
165
        this.btnEdit.setEnabled(enabled);
166
        this.btnLink.setEnabled(enabled);
167
        this.btnUnlink.setEnabled(enabled);
168

    
169
        JPanel panel = new JPanel();
170
        panel.setFocusCycleRoot(false);
171
        panel.setFocusable(false);
172
        if( !components.containsJTextField(this.getDefinition(), null) ) {
173
            panel.setLayout(new GridBagLayout());
174
            GridBagConstraints c = new GridBagConstraints();
175
            c.fill = GridBagConstraints.HORIZONTAL;
176
            c.ipadx = 4;
177
            c.ipady = 1;
178
            c.gridx = 1;
179
            c.gridy = 0;
180
            c.weightx = 1;
181
            panel.add(this.txtDescription, c);
182
            c.fill = GridBagConstraints.NONE;
183
            c.ipadx = 4;
184
            c.ipady = 1;
185
            c.gridx = 2;
186
            c.gridy = 0;
187
            c.weightx = 0;
188
            panel.add(this.btnLink, c);
189
            c.fill = GridBagConstraints.NONE;
190
            c.ipadx = 4;
191
            c.ipady = 1;
192
            c.gridx = 3;
193
            c.gridy = 0;
194
            c.weightx = 0;
195
            panel.add(this.btnUnlink, c);
196
            c.fill = GridBagConstraints.NONE;
197
            c.ipadx = 4;
198
            c.ipady = 1;
199
            c.gridx = 4;
200
            c.gridy = 0;
201
            c.weightx = 0;
202
            panel.add(this.btnEdit, c);
203
        }
204
        this.contents = panel;
205
        this.setValue(this.assignedValue);
206

    
207
    }
208
    
209
    private void fireFocusEvent(java.awt.Component c, int eventId) {
210
        FocusListener[] focusListeners = c.getListeners(FocusListener.class);
211
        if( !ArrayUtils.isEmpty(focusListeners) ) {
212
            for (FocusListener focusListener : focusListeners) {
213
                if( focusListener == null ) {
214
                    continue;
215
                }
216
                try {
217
                    FocusEvent e = new FocusEvent(c, eventId);
218
                    switch(eventId) {
219
                        case FocusEvent.FOCUS_GAINED:
220
                            focusListener.focusGained(e);
221
                            break;
222
                        case FocusEvent.FOCUS_LOST:
223
                            focusListener.focusLost(e);
224
                            break;
225
                    }
226
                } catch(Throwable t) {
227
                    LOGGER.warn("Can't fire eveny focusGained on DropDownLabel ("+focusListener.getClass().getName()+").",t);
228
                }
229
            }
230
        }
231
    }
232
    
233
    private ForeingKey getForeingKey() {
234
        JDynForm.DynFormContext context = this.getForm().getContext();
235
        if( !(context instanceof FeaturesFormContext) ) {
236
            return null;
237
        }
238
        FeatureType featureType = ((FeaturesFormContext)context).getFeatureType();
239
        if( featureType==null ) {
240
            return null;
241
        }
242
        FeatureAttributeDescriptor attribute = featureType.getAttributeDescriptor(this.getName());
243
        if( attribute == null ) {
244
            return null;
245
        }
246
        ForeingKey foreingKey = attribute.getForeingKey();
247
        return foreingKey;
248
    }
249
    
250
    private void doLink0() {
251
        final ForeingKey foreingKey = this.getForeingKey();
252
        if( foreingKey==null ) {
253
            return;
254
        }
255
        final ContextForeingKey context = foreingKey.createContext();
256
        try {
257
            final List<Feature> features = foreingKey.getFeatures(context);
258
            
259
            ListModel<String> model = new ListModel<String>() {
260
                @Override
261
                public int getSize() {
262
                    return features.size();
263
                }
264

    
265
                @Override
266
                public String getElementAt(int index) {
267
                    Feature feature = features.get(index);
268
                    ForeingKey foreingKey = getForeingKey();
269
                    return foreingKey.getLabel(context, feature);
270
                }
271

    
272
                @Override
273
                public void addListDataListener(ListDataListener l) {
274
                }
275

    
276
                @Override
277
                public void removeListDataListener(ListDataListener l) {
278
                }
279
            };
280
            WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
281

    
282
            final JList<String> jlist = new JList<>();
283
            JScrollPane jscroll = new JScrollPane(jlist);
284
            jscroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
285
            jscroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
286
            jlist.setModel(model);
287
            jlist.setPreferredSize(new Dimension(350, 200));
288
            final Dialog dialog = winManager.createDialog(
289
                    jscroll,
290
                    "Select",
291
                    "Select the '"+this.getLabel()+"'.", 
292
                    WindowManager_v2.BUTTONS_OK_CANCEL
293
            );
294
            dialog.addActionListener((ActionEvent e) -> {
295
                if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
296
                    int n = jlist.getSelectedIndex();
297
                    if( n<0 ) {
298
                        return;
299
                    }
300
                    Feature feature = features.get(n);
301
                    if( feature!=null ) {
302
                        setEditedValue(foreingKey.getCode(context, feature));
303
                        fireFieldChangedEvent();
304
                    }
305
                }
306
            });
307
            dialog.show(WindowManager.MODE.DIALOG);
308

    
309
        } catch (Exception ex) {
310
            LOGGER.warn("Can't show selector", ex);
311
        } finally {
312
            DisposeUtils.disposeQuietly(context);
313
        }
314
    }
315
    
316
    private void doLink() {
317
        final ForeingKey foreingKey = this.getForeingKey();
318
        if( foreingKey==null ) {
319
            return;
320
        }
321
        final ContextForeingKey context = foreingKey.createContext();
322
        try {
323
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
324
            final FeatureStoreSearchPanel searchPanel = dataSwingManager.createFeatureStoreSearchPanel(
325
                    foreingKey.getFeatureStore(context)
326
            );
327
            searchPanel.setFilterOnlyMode(true);
328
            WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
329

    
330
            ToolsSwingUtils.ensureHeightWitdh(
331
                    searchPanel, 
332
                    ToolsSwingUtils.RELATIVE_TO_SCREEN,
333
                    0.75f, 0.75f, 0.85f, 0.85f
334
            );          
335
                        
336
            final Dialog dialog = winManager.createDialog(
337
                    searchPanel.asJComponent(),
338
                    "Select",
339
                    "Select the '"+this.getLabel()+"'.", 
340
                    WindowManager_v2.BUTTONS_OK_CANCEL
341
            );
342
            dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, this.btnUnlink.isEnabled());
343
            dialog.addActionListener((ActionEvent e) -> {
344
                if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) {
345
                    Feature feature = searchPanel.getLastSelectedFeature();
346
                    if( feature!=null ) {
347
                        setEditedValue(foreingKey.getCode(context, feature));
348
                        this.relatedFeature = feature;
349
                        fireFieldChangedEvent();
350
                    }
351
                }
352
            });
353
            dialog.show(WindowManager.MODE.DIALOG);
354

    
355
        } catch (Exception ex) {
356
            LOGGER.warn("Can't show selector", ex);
357
        } finally {
358
            DisposeUtils.disposeQuietly(context);
359
        }
360
    }
361

    
362
    public Feature getRelatedFeature() {
363
        try {
364
            if( this.relatedFeature!=null ) {
365
                return this.relatedFeature;
366
            }
367
            final ForeingKey foreingKey = this.getForeingKey();
368
            if( foreingKey == null ) {
369
                return null;
370
            }
371
            this.relatedFeature = foreingKey.getFeature(null, value);
372
            return this.relatedFeature;
373
        } catch(Exception ex) {
374
            LOGGER.warn("Can't retrieve related feature from '"+value+"'.",ex);
375
            return null;
376
        }
377
    }
378
    
379
    private void doUnlink() {
380
        this.setEditedValue(null);
381
        fireFieldChangedEvent();
382
    }
383

    
384
    private void doEdit() {
385
        if (this.value == null) {
386
            return;
387
        }
388
        final ForeingKey foreingKey = this.getForeingKey();
389
        if( foreingKey==null ) {
390
            return;
391
        }
392
        final ContextForeingKey context = foreingKey.createContext();
393
        try {
394
            this.btnEdit.setEnabled(false);
395
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
396
            FeatureQuery query = foreingKey.getQuery(context, value);
397
            JFeaturesForm form = dataSwingManager.createJFeaturesForm(
398
                    foreingKey.getFeatureStore(context)
399
            );
400
            form.setQuery(query);
401
            form.showForm(WindowManager.MODE.WINDOW);
402

    
403
        } catch (Exception ex) {
404
            LOGGER.warn("Can't show linked form", ex);
405
        } finally {
406
            this.btnEdit.setEnabled(true);
407
            DisposeUtils.disposeQuietly(context);
408
        }
409
    }
410

    
411
    private String getDescription() {
412
        if (this.value == null) {
413
            return null;
414
        }
415
        try {
416
            final ForeingKey foreingKey = this.getForeingKey();
417
            if( foreingKey==null ) {
418
                return null;
419
            }
420
            String description = foreingKey.getLabel(null, value);
421
            return description;
422
        } catch (Exception ex) {
423
        }
424
        return null;
425

    
426
    }
427
    
428
    @Override
429
    public void setReadOnly(boolean readonly) {
430
        initComponentIfNeed();
431
        this.readOnly = readonly;
432
        boolean editable = !readonly;
433
        JComponent theJLabel = this.getJLabel();
434
        if( this.jlabel != null ) {
435
            this.jlabel.setEnabled(editable);
436
        } else if( theJLabel !=null ) {
437
            theJLabel.setEnabled(editable);
438
        }
439
        this.txtDescription.setEditable(false);
440
        this.btnEdit.setEnabled(true);
441
        this.btnLink.setEnabled(true);
442
        this.btnUnlink.setEnabled(editable);
443
        this.setReadOnlyButtonsOfEvents(readonly);
444
    }
445

    
446
    @Override
447
    public void setValue(Object value) {
448
        setEditedValue(value);
449
        this.assignedValue = value;
450
       this.relatedFeature = null;
451
    }
452

    
453
    public void setEditedValue(Object value) {
454
        initComponentIfNeed();
455
        if (value == null) {
456
            this.value = null;
457
            this.txtDescription.setText("");
458
            return;
459
        }
460
        this.value = value;
461
        this.txtDescription.setText(Objects.toString(this.getDescription(), ""));
462
       
463
    }
464
    
465
    @Override
466
    public Object getValue() {
467
        return this.value;
468
    }
469

    
470
    @Override
471
    public boolean hasValidValue() {
472
        return true;
473
    }
474

    
475
    @Override
476
    public void clear() {
477
        this.setValue(null);
478
    }
479

    
480
    @Override
481
    public boolean isModified() {
482
        return !Objects.equals(this.value, this.getAssignedValue());
483
    }
484
    
485

    
486
    @Override
487
    public String toHTML() {
488
        return "<span>"+StringEscapeUtils.escapeHtml3(this.getDescription())+"</span>";
489
    }
490
    
491
}