Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / dynformfield / linkforeingkeywgs / JDynFormFieldForeingKeyWGS.java @ 47727

History | View | Annotate | Download (31 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.app.project.documents.view.dynformfield.linkforeingkeywgs;
24

    
25
import java.awt.Color;
26
import java.awt.GridBagConstraints;
27
import java.awt.GridBagLayout;
28
import java.awt.Image;
29
import java.awt.event.ActionEvent;
30
import java.awt.event.ComponentAdapter;
31
import java.awt.event.ComponentEvent;
32
import java.awt.event.FocusEvent;
33
import java.awt.event.FocusListener;
34
import java.awt.event.InputEvent;
35
import java.awt.event.MouseEvent;
36
import java.util.Objects;
37
import javax.swing.JButton;
38
import javax.swing.JComponent;
39
import javax.swing.JOptionPane;
40
import javax.swing.JPanel;
41
import javax.swing.JTextField;
42
import javax.swing.JToggleButton;
43
import javax.swing.SwingUtilities;
44
import javax.swing.event.AncestorEvent;
45
import javax.swing.event.AncestorListener;
46
import javax.swing.text.JTextComponent;
47
import org.apache.commons.lang.StringUtils;
48
import org.apache.commons.lang3.tuple.ImmutablePair;
49
import org.apache.commons.lang3.tuple.Pair;
50
import org.cresques.cts.IProjection;
51
import org.gvsig.app.ApplicationLocator;
52
import org.gvsig.app.ApplicationManager;
53
import org.gvsig.app.project.documents.view.ViewDocument;
54
import org.gvsig.app.project.documents.view.gui.IView;
55
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
56
import org.gvsig.expressionevaluator.GeometryExpressionUtils;
57
import org.gvsig.featureform.swing.JFeaturesForm;
58
import org.gvsig.featureform.swing.FeaturesFormContext;
59
import org.gvsig.fmap.dal.DataStoreParameters;
60
import org.gvsig.fmap.dal.exception.DataException;
61
import org.gvsig.fmap.dal.feature.Feature;
62
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
63
import org.gvsig.fmap.dal.feature.FeatureQuery;
64
import org.gvsig.fmap.dal.feature.FeatureStore;
65
import org.gvsig.fmap.dal.feature.FeatureType;
66
import org.gvsig.fmap.dal.feature.ForeingKey;
67
import org.gvsig.fmap.dal.feature.ForeingKey.ContextForeingKey;
68
import org.gvsig.fmap.dal.swing.DALSwingLocator;
69
import org.gvsig.fmap.dal.swing.DataSwingManager;
70
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
71
import org.gvsig.fmap.geom.Geometry;
72
import org.gvsig.fmap.geom.GeometryLocator;
73
import org.gvsig.fmap.geom.GeometryManager;
74
import org.gvsig.fmap.geom.exception.CreateGeometryException;
75
import org.gvsig.fmap.geom.primitive.Circle;
76
import org.gvsig.fmap.geom.primitive.Point;
77
import org.gvsig.fmap.mapcontext.MapContext;
78
import org.gvsig.fmap.mapcontext.ViewPort;
79
import org.gvsig.fmap.mapcontext.layers.FLayer;
80
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
81
import org.gvsig.fmap.mapcontext.layers.vectorial.SpatialEvaluatorsFactory;
82
import org.gvsig.fmap.mapcontrol.MapControl;
83
import org.gvsig.fmap.mapcontrol.tools.Behavior.Behavior;
84
import org.gvsig.fmap.mapcontrol.tools.Behavior.PointBehavior;
85
import org.gvsig.fmap.mapcontrol.tools.Behavior.RectangleBehavior;
86
import org.gvsig.fmap.mapcontrol.tools.BehaviorException;
87
import org.gvsig.fmap.mapcontrol.tools.CompoundBehavior;
88
import org.gvsig.fmap.mapcontrol.tools.Events.EnvelopeEvent;
89
import org.gvsig.fmap.mapcontrol.tools.Events.PointEvent;
90
import org.gvsig.fmap.mapcontrol.tools.Listeners.AbstractPointListener;
91
import org.gvsig.fmap.mapcontrol.tools.Listeners.RectangleListener;
92
import org.gvsig.tools.ToolsLocator;
93
import org.gvsig.tools.dispose.DisposeUtils;
94
import org.gvsig.tools.dynform.DynFormFieldDefinition;
95
import org.gvsig.tools.dynform.JDynForm;
96

    
97
import org.gvsig.tools.dynform.JDynFormField;
98
import org.gvsig.tools.dynform.spi.DynFormSPIManager;
99
import org.gvsig.tools.dynform.spi.DynFormSPIManager.ComponentsFactory;
100
import org.gvsig.tools.dynform.spi.dynformfield.AbstractJDynFormField;
101
import org.gvsig.tools.dynform.spi.dynformfield.JDynFormFieldFactory;
102
import org.gvsig.tools.dynobject.DynObject;
103
import org.gvsig.tools.evaluator.Evaluator;
104
import org.gvsig.tools.i18n.I18nManager;
105
import org.gvsig.tools.swing.api.ToolsSwingLocator;
106
import org.gvsig.tools.swing.api.ToolsSwingUtils;
107
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
108
import org.gvsig.tools.swing.api.windowmanager.Dialog;
109
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
110
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
111

    
112
@SuppressWarnings("UseSpecificCatch")
113
public class JDynFormFieldForeingKeyWGS extends AbstractJDynFormField implements JDynFormField {
114

    
115
    private Object assignedValue = null;
116
    private Object value = null;
117
    private Feature relatedFeature = null;
118
    private JTextComponent txtDescription = null;
119
    private JToggleButton btnLinkGraphically = null;
120
    private JButton btnLink = null;
121
    private JButton btnUnlink = null;
122
    private JButton btnEdit = null;
123
    private MapControl mapControl;
124
    private String previosTool;
125
    private Color colorok;
126

    
127
    private static class ForeignkeyCaptureListener extends AbstractPointListener implements RectangleListener {
128

    
129
        private FLyrVect layer;
130
        protected MapControl mapControl;
131
        private JDynFormFieldForeingKeyWGS field;
132

    
133
        private ForeignkeyCaptureListener(MapControl mapControl) {
134
            this.mapControl = mapControl;
135
        }
136

    
137
        public void putValueInFormField(Feature f) throws BehaviorException {
138
            if (f == null) {
139
                return;
140
            }
141
            final ForeingKey foreingKey = field.getForeingKey();
142
            if (foreingKey == null) {
143
                return;
144
            }
145
            final ContextForeingKey context = foreingKey.createContext();
146
            try {
147
                field.setEditedValue(foreingKey.getCode(context, f));
148
                field.relatedFeature = f;
149
            } finally {
150
                DisposeUtils.disposeQuietly(context);
151
            }
152
            field.fireFieldChangedEvent();
153
        }
154

    
155
        public void setLayer(FLyrVect layer) {
156
            this.layer = layer;
157
        }
158

    
159
        public FLyrVect getLayer() {
160
            return this.layer;
161
        }
162
        
163
        public void setField(JDynFormFieldForeingKeyWGS field) {
164
            this.field = field;
165
        }
166

    
167
        @Override
168
        public void point(PointEvent e) throws BehaviorException {
169
            MouseEvent mouseEvent = e.getEvent();
170
            if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
171
                    | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
172
                    || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
173
                return;
174
            }
175
            String layerName = "";
176
            try {
177
                @SuppressWarnings("LocalVariableHidesMemberVariable")
178
                FLyrVect layer = getLayer();
179
                layerName = layer.getName();
180
                ViewPort vp = this.mapControl.getViewPort();
181
                Point point = vp.convertToMapPoint(e.getPoint());
182
                double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
183
                FeatureQuery query = queryByPoint(point, tolerance);
184
                search(layer, query);
185
            } catch (Exception ex) {
186
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
187
            }
188
        }
189

    
190
        private FeatureQuery queryByPoint(Point point, double tol) throws CreateGeometryException, DataException {
191
            GeometryManager manager = GeometryLocator.getGeometryManager();
192
            Circle circle = (Circle) manager.create(Geometry.TYPES.CIRCLE, Geometry.SUBTYPES.GEOM2D);
193
            circle.setPoints(point, tol);
194

    
195
            FLyrVect currentLayer = getLayer();
196
            if (currentLayer == null) {
197
                return null;
198
            }
199
            FeatureStore featureStore = currentLayer.getFeatureStore();
200
            FeatureQuery featureQuery = featureStore.createFeatureQuery();
201
            FeatureType featureType = featureStore.getDefaultFeatureType();
202
            featureQuery.setFeatureType(featureType);
203

    
204
            Geometry query_geo = currentLayer.transformToSourceCRS(circle, true);
205

    
206
            IProjection query_proj = currentLayer.getMapContext().getProjection();
207
            if (currentLayer.getCoordTrans() != null) {
208
                query_proj = currentLayer.getCoordTrans().getPOrig();
209
            }
210

    
211
            Evaluator iee = SpatialEvaluatorsFactory.getInstance().intersects(
212
                    query_geo.getEnvelope(),
213
                    query_proj,
214
                    featureStore
215
            );
216
            featureQuery.setFilter(iee);
217
            featureQuery.retrievesAllAttributes();
218
            return featureQuery;
219
        }
220

    
221
        @Override
222
        public void rectangle(EnvelopeEvent e) throws BehaviorException {
223
            MouseEvent mouseEvent = e.getEvent();
224
            if (((mouseEvent.getModifiersEx() & (InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK
225
                    | InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK | InputEvent.META_DOWN_MASK)) != 0)
226
                    || !SwingUtilities.isLeftMouseButton(mouseEvent)) {
227
                return;
228
            }
229
            String layerName = "";
230
            try {
231
                @SuppressWarnings("LocalVariableHidesMemberVariable")
232
                FLyrVect layer = getLayer();
233
                layerName = layer.getName();
234
                FeatureQuery query;
235
                Geometry geom = e.getWorldCoordRect().getGeometry();
236
                if (geom instanceof Point) {
237
                    ViewPort vp = this.mapControl.getViewPort();
238
                    double tolerance = vp.toMapDistance(layer.getDefaultTolerance());
239
                    query = queryByPoint((Point) geom, tolerance);
240
                } else {
241
                    FeatureStore store = layer.getFeatureStore();
242
                    FeatureType featureType = store.getDefaultFeatureTypeQuietly();
243
                    GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder();
244
                    String filter = builder.ST_Intersects(
245
                            builder.column(featureType.getDefaultGeometryAttributeName()),
246
                            builder.geometry(e.getWorldCoordRect().getGeometry())
247
                    ).toString();
248
                    query = store.createFeatureQuery(filter);
249
                }
250
                search(layer, query);
251
            } catch (Exception ex) {
252
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
253
            }
254
        }
255

    
256
        private void search(FLyrVect layer, FeatureQuery query) {
257
            if (layer == null || query == null) {
258
                return;
259
            }
260
            String layerName = "";
261
            try {
262
                layerName = layer.getName();
263
                FeatureStore featureStore = layer.getFeatureStore();
264
                this.putValueInFormField(featureStore.findFirst(query));
265
            } catch (Exception ex) {
266
                LOGGER.warn("Can't get information from point on the layer " + layerName, ex);
267
            }
268
        }
269
    }
270

    
271
    private static class ForeignkeyCaptureBehavior extends CompoundBehavior {
272

    
273
        ForeignkeyCaptureListener foreignkeyCaptureListener;
274

    
275
        @SuppressWarnings("OverridableMethodCallInConstructor")
276
        public ForeignkeyCaptureBehavior(MapControl mapControl) {
277
            super(new Behavior[0]);
278
            this.foreignkeyCaptureListener = new ForeignkeyCaptureListener(mapControl);
279

    
280
            this.addMapBehavior(new PointBehavior(foreignkeyCaptureListener), true);
281
            this.addMapBehavior(new RectangleBehavior(foreignkeyCaptureListener), true);
282
        }
283

    
284
        @Override
285
        public Image getImageCursor() {
286
            return this.foreignkeyCaptureListener.getImageCursor();
287
        }
288

    
289
        @Override
290
        public ForeignkeyCaptureListener getListener() {
291
            return this.foreignkeyCaptureListener;
292
        }
293

    
294
        public void setLayer(FLyrVect layer) {
295
            this.foreignkeyCaptureListener.setLayer(layer);
296
        }
297

    
298
        public void setField(JDynFormFieldForeingKeyWGS field) {
299
            this.foreignkeyCaptureListener.setField(field);
300
        }
301

    
302
    }
303

    
304
    public JDynFormFieldForeingKeyWGS(
305
            DynFormSPIManager serviceManager,
306
            DynFormSPIManager.ComponentsFactory componentsFactory,
307
            JDynFormFieldFactory factory,
308
            DynFormFieldDefinition definition,
309
            Object value
310
    ) {
311
        super(serviceManager, componentsFactory, factory, definition, value);
312
        if (value != null) {
313
            this.assignedValue = (DynObject) value;
314
        }
315
        this.colorok = Color.white;
316
    }
317

    
318
    @Override
319
    public Object getAssignedValue() {
320
        return this.assignedValue;
321
    }
322

    
323
    public void initComponentIfNeed() {
324
        if (this.contents == null) {
325
            this.initComponent();
326
        }
327
    }
328

    
329
    @Override
330
    public void initComponent() {
331
        ComponentsFactory components = this.getComponentsFactory();
332
        FocusListener focusListener = new FocusListener() {
333
            @Override
334
            public void focusGained(FocusEvent e) {
335
                fireFieldEnterEvent();
336
            }
337

    
338
            @Override
339
            public void focusLost(FocusEvent e) {
340
                fireFieldExitEvent();
341
            }
342
        };
343
        this.txtDescription = components.getJTextField(this.getDefinition(), null);
344
        if (this.txtDescription == null) {
345
            this.txtDescription = new JTextField();
346
        }
347
        this.colorok = this.txtDescription.getBackground();
348
        this.btnLinkGraphically = components.getJToggleButton(this.getDefinition(), "LinkGraphical");
349
        if (this.btnLinkGraphically == null) {
350
            this.btnLinkGraphically = new JToggleButton();
351
        }
352
        this.btnLink = components.getJButton(this.getDefinition(), "Link");
353
        if (this.btnLink == null) {
354
            this.btnLink = new JButton();
355
        }
356
        this.btnUnlink = components.getJButton(this.getDefinition(), "Unlink");
357
        if (this.btnUnlink == null) {
358
            this.btnUnlink = new JButton();
359
        }
360
        this.btnEdit = components.getJButton(this.getDefinition(), "Edit");
361
        if (this.btnEdit == null) {
362
            this.btnEdit = new JButton();
363
        }
364
        ToolsSwingUtils.configurePickersButton(
365
                btnLinkGraphically, 
366
                "_Select_related_item_graphically", 
367
                "selection-simple-select", 
368
                (ActionEvent ae) -> {doLinkGraphically(this.btnLinkGraphically.isSelected());},
369
                focusListener
370
        );
371
        ToolsSwingUtils.configurePickersButton(
372
                btnLink, 
373
                "_Select_related_item", 
374
                "picker-foreingkey-link", 
375
                (ActionEvent ae) -> {doLink();},
376
                focusListener
377
        );
378
        ToolsSwingUtils.configurePickersButton(
379
                btnUnlink, 
380
                "_Remove_relation", 
381
                "picker-foreingkey-unlink", 
382
                (ActionEvent ae) -> {doUnlink();},
383
                focusListener
384
        );
385
        ToolsSwingUtils.configurePickersButton(
386
                btnEdit, 
387
                "_See_related_item", 
388
                "picker-foreingkey-showform", 
389
                (ActionEvent ae) -> {doEdit();},
390
                focusListener
391
        );        
392
        
393
//        this.initButton(this.btnLinkGraphically, "Select item to link graphically", "selection-simple-select");
394
//        this.initButton(this.btnLink, "Select item to link", "formfield-foreignkey-link");
395
//        this.initButton(this.btnUnlink, "Remove link", "formfield-foreignkey-unlink");
396
//        this.initButton(this.btnEdit, "View linked item", "formfield-foreignkey-edit");
397
//
398
//        this.btnLinkGraphically.addActionListener((ActionEvent ae) -> {
399
//            fireFieldEnterEvent();
400
//            doLinkGraphically(this.btnLinkGraphically.isSelected());
401
//        });
402
        this.btnLinkGraphically.addComponentListener(new ComponentAdapter() {
403
            @Override
404
            public void componentHidden(ComponentEvent e) {
405
                doLinkGraphically(false);
406
            }
407
        });
408
        this.btnLinkGraphically.addAncestorListener(new AncestorListener() {
409
            @Override
410
            public void ancestorAdded(AncestorEvent event) {
411
            }
412

    
413
            @Override
414
            public void ancestorRemoved(AncestorEvent event) {
415
                doLinkGraphically(false);
416
            }
417

    
418
            @Override
419
            public void ancestorMoved(AncestorEvent event) {
420
            }
421
        });
422
//        this.btnLink.addActionListener((ActionEvent ae) -> {
423
//            fireFieldEnterEvent();
424
//            doLink();
425
//        });
426
//        this.btnUnlink.addActionListener((ActionEvent ae) -> {
427
//            fireFieldEnterEvent();
428
//            doUnlink();
429
//        });
430
//        this.btnEdit.addActionListener((ActionEvent ae) -> {
431
//            fireFieldEnterEvent();
432
//            doEdit();
433
//        });
434

    
435
        this.txtDescription.setText("                        ");
436
        this.txtDescription.addFocusListener(new FocusListener() {
437
            @Override
438
            public void focusGained(FocusEvent e) {
439
                fireFieldEnterEvent();
440
            }
441

    
442
            @Override
443
            public void focusLost(FocusEvent e) {
444
                fireFieldExitEvent();
445
            }
446
        });
447
        this.txtDescription.setEditable(false);
448

    
449
        boolean enabled = !this.isReadOnly();
450
        this.btnEdit.setEnabled(enabled);
451
        this.btnLink.setEnabled(enabled);
452
        this.btnUnlink.setEnabled(enabled);
453

    
454
        // Habilitar solo si no hay ninguna modal visible.
455
        this.btnLinkGraphically.setEnabled(enabled);
456

    
457
        JPanel panel = new JPanel();
458
        if (!components.containsJTextField(this.getDefinition(), null)) {
459
            panel.setLayout(new GridBagLayout());
460
            GridBagConstraints c = new GridBagConstraints();
461
            c.fill = GridBagConstraints.HORIZONTAL;
462
            c.ipadx = 4;
463
            c.ipady = 1;
464
            c.gridx = 1;
465
            c.gridy = 0;
466
            c.weightx = 1;
467
            panel.add(this.txtDescription, c);
468
            c.fill = GridBagConstraints.NONE;
469
            c.ipadx = 4;
470
            c.ipady = 1;
471
            c.gridx = 2;
472
            c.gridy = 0;
473
            c.weightx = 0;
474
            panel.add(this.btnLinkGraphically, c);
475
            c.fill = GridBagConstraints.NONE;
476
            c.ipadx = 4;
477
            c.ipady = 1;
478
            c.gridx = 3;
479
            c.gridy = 0;
480
            c.weightx = 0;
481
            panel.add(this.btnLink, c);
482
            c.fill = GridBagConstraints.NONE;
483
            c.ipadx = 4;
484
            c.ipady = 1;
485
            c.gridx = 4;
486
            c.gridy = 0;
487
            c.weightx = 0;
488
            panel.add(this.btnUnlink, c);
489
            c.fill = GridBagConstraints.NONE;
490
            c.ipadx = 4;
491
            c.ipady = 1;
492
            c.gridx = 5;
493
            c.gridy = 0;
494
            c.weightx = 0;
495
            panel.add(this.btnEdit, c);
496
        }
497
        this.contents = panel;
498
        this.setValue(this.assignedValue);
499

    
500
    }
501
   
502
//    private AbstractButton initButton(AbstractButton button, final String tip, final String image) {
503
//        if (button.getIcon() == null) {
504
//            IconThemeManager iconThemeManager = ToolsSwingLocator.getIconThemeManager();
505
//            Icon icon = iconThemeManager.getCurrent().get(image);
506
//            if (icon == null) {
507
//                URL url = this.getClass().getClassLoader().getResource("org/gvsig/featureform/swing/impl/" + image + ".png");
508
//                if (url != null) {
509
//                    icon = new ImageIcon(url);
510
//                }
511
//            }
512
//            if (icon != null) {
513
//                button.setIcon(icon);
514
//            }
515
//        }
516
//        if (button.getText().trim().equals("...") && button.getIcon() != null) {
517
//            button.setText("");
518
//        }
519
//        button.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
520
//        button.setBorderPainted(false);
521
////        button.setFocusPainted(false);
522
////        button.setContentAreaFilled(false);
523
//        button.setToolTipText(tip);
524
//        button.setCursor(new Cursor(Cursor.HAND_CURSOR));
525
//        return button;
526
//    }
527

    
528
    private ForeingKey getForeingKey() {
529
        JDynForm.DynFormContext context = this.getForm().getContext();
530
        if (!(context instanceof FeaturesFormContext)) {
531
            return null;
532
        }
533
        FeatureType featureType = ((FeaturesFormContext) context).getFeatureType();
534
        if (featureType == null) {
535
            return null;
536
        }
537
        FeatureAttributeDescriptor attribute = featureType.getAttributeDescriptor(this.getName());
538
        if (attribute == null) {
539
            return null;
540
        }
541
        ForeingKey foreingKey = attribute.getForeingKey();
542
        return foreingKey;
543
    }
544

    
545
    private void doLink() {
546
        final ForeingKey foreingKey = this.getForeingKey();
547
        if (foreingKey == null) {
548
            return;
549
        }
550
        final ContextForeingKey context = foreingKey.createContext();
551
        try {
552
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
553
            final FeatureStoreSearchPanel searchPanel = dataSwingManager.createFeatureStoreSearchPanel(
554
                    foreingKey.getFeatureStore(context)
555
            );
556
            searchPanel.setFilterOnlyMode(true);
557
            WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
558
            
559
            ToolsSwingUtils.ensureHeightWitdh(
560
                    searchPanel, 
561
                    ToolsSwingUtils.RELATIVE_TO_SCREEN,
562
                    0.75f, 0.75f, 0.85f, 0.85f
563
            );               
564
            
565
            final Dialog dialog = winManager.createDialog(
566
                    searchPanel.asJComponent(),
567
                    "Select",
568
                    "Select the '" + this.getLabel() + "'.",
569
                    WindowManager_v2.BUTTONS_OK_CANCEL
570
            );
571
            dialog.setButtonEnabled(WindowManager_v2.BUTTON_OK, this.btnUnlink.isEnabled());
572
            dialog.addActionListener((ActionEvent e) -> {
573
                if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
574
                    Feature feature = searchPanel.getLastSelectedFeature();
575
                    if (feature != null) {
576
                        setEditedValue(foreingKey.getCode(context, feature));
577
                        this.relatedFeature = feature;
578
                        fireFieldChangedEvent();
579
                    }
580
                }
581
            });
582
            dialog.show(WindowManager.MODE.DIALOG);
583

    
584
        } catch (Exception ex) {
585
            LOGGER.warn("Can't show selector", ex);
586
        } finally {
587
            DisposeUtils.disposeQuietly(context);
588
        }
589
    }
