Statistics
| Revision:

root / branches / v2_0_0_prep / extensions / extWFS2 / src / org / gvsig / wfs / gui / panels / WFSSelectFeaturePanel.java @ 34026

History | View | Annotate | Download (36.6 KB)

1
package org.gvsig.wfs.gui.panels;
2

    
3
import java.awt.Color;
4
import java.awt.Component;
5
import java.awt.Graphics;
6
import java.awt.Point;
7
import java.awt.Rectangle;
8
import java.awt.event.MouseAdapter;
9
import java.awt.event.MouseEvent;
10
import java.text.Collator;
11
import java.util.Collections;
12
import java.util.Locale;
13
import java.util.Vector;
14

    
15
import javax.swing.DefaultListSelectionModel;
16
import javax.swing.JCheckBox;
17
import javax.swing.JComponent;
18
import javax.swing.JLabel;
19
import javax.swing.JPanel;
20
import javax.swing.JScrollPane;
21
import javax.swing.JTable;
22
import javax.swing.JTextField;
23
import javax.swing.ListSelectionModel;
24
import javax.swing.UIManager;
25
import javax.swing.event.DocumentEvent;
26
import javax.swing.event.DocumentListener;
27
import javax.swing.event.ListSelectionListener;
28
import javax.swing.plaf.basic.BasicTableHeaderUI;
29
import javax.swing.table.AbstractTableModel;
30
import javax.swing.table.DefaultTableCellRenderer;
31
import javax.swing.table.TableCellRenderer;
32
import javax.swing.table.TableColumn;
33
import javax.swing.table.TableColumnModel;
34
import javax.swing.table.TableModel;
35

    
36
import org.gvsig.andami.PluginServices;
37
import org.gvsig.andami.messages.NotificationManager;
38
import org.gvsig.gui.beans.panelGroup.IPanelGroup;
39
import org.gvsig.remoteclient.wfs.WFSFeatureField;
40
import org.gvsig.utils.StringComparator;
41
import org.gvsig.wfs.gui.panels.WFSSelectFeaturePanel.LayerTable.LayerTableModel;
42
import org.gvsig.wfs.gui.panels.model.WFSSelectedFeature;
43

    
44

    
45
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
46
 *
47
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
48
 *
49
 * This program is free software; you can redistribute it and/or
50
 * modify it under the terms of the GNU General Public License
51
 * as published by the Free Software Foundation; either version 2
52
 * of the License, or (at your option) any later version.
53
 *
54
 * This program is distributed in the hope that it will be useful,
55
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
56
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57
 * GNU General Public License for more details.
58
 *
59
 * You should have received a copy of the GNU General Public License
60
 * along with this program; if not, write to the Free Software
61
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
62
 *
63
 * For more information, contact:
64
 *
65
 *  Generalitat Valenciana
66
 *   Conselleria d'Infraestructures i Transport
67
 *   Av. Blasco Ib??ez, 50
68
 *   46010 VALENCIA
69
 *   SPAIN
70
 *
71
 *      +34 963862235
72
 *   gvsig@gva.es
73
 *      www.gvsig.gva.es
74
 *
75
 *    or
76
 *
77
 *   IVER T.I. S.A
78
 *   Salamanca 50
79
 *   46005 Valencia
80
 *   Spain
81
 *
82
 *   +34 963163400
83
 *   dac@iver.es
84
 */
85
/* CVS MESSAGES:
86
 *
87
 * $Id: WFSSelectFeaturePanel.java 18799 2008-02-12 16:53:03Z vcaballero $
88
 * $Log$
89
 * Revision 1.19  2007-09-19 16:14:50  jaume
90
 * removed unnecessary imports
91
 *
92
 * Revision 1.18  2007/03/15 13:34:16  ppiqueras
93
 * Eliminado mensaje de aviso no necesario.
94
 *
95
 * Revision 1.17  2007/03/05 13:49:42  ppiqueras
96
 * Si una capa WFS no tiene campos (y por tanto no tiene un campo obligatorio de tipo geometr?a), que avise al usuario y no permita que se intente cargar dicha capa.
97
 *
98
 * Revision 1.16  2007/02/22 12:25:09  ppiqueras
99
 * A?adidas tool tip text.
100
 *
101
 * Revision 1.15  2007/02/09 14:12:39  jorpiell
102
 * Soporte para WFS 1.1 y WFS-T
103
 *
104
 * Revision 1.14  2007/02/07 13:26:23  ppiqueras
105
 * Corregido bug: al seleccionar una feature, pero sin cerrar el di?logo, se retrocede y se conecta a otro servidor,  se manten?a la posici?n seleccionada en la tabla de features. Se ha solucionado haciendo que se quede deseleccionada toda la tabla de features.
106
 *
107
 * Revision 1.13  2007/01/23 13:12:43  ppiqueras
108
 * Corregido un peque?o bug: el ?rea de texto del nombre de la feature no debe ser editable, dado que si se edita no procesa el texto escrito.
109
 *
110
 * Revision 1.12  2007/01/15 14:16:22  ppiqueras
111
 * Corregido bug: no cargaba los campos al principio y adem?s se ejecutaba m?s de una vez.
112
 *
113
 * Revision 1.11  2006/12/15 13:57:34  ppiqueras
114
 * eliminado un import que sobraba
115
 *
116
 * Revision 1.10  2006/12/12 10:24:45  ppiqueras
117
 * Nueva funcionalidad: Pulsando doble 'click' sobre una capa de un servidor, se carga (igual que antes), pero adem?s se avanza a la siguiente pesta?a sin tener que pulsar el bot?n 'Siguiente'.
118
 *
119
 * Revision 1.9  2006/12/04 08:59:47  ppiqueras
120
 * Algunos bugs corregidos. A cambio hay 2 bugs relacionados que todav?a no han sido corregidos (ver PHPCollab) (los tiene asignados Jorge).
121
 *
122
 * Revision 1.8  2006/10/27 06:44:56  jorpiell
123
 * Se han cambiado algunas etiquetas de texto que sal?an recortadas
124
 *
125
 * Revision 1.7  2006/07/21 11:50:31  jaume
126
 * improved appearance
127
 *
128
 * Revision 1.6  2006/06/21 12:35:45  jorpiell
129
 * Se ha a?adido la ventana de propiedades. Esto implica a?adir listeners por todos los paneles. Adem?s no se muestra la geomatr?a en la lista de atributos y se muestran ?nicamnete los que se van a descargar
130
 *
131
 * Revision 1.5  2006/05/25 10:31:06  jorpiell
132
 * Como ha cambiado la forma de mostrar las capas (una tabla, en lugar de una lista), los paneles han tenido que ser modificados
133
 *
134
 * Revision 1.4  2006/05/23 08:09:39  jorpiell
135
 * Se ha cambiado la forma en la que se leian los valores seleccionados en los paneles y se ha cambiado el comportamiento de los botones
136
 *
137
 * Revision 1.3  2006/05/19 12:57:08  jorpiell
138
 * Modificados algunos paneles
139
 *
140
 * Revision 1.2  2006/04/20 16:38:24  jorpiell
141
 * Ahora mismo ya se puede hacer un getCapabilities y un getDescribeType de la capa seleccionada para ver los atributos a dibujar. Queda implementar el panel de opciones y hacer el getFeature().
142
 *
143
 *
144
 */