590

    
591
    public Feature getRelatedFeature() {
592
        try {
593
            if (this.relatedFeature != null) {
594
                return this.relatedFeature;
595
            }
596
            final ForeingKey foreingKey = this.getForeingKey();
597
            if (foreingKey == null) {
598
                return null;
599
            }
600
            this.relatedFeature = foreingKey.getFeature(null, value);
601
            return this.relatedFeature;
602
        } catch (Exception ex) {
603
            LOGGER.warn("Can't retrieve related feature from '" + value + "'.", ex);
604
            return null;
605
        }
606
    }
607

    
608
    private void doUnlink() {
609
        this.setEditedValue(null);
610
        fireFieldChangedEvent();
611
    }
612

    
613
    private void doEdit() {
614
        if (this.value == null) {
615
            return;
616
        }
617
        final ForeingKey foreingKey = this.getForeingKey();
618
        if (foreingKey == null) {
619
            return;
620
        }
621
        final ContextForeingKey context = foreingKey.createContext();
622
        try {
623
            this.btnEdit.setEnabled(false);
624
            DataSwingManager dataSwingManager = DALSwingLocator.getSwingManager();
625
            FeatureQuery query = foreingKey.getQuery(context, value);
626
            JFeaturesForm form = dataSwingManager.createJFeaturesForm(
627
                    foreingKey.getFeatureStore(context)
628
            );
629
            form.setQuery(query);
630
            form.showForm(WindowManager.MODE.WINDOW);
631

    
632
        } catch (Exception ex) {
633
            LOGGER.warn("Can't show linked form", ex);
634
        } finally {
635
            this.btnEdit.setEnabled(true);
636
            DisposeUtils.disposeQuietly(context);
637
        }
638
    }