145

    
146

    
147
/**
148
 * <p>Panel where user can select a feature type to load as a WFS layer.</p>
149
 * 
150
 * @author Jorge Piera Llodr? (piera_jor@gva.es)
151
 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
152
 */
153
public class WFSSelectFeaturePanel extends AbstractWFSPanel {
154
        private static final long serialVersionUID = -3781080396069038450L;
155
        private JPanel featureListPanel = null;
156
        private JScrollPane jScrollPane = null;
157
        private LayerTable lstFeatures = null;
158
        private JTextField txtName = null;
159
        private JCheckBox chkExtendedNames = null;
160
        private JPanel layerNamePanel = null;
161
        private WFSSelectedFeature layerNode = null;
162
        private ListSelectionListener listSelectionListener = null;
163

    
164
        /**
165
         * Creates a new WFS select feature panel.
166
         */
167
        public WFSSelectFeaturePanel() {
168
                super();
169
                initialize();
170
        }
171

    
172
        /**
173
         * This method initializes coveragesListPanel
174
         *
175
         * @return javax.swing.JPanel
176
         */
177
        private JPanel getFeaturesListPanel() {
178
                if (featureListPanel == null) {
179
                        java.awt.GridBagConstraints gridBagConstraints;
180
                        featureListPanel = new JPanel();
181
                        featureListPanel.setLayout(new java.awt.GridBagLayout());
182
                        featureListPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
183
                                        null, PluginServices.getText(this, "select_features"),
184
                                        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
185
                                        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
186

    
187
                        gridBagConstraints = new java.awt.GridBagConstraints();
188
                        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
189
                        gridBagConstraints.weightx = 1.0;
190
                        gridBagConstraints.weighty = 1.0;
191
                        featureListPanel.add(getJScrollPane(), gridBagConstraints);
192
                }
193

    
194
                return featureListPanel;
195
        }
196

    
197
        /**
198
         * This method initializes jScrollPane
199
         *
200
         * @return javax.swing.JScrollPane
201
         */
202
        private JScrollPane getJScrollPane() {
203
                if (jScrollPane == null) {
204
                        jScrollPane = new JScrollPane();                
205
                        jScrollPane.setViewportView(getLstFeatures());
206
                        jScrollPane.setToolTipText(PluginServices.getText(jScrollPane, "feature_Selection_Info"));
207
                }
208

    
209
                return jScrollPane;
210
        }
211

    
212
        /**
213
         * This method initializes lstFeatures
214
         *
215
         * @return javax.swing.LayerTable
216
         */
217
        public LayerTable getLstFeatures() {
218
                if (lstFeatures == null) {
219
                        lstFeatures = new LayerTable();
220
                        lstFeatures.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
221
                        lstFeatures.getSelectionModel().addListSelectionListener(getListSelectionListener());
222
                        lstFeatures.setToolTipText(PluginServices.getText(lstFeatures, "feature_Selection_Info"));
223

    
224
                        // Double-click -> click the 'Next' button
225
                        lstFeatures.addMouseListener(new MouseAdapter() {
226
                                /*
227
                                 *  (non-Javadoc)
228
                                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
229
                                 */
230
                                public void mouseClicked(MouseEvent e) {
231
                                        if (e.getClickCount() == 2) {
232
                                                Object obj = getPanelGroup();
233

    
234
                                                if ((obj != null) && (obj instanceof WFSParamsPanel))
235
                                                        ((WFSParamsPanel)obj).doClickOnNextButton();
236
                                        }
237
                                }                        
238
                        });
239
                }
240

    
241
                return lstFeatures;
242
        }
243

    
244
        /**
245
         * Creates the list selection listener for the layers list
246
         * 
247
         * @return the listener
248
         */
249
        private ListSelectionListener getListSelectionListener(){
250
                if (listSelectionListener == null){
251
                        listSelectionListener = new ListSelectionListener(){
252
                                public void valueChanged(javax.swing.event.ListSelectionEvent e) {
253
                                        DefaultListSelectionModel model = (DefaultListSelectionModel) e.getSource();
254
                                        LayerTableModel t_model = ((LayerTableModel)lstFeatures.getModel());
255
                                        if (t_model.isUpdatingSelection())
256
                                                return;
257

    
258
                                        // With this condition we force to execute the updating only when a row has been selected by the user
259
                                        if ((model.getMinSelectionIndex() > -1) && (e.getValueIsAdjusting() == false)) {
260
                                                // Indicate that now we are loading a new layer
261
                                                IPanelGroup panelGroup = getPanelGroup();
262

    
263
                                                if (panelGroup == null)
264
                                                        return;
265

    
266
                                                if (((WFSParamsPanel)panelGroup).getFilterPanel() == null)
267
                                                        return;
268

    
269
                                                ((WFSParamsPanel)panelGroup).getFilterPanel().setWFSFilterPanelIsAsTabForWFSLayersLoad(true);
270

    
271
                                                refreshData();
272
                                        }
273
                                }
274
                        };        
275
                }
276

    
277
                return listSelectionListener;
278
        }
279

    
280
        /**
281
         * This method initializes jTextField
282
         *
283
         * @return javax.swing.JTextField
284
         */
285
        public JTextField getTxtName() {
286
                if (txtName == null) {
287
                        txtName = new JTextField();
288
                        txtName.setBounds(6, 19, 472, 20);
289
                        txtName.setText(PluginServices.getText(this, "WFSLayer"));
290
                        txtName.setEditable(false);
291
                        txtName.setBackground(Color.WHITE);
292
                        txtName.setToolTipText(PluginServices.getText(txtName, "feature_to_load"));
293

    
294
                        txtName.getDocument().addDocumentListener(new DocumentListener() {
295
                                /*
296
                                 * (non-Javadoc)
297
                                 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
298
                                 */
299
                                public void changedUpdate(DocumentEvent e) {
300
                                }
301

    
302
                                /*
303
                                 * (non-Javadoc)
304
                                 * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
305
                                 */
306
                                public void insertUpdate(DocumentEvent e) {
307
                                        IPanelGroup panelGroup = getPanelGroup();
308

    
309
                                        if (panelGroup == null)
310
                                                return;
311

    
312
                                        ((WFSParamsPanel)panelGroup).setApplicable(true);
313
                                }
314

    
315
                                /*
316
                                 * (non-Javadoc)
317
                                 * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
318
                                 */
319
                                public void removeUpdate(DocumentEvent e) {
320
                                }
321
                        });
322
                }
323

    
324
                return txtName;
325
        }
326

    
327
        /**
328
         * This method initializes chkExtendedNames
329
         *
330
         * @return javax.swing.JCheckBox
331
         */
332
        private JCheckBox getChkExtendedNames() {
333
                if (chkExtendedNames == null) {
334
                        chkExtendedNames = new JCheckBox();
335
                        chkExtendedNames.setText(PluginServices.getText(this, "show_layer_names"));
336
                        chkExtendedNames.setBounds(10, 372, 382, 20);
337
                        chkExtendedNames.addItemListener(new java.awt.event.ItemListener() {
338
                                /*
339
                                 * (non-Javadoc)
340
                                 * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)
341
                                 */
342
                                public void itemStateChanged(java.awt.event.ItemEvent e) {
343
                                        boolean b = chkExtendedNames.isSelected();
344
                                        getLstFeatures().setShowLayerNames(b);
345
                                        getLstFeatures().repaint();
346
                                }
347
                        });
348
                }
349

    
350
                return chkExtendedNames;
351
        }
352

    
353
        /**
354
         * Set the selected layer node
355
         * 
356
         * @param layerNode the layer to select
357
         */
358
        public void setSelectedFeature(WFSSelectedFeature layerNode){
359
                int index = -1;
360

    
361
                for (int i=0; i<getLstFeatures().getRowCount(); i++){
362
                        WFSSelectedFeature node = (WFSSelectedFeature)getLstFeatures().getValueAt(i);
363

    
364
                        if (node != null && layerNode.getName().equals(node.getName())){
365
                                index = i;
366
                        }
367
                }
368

    
369
                if (index != -1){
370
                        getLstFeatures().changeSelection(index, 0, false, false);
371
                }
372
        }
373

    
374
        /**
375
         * Refresh the features list
376
         */
377
        public void refresh(WFSSelectedFeature layer) {
378
                // Unselects all features
379
                unselectAllFeatures();
380

    
381
                // Add the new features
382
                getLstFeatures().addFeatures(getSelectedFeatureManager().getLayerList());
383

    
384
                if (layer != null) {
385
                        layerNode = layer;
386
                        setLayerName(layer.getName());
387
                        setSelectedFeature(layer);                        
388
                }                
389
        }
390

    
391
        /**
392
         * Refreshes the wizard components data each time a feature
393
         * is selected. The <i>describeFeatureType</i> operation must be sent.
394
         */
395
        public void refreshData() {
396
                WFSSelectedFeature lyr = (WFSSelectedFeature)getLstFeatures().getSelectedValue();
397

    
398
                try {
399
                        getTxtName().setText(lyr.getTitle());
400
                } catch (NullPointerException e){
401
                        getTxtName().setText(PluginServices.getText(this,"default_name"));
402
                        NotificationManager.addError(PluginServices.getText(this,"default_name"), e);
403
                }
404

    
405
                IPanelGroup panelGroup = getPanelGroup();
406

    
407
                if (panelGroup == null)
408
                        return;
409

    
410
                ((WFSParamsPanel)panelGroup).refresh(lyr);
411

    
412
                repaint();
413
        }
414

    
415
        /**
416
         * This method initializes layerNamePanel
417
         *
418
         * @return javax.swing.JPanel
419
         */
420
        private JPanel getLayerNamePanel() {
421
                if (layerNamePanel == null) {
422
                        java.awt.GridBagConstraints gridBagConstraints;
423
                        layerNamePanel = new JPanel();
424
                        layerNamePanel.setLayout(new java.awt.GridBagLayout());
425
                        layerNamePanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
426
                                        null, PluginServices.getText(this, "layer_name"),
427
                                        javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
428
                                        javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));                        
429
                        gridBagConstraints = new java.awt.GridBagConstraints();
430
                        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
431
                        gridBagConstraints.weightx = 1.0;
432
                        layerNamePanel.add(getTxtName(), gridBagConstraints);
433
                }
434

    
435
                return layerNamePanel;
436
        }
437

    
438
        /**
439
         * Gets the name of the layer (feature) selected.
440
         *
441
         * @return the layer name
442
         */
443
        public String getLayerName() {
444
                if ((WFSSelectedFeature)getLstFeatures().getSelectedValue() != null){
445
                        return ((WFSSelectedFeature)getLstFeatures().getSelectedValue()).getName();
446
                }
447
                return "";
448
        }
449

    
450
        /**
451
         * Gets the name space of the layer (feature) selected.
452
         *
453
         * @return the name space
454
         */
455
        public String getLayerNameSpace(){
456
                return ((WFSSelectedFeature)getLstFeatures().getSelectedValue()).getNameSpace();
457
        }
458

    
459
        /**
460
         * Gets the selected feature.
461
         * 
462
         * @return the selected feature
463
         */
464
        public WFSSelectedFeature getSelectedFeature() {
465
                WFSSelectedFeature selectedFeature = (WFSSelectedFeature)getLstFeatures().getSelectedValue();
466

    
467
                if (selectedFeature != null) {
468
                        layerNode = selectedFeature;
469
                }
470

    
471
                return layerNode;
472
        }
473

    
474
        /**
475
         * Sets the name of the feature selected.
476
         * 
477
         * @param name the name of the feature selected
478
         */