639

    
640
    private String getDescription() {
641
        if (this.value == null) {
642
            return null;
643
        }
644
        try {
645
            final ForeingKey foreingKey = this.getForeingKey();
646
            if (foreingKey == null) {
647
                return null;
648
            }
649
            String description = foreingKey.getLabel(null, value);
650
            return description;
651
        } catch (Exception ex) {
652
        }
653
        return null;
654

    
655
    }
656

    
657
    @Override
658
    public void setReadOnly(boolean readonly) {
659
        initComponentIfNeed();
660
        this.readOnly = readonly;
661
        boolean editable = !readonly;
662
        JComponent theJLabel = this.getJLabel();
663
        if( this.jlabel != null ) {
664
            this.jlabel.setEnabled(editable);
665
        } else if( theJLabel !=null ) {
666
            theJLabel.setEnabled(editable);
667
        }
668
        this.txtDescription.setEditable(false);
669
        this.btnEdit.setEnabled(true);
670
        this.btnLink.setEnabled(true);
671
        this.btnUnlink.setEnabled(editable);
672

    
673
        // Habilitar solo si no hay ninguna modal visible.
674
        this.btnLinkGraphically.setEnabled(editable);
675
        this.setReadOnlyButtonsOfEvents(readonly);
676
    }
677

    
678
    @Override