479
        public void setLayerName(String name) {
480
                getTxtName().setText(name);
481
        }
482

    
483
        /*
484
         * (non-Javadoc)
485
         * @see com.iver.cit.gvsig.gui.panels.AbstractWFSPanel#initialize()
486
         */
487
        protected void initialize() {
488
                setLabel(PluginServices.getText(this, "feature"));
489
                setLabelGroup(PluginServices.getText(this, "wfs"));
490
                java.awt.GridBagConstraints gridBagConstraints;
491
                this.setLayout(new java.awt.GridBagLayout());
492

    
493
                gridBagConstraints = new java.awt.GridBagConstraints();
494
                gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
495
                gridBagConstraints.weightx = 1.0;
496
                this.add(getLayerNamePanel(), gridBagConstraints);
497

    
498
                gridBagConstraints = new java.awt.GridBagConstraints();
499
                gridBagConstraints.gridx = 0;
500
                gridBagConstraints.gridy = 1;
501
                gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
502
                gridBagConstraints.weightx = 1.0;
503
                gridBagConstraints.weighty = 1.0;
504
                this.add(getFeaturesListPanel(), gridBagConstraints);
505

    
506
                gridBagConstraints = new java.awt.GridBagConstraints();
507
                gridBagConstraints.gridx = 0;
508
                gridBagConstraints.gridy = 2;
509
                gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
510
                gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
511
                gridBagConstraints.weightx = 1.0;
512
                this.add(getChkExtendedNames(), gridBagConstraints);                
513

    
514
        }
515

    
516
        /*
517
         * (non-Javadoc)
518
         * @see com.iver.cit.gvsig.gui.panels.AbstractWFSPanel#setReference(java.lang.Object)
519
         */
520
        public void setReference(Object ref) {
521
                super.setReference(ref);
522
                //                if (ref instanceof FLyrWFS){                        
523
                //                        getPanelGroup().setEnabledApplyButton(false);
524
                //                }                
525
        }        
526

    
527
        /**
528
         * Updates the list with no feature selected.
529
         */
530
        public void unselectAllFeatures() {
531
                // Reset the last row selection of the features table
532
                int numberOfFeatures = getLstFeatures().getRowCount();
533

    
534
                if (numberOfFeatures > 0) {                        
535
                        ListSelectionModel model = getLstFeatures().getSelectionModel();
536
                        model.removeSelectionInterval(0, numberOfFeatures - 1); // whatever row selection
537
                }
538
        }
539

    
540
        /**
541
         * Table with the information of all layers which could be selected from the server connected.
542
         * 
543
         * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es)
544
         * @author Jorge Piera Llodr? (piera_jor@gva.es)
545
         */
546
        public class LayerTable extends JTable {
547
                private static final long serialVersionUID = 4700375945858283696L;
548
                private int headerSelected = -1; 
549

    
550
                /**
551
                 * Creates a new instance of <code>LayerTable</code>
552
                 */
553
                public LayerTable() {
554
                        super();
555

    
556
                        setModel(new LayerTableModel());
557

    
558
                        getTableHeader().setUI(new BasicTableHeaderSelectableUI());
559

    
560
                        getTableHeader().addMouseListener(new MouseAdapter() {
561
                                /*
562
                                 * (non-Javadoc)
563
                                 * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
564
                                 */
565
                                public void mouseClicked(MouseEvent e) {
566
                                        // Sorts according the selected column
567
                                        ((LayerTableModel)getModel()).sort(getTableHeader().getColumnModel().getColumnIndexAtX(e.getX()));
568
                                }
569

    
570
                                /*
571
                                 * (non-Javadoc)
572
                                 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
573
                                 */
574
                                public void mousePressed(MouseEvent e) {
575
                                        headerSelected = getTableHeader().getColumnModel().getColumnIndexAtX(e.getX());
576
                                        getTableHeader().repaint();
577
                                }
578

    
579
                                /*
580
                                 * (non-Javadoc)
581
                                 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
582
                                 */
583
                                public void mouseReleased(MouseEvent e) {
584
                                        headerSelected = -1;
585
                                }
586
                        });
587
                }
588

    
589
                /*
590
                 * (non-Javadoc)
591
                 * @see javax.swing.JTable#createDefaultColumnsFromModel()
592
                 */
593
                public void createDefaultColumnsFromModel() {
594
                        TableModel m = getModel();
595
                        if (m != null) {
596
                                // Remove any current columns
597
                                TableColumnModel cm = getColumnModel();
598
                                while (cm.getColumnCount() > 0) {
599
                                        cm.removeColumn(cm.getColumn(0));
600
                                }
601

    
602
                                // Create new columns from the data model info
603
                                for (int i = 0; i < m.getColumnCount(); i++) {
604
                                        TableColumn newColumn = new TableColumn(i);
605

    
606
                                        // Special renderer for supporting selection of a particular column header
607
                                        newColumn.setHeaderRenderer(new DefaultTableSelectableCellRenderer());
608
                                        addColumn(newColumn);
609
                                }
610
                        }
611
                }
612

    
613
                /**
614
                 * Gets the selected <i>WFS</i> layer.
615
                 * 
616
                 * @return node of the selected <i>WFS</i> layer
617
                 */
618
                public WFSSelectedFeature getSelectedValue() {
619
                        int selectedRow = getSelectedRow();
620
                        LayerTableModel model = (LayerTableModel)getModel();
621

    
622
                        return model.getLayerAt(selectedRow);
623
                }
624

    
625
                /**
626
                 * Gets the layer at a row position.
627
                 * 
628
                 * @return node of the selected <i>WFS</i> layer
629
                 */
630
                public WFSSelectedFeature getValueAt(int position) {
631
                        if (position < this.getRowCount()) {
632
                                LayerTableModel model = (LayerTableModel)getModel();
633

    
634
                                return model.getLayerAt(position);                        
635
                        }
636

    
637
                        return null;
638
                }
639

    
640
                /**
641
                 * Adds the available features to load as a <i>WFS</i> layer.
642
                 * 
643
                 * @param features available features
644
                 */
645
                public void addFeatures(WFSSelectedFeature[] features) {
646
                        LayerTableModel model = (LayerTableModel)getModel();
647
                        model.deleteAllRows();
648

    
649
                        for (int i=0 ; i < features.length ; i++){
650
                                model.addRow(features[i]);                        
651
                        }        
652
                }        
653

    
654
                /**
655
                 * Shows the names of the features.
656
                 * 
657
                 * @param showFeatureNameType The showLayerNames to set.
658
                 */
659
                public void setShowLayerNames(boolean showFeatureNameType) {
660
                        LayerTableModel model = (LayerTableModel)getModel();
661
                        model.setShowedFeatureNameType(showFeatureNameType);
662
                }
663

    
664
                /**
665
                 * Model of the <code>LayerTable</code> that stores the features available to load as a WFS layer.
666
                 * 
667
                 * @author Jorge Piera Llodr? (piera_jor@gva.es)
668
                 * @author Pablo Piqueras Bartolome (pablo.piqueras@iver.es)
669
                 */
670
                public class LayerTableModel extends AbstractTableModel {  
671
                        private static final long serialVersionUID = 2722138264867593508L;
672
                        private Vector<WFSSelectedFeature> layers = new Vector<WFSSelectedFeature>();
673
                        private boolean showFeatureNameType = false;
674
                        private WFSLayerStringComparator stringComparator;
675
                        private boolean updatingSelection;
676
                        private short previousColumnSorted;
677

    
678

    
679
                        /**
680
                         * Constructs an investment table model.
681
                         */
682
                        public LayerTableModel(){  
683
                                super();
684

    
685
                                // Alphabetical sort ordering support
686
                                updatingSelection = false;
687
                                previousColumnSorted = -1;
688
                                Collator collator = Collator.getInstance(new Locale("en_EN"));                
689
                                stringComparator = new WFSLayerStringComparator();
690
                                stringComparator.setLocaleRules(stringComparator.new LocaleRules(true, collator));
691
                                stringComparator.setCaseSensitive(false);
692
                                stringComparator.setAscendingOrdering(true);
693
                        }
694

    
695

    
696
                        /*
697
                         *  (non-Javadoc)
698
                         * @see javax.swing.table.TableModel#getRowCount()
699
                         */
700
                        public int getRowCount(){  
701
                                return layers.size();                
702
                        }
703

    
704
                        /*
705
                         *  (non-Javadoc)
706
                         * @see javax.swing.table.TableModel#getColumnCount()
707
                         */
708
                        public int getColumnCount(){  
709
                                return 2;
710
                        }
711

    
712
                        /*
713
                         *  (non-Javadoc)
714
                         * @see javax.swing.table.TableModel#getValueAt(int, int)
715
                         */
716
                        public Object getValueAt(int rowNumber, int columnNumber){  
717
                                if (rowNumber < layers.size()) {
718
                                        WFSSelectedFeature layer = (WFSSelectedFeature)layers.get(rowNumber);
719

    
720
                                        if (columnNumber == 0) {
721
                                                return getLayerName(layer);
722
                                        } else {
723
                                            if (layer.getGeometryField() != null){
724
                                                return PluginServices.getText(this, layer.getGeometryField().getDataType().getName());
725
                                            }
726
                                                return "";
727
                                        }
728
                                } else {
729
                                        return "";
730
                                }
731
                        }        
732

    
733
                        /**
734
                         * Gets the layer name displaying the type name of the feature collection associated if it's needed.
735
                         * 
736
                         * @param layer a <i>WFS</i> layer 
737
                         * @return the layer name
738
                         */
739
                        private String getLayerName(WFSSelectedFeature layer){
740
                                if (showFeatureNameType){
741
                                        return "[" + layer.getName() + "] " + layer.getTitle(); 
742
                                } else {
743
                                        return layer.getTitle();
744
                                }
745
                        }
746

    
747
                        /**
748
                         * Gets the layer at the specified position.
749
                         * 
750
                         * @param rowNumber row position
751
                         * @return <i>WFS</i> layer node
752
                         */
753
                        public WFSSelectedFeature getLayerAt(int rowNumber){
754
                                try {
755
                                        if (rowNumber == -1)
756
                                                return null;
757

    
758
                                        return (WFSSelectedFeature)layers.get(rowNumber);
759
                                } catch (ArrayIndexOutOfBoundsException e) {
760
                                        NotificationManager.addError(e);
761
                                        return null;
762
                                }
763
                        }        
764

    
765
                        /**
766
                         * Adds a new layer to the table model, each table will be represented as a row.
767
                         *  
768
                         * @param layer a new <i>WFS</i> layer
769
                         */
770
                        public void addRow(WFSSelectedFeature layer){
771
                                layers.add(layer);
772
                                fireTableRowsInserted(getRowCount(), getRowCount());
773
                                fireTableRowsUpdated(0,getRowCount());
774
                        }
775

    
776
                        /**
777
                         * Deletes all the table rows.
778
                         */
779
                        public void deleteAllRows(){
780
                                layers.clear();
781
                                int rows = getRowCount();
782

    
783
                                if (rows >= 1){
784
                                        fireTableRowsDeleted(0, rows - 1);
785
                                }                
786
                        }        
787

    
788
                        /**
789
                         * Delete all the table rows
790
                         */
791
                        public void deleteRow(int rowPosition){
792
                                layers.remove(rowPosition);
793
                                fireTableRowsDeleted(rowPosition, rowPosition);
794
                                fireTableRowsUpdated(0,getRowCount());
795
                        }        
796

    
797
                        /*
798
                         *  (non-Javadoc)
799
                         * @see javax.swing.table.TableModel#getColumnName(int)
800
                         */
801
                        public String getColumnName(int columnIndex){
802
                                if (columnIndex == 0){
803
                                        return PluginServices.getText(this, "layerName");
804
                                }else{
805
                                        return PluginServices.getText(this, "layerType");
806
                                }
807
                        }
808

    
809
                        /**
810
                         * Gets if shows the feature name type.
811
                         * 
812
                         * @return <code>true</code> if shows the feature name type; <code>false</code> otherwise
813
                         */
814
                        public boolean isShowedFeatureNameType() {
815
                                return showFeatureNameType;
816
                        }
817

    
818
                        /**
819
                         * Gets if shows the feature name type.
820
                         * 
821
                         * @param showFeatureNameType <code>true</code> if shows the feature name type; <code>false</code> otherwise
822
                         */
823
                        public void setShowedFeatureNameType(boolean showFeatureNameType) {
824
                                this.showFeatureNameType = showFeatureNameType;
825

    
826
                                this.stringComparator.setShowFeatureNameType(showFeatureNameType);
827
                        }
828

    
829
                        /**
830
                         * Sorts the rows of the table alphabetically.
831
                         * 
832
                         * @param column index of the column to sort. In this table there are only 2 columns.
833
                         */
834
                        public void sort(int column) {
835
                                // Orders the layer alphabetically according the Spanish alphabetically rules 
836
                                switch(column) {
837
                                case 0:
838
                                        stringComparator.setColumn(WFSLayerStringComparator.LAYER_NAME);
839
                                        break;
840
                                case 1:
841
                                        stringComparator.setColumn(WFSLayerStringComparator.GEOMETRY_TYPE);
842
                                        break;
843
                                }
844

    
845
                                if (previousColumnSorted != column)
846
                                        stringComparator.setAscendingOrdering(true);
847

    
848
                                previousColumnSorted = (short) column;
849

    
850
                                WFSSelectedFeature layer = getSelectedValue();
851

    
852
                                Collections.sort(layers, stringComparator);
853

    
854
                                if (layer != null) {
855
                                        updatingSelection = true;
856
                                        unselectAllFeatures();
857
                                        int row = Collections.binarySearch(layers, layer, stringComparator);
858

    
859
                                        if (row != -1) {
860
                                                ListSelectionModel model = getSelectionModel();
861
                                                model.setLeadSelectionIndex(row);
862
                                        }
863

    
864
                                        updatingSelection = false;
865
                                }
866
                                stringComparator.setAscendingOrdering(!stringComparator.isAscendingOrdering());
867
                        }
868

    
869
                        /**
870
                         * Determines if now is updating the selection of the previous selected item.
871
                         * 
872
                         * @return <code>true</code> if now is updating the selection of the previous selected item; otherwise <code>false</code>
873
                         */
874
                        public boolean isUpdatingSelection() {
875
                                return updatingSelection;
876
                        }
877
                }
878

    
879
                /**
880
                 * <p>Enhances {@link BasicTableHeaderUI BasicTableHeaderUI} adding support for column head selection.</p>
881
                 * 
882
                 * @see BasicTableHeaderUI
883
                 *
884
                 * @version 29/01/2008
885
                 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es) 
886
                 */
887
                private class BasicTableHeaderSelectableUI extends BasicTableHeaderUI {
888
                        /**
889
                         * Creates a new BasicTableHeaderSelectableUI object
890
                         */
891
                        public BasicTableHeaderSelectableUI() {
892
                                super();
893
                        }
894

    
895
                        //
896
                        // Some Paint Methods and support re-implemented
897
                        //
898

    
899
                        /*
900
                         * (non-Javadoc)
901
                         * @see javax.swing.plaf.basic.BasicTableHeaderUI#paint(java.awt.Graphics, javax.swing.JComponent)
902
                         */
903
                        public void paint(Graphics g, JComponent c) {
904
                                if (header.getColumnModel().getColumnCount() <= 0) { 
905
                                        return; 
906
                                }
907

    
908
                                boolean ltr = header.getComponentOrientation().isLeftToRight();
909

    
910
                                Rectangle clip = g.getClipBounds(); 
911
                                Point left = clip.getLocation();
912
                                Point right = new Point( clip.x + clip.width - 1, clip.y );
913
                                TableColumnModel cm = header.getColumnModel(); 
914
                                int cMin = header.columnAtPoint( ltr ? left : right );
915
                                int cMax = header.columnAtPoint( ltr ? right : left );
916
                                // This should never happen. 
917
                                if (cMin == -1) {
918
                                        cMin =  0;
919
                                }
920
                                // If the table does not have enough columns to fill the view we'll get -1.
921
                                // Replace this with the index of the last column.
922
                                if (cMax == -1) {
923
                                        cMax = cm.getColumnCount()-1;  
924
                                }
925

    
926
                                TableColumn draggedColumn = header.getDraggedColumn(); 
927
                                int columnWidth;
928
                                Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); 
929
                                TableColumn aColumn;
930
                                if (ltr) {
931
                                        for(int column = cMin; column <= cMax ; column++) { 
932
                                                aColumn = cm.getColumn(column); 
933
                                                columnWidth = aColumn.getWidth();
934
                                                cellRect.width = columnWidth;
935
                                                if (aColumn != draggedColumn) {
936
                                                        paintCell(g, cellRect, column);
937
                                                } 
938
                                                cellRect.x += columnWidth;
939
                                        }
940
                                } else {
941
                                        for(int column = cMax; column >= cMin; column--) {
942
                                                aColumn = cm.getColumn(column);
943
                                                columnWidth = aColumn.getWidth();
944
                                                cellRect.width = columnWidth;
945
                                                if (aColumn != draggedColumn) {
946
                                                        paintCell(g, cellRect, column);
947
                                                }
948
                                                cellRect.x += columnWidth;
949
                                        }
950
                                } 
951

    
952
                                // Paint the dragged column if we are dragging. 
953
                                if (draggedColumn != null) { 
954
                                        int draggedColumnIndex = viewIndexForColumn(draggedColumn); 
955
                                        Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); 
956

    
957
                                        // Draw a gray well in place of the moving column. 
958
                                        g.setColor(header.getParent().getBackground());
959
                                        g.fillRect(draggedCellRect.x, draggedCellRect.y,
960
                                                        draggedCellRect.width, draggedCellRect.height);
961

    
962
                                        draggedCellRect.x += header.getDraggedDistance();
963

    
964
                                        // Fill the background. 
965
                                        g.setColor(header.getBackground());
966
                                        g.fillRect(draggedCellRect.x, draggedCellRect.y,
967
                                                        draggedCellRect.width, draggedCellRect.height);
968

    
969
                                        paintCell(g, draggedCellRect, draggedColumnIndex);
970
                                }
971

    
972
                                // Remove all components in the rendererPane. 
973
                                rendererPane.removeAll(); 
974
                        }