679
    public void setValue(Object value) {
680
        setEditedValue(value);
681
        this.assignedValue = value;
682
    }
683

    
684
    public void setEditedValue(Object value) {
685
        initComponentIfNeed();
686
        if (value == null) {
687
            this.value = null;
688
            this.txtDescription.setText("");
689
            return;
690
        }
691
        this.problemIndicator().clear();
692
        this.value = value;
693
        String description = this.getDescription();
694
        if( description == null ) {
695
            this.txtDescription.setText(Objects.toString(value, ""));
696
            this.txtDescription.setBackground(ToolsSwingLocator.getToolsSwingManager().getWarningBackgroundColor());
697
            I18nManager i18n = ToolsLocator.getI18nManager();
698
            this.problemIndicator().set(i18n.getTranslation("_Related_feature_not_found"));
699
        } else {
700
            this.txtDescription.setText(Objects.toString(description));
701
            this.txtDescription.setBackground(this.colorok);
702
        }       
703
        this.relatedFeature = null;
704
    }
705

    
706
    @Override
707
    public Object getValue() {
708
        return this.value;
709
    }
710

    
711
    @Override
712
    public boolean hasValidValue() {
713
        return true;
714
    }
715

    
716
    @Override
717
    public void clear() {
718
        this.setValue(null);
719
    }