975

    
976
                        private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
977
                                Component component = getHeaderRenderer(columnIndex); 
978
                                rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
979
                                                cellRect.width, cellRect.height, true);
980
                        }
981

    
982
                        private Component getHeaderRenderer(int columnIndex) { 
983
                                TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); 
984
                                TableCellRenderer renderer = aColumn.getHeaderRenderer();
985

    
986
                                if (renderer == null) { 
987
                                        renderer = header.getDefaultRenderer(); 
988
                                }
989

    
990
                                if (headerSelected == columnIndex) {
991
                                        headerSelected = -1;
992
                                        return renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), true, false, -1, columnIndex);
993
                                }
994
                                else {
995
                                        return renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), false, false, -1, columnIndex);
996
                                }
997
                        }
998

    
999
                        private int viewIndexForColumn(TableColumn aColumn) {
1000
                                TableColumnModel cm = header.getColumnModel();
1001

    
1002
                                for (int column = 0; column < cm.getColumnCount(); column++) {
1003
                                        if (cm.getColumn(column) == aColumn) {
1004
                                                return column;
1005
                                        }
1006
                                }
1007

    
1008
                                return -1;
1009
                        }
1010
                }
1011

    
1012
                /**
1013
                 * <p>Simulates the selection / unselection of the head of the column clicked.</p>
1014
                 * 
1015
                 * @version 29/01/2008
1016
                 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es) 
1017
                 */
1018
                private class DefaultTableSelectableCellRenderer extends DefaultTableCellRenderer {
1019
                        private static final long serialVersionUID = -3896516869747447668L;
1020

    
1021
                        /*
1022
                         * (non-Javadoc)
1023
                         * @see javax.swing.table.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
1024
                         */
1025
                        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
1026
                                Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
1027

    
1028
                                Color bgColor = getTableHeader().getBackground();
1029

    
1030
                                if (isSelected)
1031
                                        comp.setBackground(new Color(bgColor.getRed() - 10 , bgColor.getGreen() - 10, bgColor.getBlue() - 10));
1032
                                else
1033
                                        comp.setBackground(bgColor);
1034

    
1035
                                ((JLabel)comp).setText((value == null) ? "" : value.toString());
1036
                                ((JLabel)comp).setBorder(UIManager.getBorder("TableHeader.cellBorder"));
1037

    
1038
                                return comp;
1039
                        }
1040
                }
1041

    
1042
                /**
1043
                 * Compares two chain of characters alphabetically, bearing in mind the information of a WFS layer.
1044
                 * 
1045
                 * @version 24/01/2008
1046
                 * @author Pablo Piqueras Bartolom? (pablo.piqueras@iver.es) 
1047
                 */
1048
                private class WFSLayerStringComparator extends StringComparator {
1049
                        public static final short LAYER_NAME = 0;
1050
                        public static final short GEOMETRY_TYPE = 1;
1051

    
1052
                        protected short column = LAYER_NAME; // by default the first column
1053
                        protected boolean showFeatureNameType = false; // by default doesn't shows the feature name type
1054
                        protected boolean ascendingOrdering = true; // by default: ascending ordering
1055

    
1056
                        /*
1057
                         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
1058
                         */
1059
                        public int compare(Object o1, Object o2) {
1060
                                String s1 = null, s2 = null;
1061

    
1062
                                switch(column) {
1063
                                case LAYER_NAME:
1064
                                        if (ascendingOrdering) {
1065
                                                s1 = o1.toString();
1066
                                                s2 = o2.toString();
1067
                                        }
1068
                                        else {
1069
                                                s1 = o2.toString();
1070
                                                s2 = o1.toString();
1071
                                        }
1072

    
1073
                                        if (showFeatureNameType) {
1074
                                                if (ascendingOrdering) {
1075
                                                        return super.compare(o1, o2);
1076
                                                }
1077
                                                else {
1078
                                                        return super.compare(o2, o1);
1079
                                                }
1080
                                        }
1081

    
1082
                                        // Only if "showFeatureNameType == true" :
1083
                                        int index = s1.indexOf(']');
1084

    
1085
                                        if (index > 0)
1086
                                                s1 = s1.substring(index, s1.length()).trim();
1087
                                        else
1088
                                                s1 = s1.trim();
1089

    
1090
                                        index = s2.indexOf(']');
1091

    
1092
                                        if (index > 0)
1093
                                                s2 = s2.substring(index, s2.length()).trim();
1094
                                        else
1095
                                                s2 = s2.trim();
1096

    
1097
                                        break;
1098
                                case GEOMETRY_TYPE:
1099
                                        WFSFeatureField gType = ((WFSSelectedFeature)o1).getGeometryField();
1100

    
1101
                                        if (gType == null)
1102
                                                s1 = "";
1103
                                        else
1104
                                                s1 = gType.getName();
1105

    
1106
                                        gType = ((WFSSelectedFeature)o2).getGeometryField();
1107

    
1108
                                        if (gType == null)
1109
                                                s2 = "";
1110
                                        else
1111
                                                s2 = gType.getName();
1112

    
1113
                                        if (ascendingOrdering)
1114
                                                return super.compare(s1, s2);
1115
                                        else
1116
                                                return super.compare(s2, s1);
1117
                                default:
1118
                                        return 0;
1119
                                }
1120

    
1121
                                // If localeRules is null -> use the default rules
1122
                                if (getLocaleRules() == null) {
1123
                                        if (isCaseSensitive()) {
1124
                                                return s1.compareTo(s2);
1125
                                        }
1126
                                        else {
1127
                                                return s1.compareToIgnoreCase(s2);
1128
                                        }
1129
                                }
1130
                                else {
1131
                                        if (getLocaleRules().isUseLocaleRules()) {
1132
                                                Collator collator = getLocaleRules().getCollator();
1133

    
1134
                                                if (isCaseSensitive()) {
1135
                                                        return collator.compare(s1, s2);
1136
                                                }
1137
                                                else {
1138
                                                        //return collator.compare(s1.toLowerCase(), s2.toLowerCase());
1139
                                                        return collator.compare(s1.toUpperCase(), s2.toUpperCase());
1140
                                                }
1141
                                        }
1142
                                        else {
1143
                                                if (isCaseSensitive()) {
1144
                                                        return s1.compareTo(s2);
1145
                                                }
1146
                                                else {
1147
                                                        return s1.compareToIgnoreCase(s2);
1148
                                                }
1149
                                        }
1150
                                }
1151
                        }
1152

    
1153
                        /**
1154
                         * Determines if the name of each element includes the type name.
1155
                         * 
1156
                         * @return <code>true</code> if the name of each element includes the type name; otherwise <code>false</code>
1157
                         */
1158
                        public boolean isShowFeatureNameType() {
1159
                                return showFeatureNameType;
1160
                        }
1161

    
1162
                        /**
1163
                         * Sets if the name of each element includes the type name.
1164
                         * 
1165
                         * @param showFeatureNameType <code>true</code> if the name of each element includes the type name; otherwise <code>false</code>
1166
                         */
1167
                        public void setShowFeatureNameType(boolean showFeatureNameType) {
1168
                                this.showFeatureNameType = showFeatureNameType;
1169
                        }
1170

    
1171
                        /**
1172
                         * <p>Sets which column well be alphabetically sort ordered.</p>
1173
                         * 
1174
                         * <p>There are two columns:
1175
                         *  <ul>
1176
                         *   <li><i>LAYER_NAME</i>: name of the layer.</li>
1177
                         *   <li><i>GEOMETRY_TYPE</i>: geometry type that layer is.</li>
1178
                         *  </ul>
1179
                         * </p>
1180
                         * 
1181
                         * @param column
1182
                         */
1183
                        public void setColumn(short column) {
1184
                                this.column = column;
1185
                        }
1186

    
1187
                        /**
1188
                         * <p>Sets if the alphabetical sort will be ascending or descending.</p>
1189
                         * 
1190
                         * @param b <code>true</code> if the alphabetical sort will be ascending, <code>false</code> if descending
1191
                         */
1192
                        public void setAscendingOrdering(boolean b) {
1193
                                ascendingOrdering = b;
1194
                        }
1195

    
1196
                        /**
1197
                         * <p>Determines if the alphabetical sort will be ascending or descending.</p>
1198
                         * 
1199
                         * @param b <code>true</code> if the alphabetical sort will be ascending, <code>false</code> if descending
1200
                         */
1201
                        public boolean isAscendingOrdering() {
1202
                                return ascendingOrdering;
1203
                        }
1204
                }
1205
        }
1206
}