720

    
721
    @Override
722
    public boolean isModified() {
723
        return !Objects.equals(this.value, this.getAssignedValue());
724
    }
725

    
726
    private void doLinkGraphically(boolean isSelected) {
727
        final ForeingKey foreingKey = this.getForeingKey();
728
        if (foreingKey == null) {
729
            LOGGER.warn("Can't retrieve foreignkey information");
730
            return;
731
        }
732
        final ContextForeingKey context = foreingKey.createContext();
733
        try {
734
            if (isSelected) {
735
                FeatureStore store = foreingKey.getFeatureStore(context);
736
                Pair<MapControl, FLyrVect> mapControlAndLayer = findMapControl(store);
737
                if (mapControlAndLayer != null) {
738
                    this.mapControl = mapControlAndLayer.getLeft();
739
                    if (!this.mapControl.hasTool("foreingkey-capture")) {
740
                        Behavior captureTool = new ForeignkeyCaptureBehavior(mapControl);
741
                        this.mapControl.addBehavior("foreingkey-capture", captureTool);
742
                    }
743
                    String s = this.mapControl.getCurrentTool();
744
                    if (!StringUtils.equalsIgnoreCase(s, "foreingkey-capture")) {
745
                        this.previosTool = s;
746
                    }
747
                    this.mapControl.setTool("foreingkey-capture");
748
                    Behavior captureTool = this.mapControl.getCurrentMapTool();
749
                    if (captureTool instanceof ForeignkeyCaptureBehavior) {
750
                        ((ForeignkeyCaptureBehavior)captureTool).setField(this);
751
                        ((ForeignkeyCaptureBehavior)captureTool).setLayer(mapControlAndLayer.getRight());
752
                    }
753
                    this.getForm().message("Activada la seleccion grafica de '"+this.getDefinition().getLabel()+"'.");
754
                } else {
755
                    ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
756
                    dialogs.messageDialog(
757
                            "No se ha encontrado la tabla '"+store.getName()+"' en la Vista activa.", 
758
                            "Selector grafico", 
759
                            JOptionPane.INFORMATION_MESSAGE
760
                    );
761
                    this.mapControl = null;
762
                    this.btnLinkGraphically.setSelected(false);
763
                }
764
            } else {
765
                if( this.mapControl!=null ) {
766
                    if (StringUtils.isBlank(this.previosTool)) {
767
                        this.mapControl.setTool("pointSelection");
768
                    } else {
769
                        this.mapControl.setTool(this.previosTool);
770
                    }
771
                }
772
                this.getForm().message("Desactivada la seleccion grafica.");
773
            }
774
        } catch (Exception ex) {
775
            LOGGER.warn("Can't active/deactive foreingkey grafical selection", ex);
776
        } finally {
777
            DisposeUtils.disposeQuietly(context);
778
        }
779
    }
780

    
781
    private Pair<MapControl, FLyrVect> findMapControl(FeatureStore store) {
782
        ApplicationManager application = ApplicationLocator.getApplicationManager();
783
        IView view = (IView) application.getActiveComponent(ViewDocument.class);
784
        if (view == null) {
785
            return null;
786
        }
787
        DataStoreParameters storeParams = store.getParameters();
788
        MapControl theMapControl = view.getMapControl();
789
        MapContext mapContext = theMapControl.getMapContext();
790
        for (FLayer layer : mapContext.getLayers().deepiterable()) {
791
            if (layer instanceof FLyrVect) {
792
                FeatureStore layerStore = ((FLyrVect) layer).getFeatureStore();
793
                if (layerStore.getParameters().isTheSameStore(storeParams)) {
794
                    return new ImmutablePair<>(theMapControl, ((FLyrVect) layer));
795
                }
796
            }
797
        }
798
        return null;
799
    }
800
}