Statistics
| Revision:

svn-gvsig-desktop / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / gui / LegendManager.java @ 18883

History | View | Annotate | Download (26.1 KB)

1
/*
2
 * Created on 08-feb-2005
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.project.documents.view.legend.gui;
45

    
46
import java.awt.BorderLayout;
47
import java.awt.Color;
48
import java.awt.Component;
49
import java.awt.Dimension;
50
import java.awt.FlowLayout;
51
import java.awt.event.ActionListener;
52
import java.io.File;
53
import java.util.ArrayList;
54
import java.util.Enumeration;
55
import java.util.Hashtable;
56
import java.util.prefs.Preferences;
57

    
58
import javax.swing.ImageIcon;
59
import javax.swing.JCheckBox;
60
import javax.swing.JComboBox;
61
import javax.swing.JComponent;
62
import javax.swing.JFileChooser;
63
import javax.swing.JLabel;
64
import javax.swing.JOptionPane;
65
import javax.swing.JPanel;
66
import javax.swing.JScrollPane;
67
import javax.swing.JSplitPane;
68
import javax.swing.JTextArea;
69
import javax.swing.JTree;
70
import javax.swing.tree.DefaultMutableTreeNode;
71
import javax.swing.tree.DefaultTreeCellRenderer;
72
import javax.swing.tree.DefaultTreeModel;
73
import javax.swing.tree.TreePath;
74
import javax.swing.tree.TreeSelectionModel;
75

    
76
import org.gvsig.gui.beans.swing.JButton;
77

    
78
import com.iver.andami.PluginServices;
79
import com.iver.andami.messages.NotificationManager;
80
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
81
import com.iver.cit.gvsig.fmap.drivers.legend.IFMapLegendDriver;
82
import com.iver.cit.gvsig.fmap.drivers.legend.LegendDriverException;
83
import com.iver.cit.gvsig.fmap.layers.FLayer;
84
import com.iver.cit.gvsig.fmap.layers.FLayers;
85
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
86
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
87
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
88
import com.iver.cit.gvsig.fmap.rendering.IClassifiedVectorLegend;
89
import com.iver.cit.gvsig.fmap.rendering.ILegend;
90
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
91
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
92
/**
93
 * Implements the panel which allows the user to control all the information about the
94
 * legends of a layer in order to improve the information that it offers to the user.
95
 * There are options to create, save or load an existing legend.
96
 *
97
 * @author jaume dominguez faus - jaume.dominguez@iver.es
98
 * @param <FMapSLDDriver>
99
 */
100
public class LegendManager extends AbstractThemeManagerPage {
101
        @SuppressWarnings("unchecked")
102
        private static ArrayList legendPool = new ArrayList();
103
        @SuppressWarnings("unchecked")
104
        private static ArrayList legendDriverPool = new ArrayList();
105

    
106
        private FLayer layer;
107
        private ILegend legend; // Le asignaremos la leyenda del primer tema activo.
108
        private Hashtable pages = new Hashtable();
109
        private JPanel topPanel = null;
110
        private JLabel jLabel = null;
111
        private JComboBox jComboBox = null;
112
        private JCheckBox jCheckBox = null;
113
        private JTextArea titleArea = null;
114
        private JPanel preview = null;
115
        private JScrollPane jTitleScrollPane = null;
116
        private JTree jTreeLegends;
117
        private ILegendPanel activePanel;
118
        private JScrollPane legendTreeScrollPane;
119
        private boolean dirtyTree;
120
        private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
121
        private DefaultTreeModel treeModel;
122
        private JScrollPane jPanelContainer;
123
        private JPanel jCentralPanel;
124
        private JSplitPane jSplitPane;
125
        private boolean isTreeListenerDisabled;
126
        private JButton btnSaveLegend;
127
        private JButton btnLoadLegend;
128
        private Hashtable<FLayer, ILegend> table = null;
129
        private boolean empty = true;
130
        public static String defaultLegendFolderPath;
131
        {
132

    
133
                Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
134
                defaultLegendFolderPath = prefs.get("LegendsFolder", "");
135
        }
136
        private ActionListener loadSaveLegendAction = new ActionListener() {
137
                public void actionPerformed(java.awt.event.ActionEvent e) {
138
                        JComponent c = (JComponent) e.getSource();
139
                        if (c.equals(getBtnSaveLegend())) {
140

    
141
                                JLegendFileChooser jfc = new JLegendFileChooser(getLegendDrivers(),true);
142
                                jfc.setAcceptAllFileFilterUsed(false);
143
                                
144
                                
145
                                File basedir = null;
146
                                Object[] options = {PluginServices.getText(this, "yes"),
147
                                                PluginServices.getText(this, "no"),
148
                                                PluginServices.getText(this, "Cancel")};
149

    
150
                                jfc.setCurrentDirectory(basedir);
151
                                if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
152

    
153
                                        File file=jfc.getSelectedFile();
154
                                        IFMapLegendDriver driver = jfc.getSuitableDriver();
155

    
156
                                        if (file.exists()) {
157
                                                int answer = JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
158
                                                                PluginServices.getText(this, "error_file_exists"),
159
                                                                PluginServices.getText(this, "confirmation_dialog"),
160
                                                                JOptionPane.YES_NO_CANCEL_OPTION,
161
                                                                JOptionPane.QUESTION_MESSAGE,
162
                                                                null,
163
                                                                options, options[1]);
164
                                                if (answer!=JOptionPane.OK_OPTION) {
165
                                                        // 'Cancel' pressed or window closed: don't save anythig, exit save dialog
166
                                                        return;
167
                                                }
168
                                        }
169

    
170

    
171
                                        try {
172
                                                driver.write(layer.getMapContext().getLayers(),layer, activePanel.getLegend(), file);
173

    
174
                                        } catch (LegendDriverException e1) {
175
                                                int type = e1.getType();
176
                                                String message="Imposible guardar la leyenda:\n";
177

    
178
                                                if ((type & LegendDriverException.SAVE_LEGEND_ERROR) != 0){
179
                                                        type = type & ~LegendDriverException.SAVE_LEGEND_ERROR;
180
                                                        message += PluginServices.getText(this, "Error guardando la leyenda.\n");
181
                                                }
182
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_CREATION) != 0){
183
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_CREATION;
184
                                                        message += PluginServices.getText(this, "-Soporte para creaci?n de este tipo de formato no implementado todavia.\n");
185
                                                }
186
                                                if (type != 0) {
187
                                                        message = PluginServices.getText(this, "-Error no especificado.\n");
188
                                                }
189
                                                JOptionPane.showMessageDialog(null, message);
190
                                        }
191
                                }
192
                        } else if (c.equals(getBtnLoadLegend())) {
193

    
194
                                JLegendFileChooser jfc = new JLegendFileChooser(getLegendDrivers());
195
                                jfc.setAcceptAllFileFilterUsed(false);
196

    
197
                                if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
198
                                        File file=jfc.getSelectedFile();
199
                                        IFMapLegendDriver driver = jfc.getSuitableDriver();
200
                                        String path = file.getAbsolutePath();
201
                                        defaultLegendFolderPath = path.substring(0, path.lastIndexOf(File.separator));
202

    
203
                                        try {
204
                                                table = driver.read(layer.getMapContext().getLayers(),layer, file);
205
//                                                ILegend my_legend = driver.read(layer.getMapContext().getLayers(),layer, file);
206
//                                                if(my_legend != null)
207
//                                                applyLegend(my_legend);
208

    
209
                                                if(table.containsKey(layer))
210
                                                        applyLegend((ILegend) table.get(layer));
211
//                                                if(table.size() > 1)
212
//                                                        applyRestOfLegends(table,layer.getMapContext().getLayers());
213

    
214

    
215
                                        } catch (LegendDriverException e1) {
216
                                                int type = e1.getType();
217
                                                String message="La leyenda no se aplicar? a la capa:\n";
218

    
219
                                                if ((type & LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND) != 0){
220
                                                        type = type & ~LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND;
221
                                                        message += PluginServices.getText(this, "-El campo de clasificaci?n no existe.\n");
222
                                                }
223
                                                if ((type & LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED) != 0){
224
                                                        type = type & ~LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED;
225
                                                        message += PluginServices.getText(this, "-El tipo de leyenda no es soportado por gvSIG.\n");
226
                                                }
227
                                                if ((type & LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED) != 0){
228
                                                        type = type & ~LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED;
229
                                                        message += PluginServices.getText(this, "-El tipo de s?mbolo no es soportado por gvSIG.\n");
230
                                                }
231
                                                if ((type & LegendDriverException.LAYER_SHAPETYPE_MISMATCH) != 0){
232
                                                        type = type & ~LegendDriverException.LAYER_SHAPETYPE_MISMATCH;
233
                                                        message += PluginServices.getText(this, "-El tipo de capa y de leyenda no coinciden.\n");
234
                                                }
235
                                                if ((type & LegendDriverException.PARSE_LEGEND_FILE_ERROR) != 0){
236
                                                        type = type & ~LegendDriverException.PARSE_LEGEND_FILE_ERROR;
237
                                                        message += PluginServices.getText(this, "-Error en el parse de la leyenda.\n");
238
                                                }
239
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION) != 0){
240
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION;
241
                                                        message += PluginServices.getText(this, "-Versi?n de leyenda no soportado por gvSIG.\n");
242
                                                }
243
                                                if ((type & LegendDriverException.UNSUPPORTED_LEGEND_READING) != 0){
244
                                                        type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
245
                                                        message += PluginServices.getText(this, "-Soporte para lectura de este tipo de formato no implementado todavia.\n");
246
                                                }
247
                                                if (type != 0) {
248
                                                        message = PluginServices.getText(this, "-Error no especificado.\n");
249
                                                }
250
                                                JOptionPane.showMessageDialog(null, message);
251
                                        }
252
                                }
253
                        }
254
                }
255

    
256

    
257

    
258

    
259

    
260

    
261

    
262
                private IFMapLegendDriver[] getLegendDrivers() {
263
                        Class[] legendDriverClasses = (Class[]) legendDriverPool.toArray(new Class[0]);
264
                        ArrayList<IFMapLegendDriver> drivers = new ArrayList<IFMapLegendDriver>();
265
                        for (int i = 0; i < legendDriverClasses.length; i++) {
266
                                try {
267
                                        drivers.add((IFMapLegendDriver) legendDriverClasses[i].newInstance());
268
                                } catch (InstantiationException e) {
269
                                        // TODO Auto-generated catch block
270
                                        e.printStackTrace();
271
                                } catch (IllegalAccessException e) {
272
                                        // TODO Auto-generated catch block
273
                                        e.printStackTrace();
274
                                }
275
                        }
276
                        return (IFMapLegendDriver[]) drivers.toArray(new IFMapLegendDriver[0]);
277
                };
278
        };
279
        private JLabel iconLabel;
280

    
281
        public LegendManager() {
282
                initialize();
283
        }
284

    
285
        private void initialize() {
286
                setLayout(new BorderLayout());
287
                add(getTopPanel(), BorderLayout.NORTH);
288
                add(getSplitPane(), BorderLayout.CENTER);
289
                setSize(500, 360);
290
                treeModel = new DefaultTreeModel(root);
291
        }
292

    
293
        private JSplitPane getSplitPane() {
294
                if (jSplitPane == null) {
295
                        jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
296
                        JPanel aux = new JPanel(new BorderLayout(0, 5));
297
                        aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
298
                        aux.add(getPreviewPanel(), BorderLayout.SOUTH);
299
                        jSplitPane.setLeftComponent(aux);
300
                        jSplitPane.setRightComponent(getCentralPanel());
301
                        jSplitPane.setDividerLocation(150);
302
                }
303
                return jSplitPane;
304
        }
305

    
306
        private JPanel getCentralPanel() {
307
                if (jCentralPanel == null) {
308
                        jCentralPanel = new JPanel(new BorderLayout(0,10));
309
                        jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
310
                        jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
311
                }
312
                return jCentralPanel;
313
        }
314

    
315
        private JScrollPane getJPanelContainer() {
316
                if (jPanelContainer == null) {
317
                        jPanelContainer = new JScrollPane();
318
                }
319
                return jPanelContainer;
320
        }
321

    
322
        /**
323
         * This method initializes jPanel
324
         *
325
         * @return javax.swing.JPanel
326
         */
327
         private JPanel getTopPanel() {
328
                if (topPanel == null) {
329
                        topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
330
                        topPanel.setPreferredSize(new Dimension(638, 31));
331
                        topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
332
                        topPanel.add(getBtnSaveLegend(), null);
333
                        topPanel.add(getBtnLoadLegend(), null);
334
                }
335
                return topPanel;
336
         }
337

    
338
         private JButton getBtnSaveLegend() {
339
                 if (btnSaveLegend == null) {
340
                         btnSaveLegend = new JButton(PluginServices.getText(this,"Guardar_leyenda")+"...");
341
                         btnSaveLegend.addActionListener(loadSaveLegendAction);
342
                 }
343
                 return btnSaveLegend;
344
         }
345

    
346
         private JButton getBtnLoadLegend() {
347
                 if (btnLoadLegend == null) {
348
                         btnLoadLegend = new JButton(PluginServices.getText(this,"Recuperar_leyenda")+"...");
349
                         btnLoadLegend.addActionListener(loadSaveLegendAction);
350
                 }
351
                 return btnLoadLegend;
352
         }
353

    
354
         /**
355
          * This method initializes jTextArea
356
          *
357
          * @return javax.swing.JTextArea
358
          */
359
         private JTextArea getTitleArea() {
360
                 if (titleArea == null) {
361
                         titleArea = new JTextArea();
362
                         titleArea.setBackground(java.awt.SystemColor.control);
363
                         titleArea.setLineWrap(true);
364
                         titleArea.setRows(0);
365
                         titleArea.setWrapStyleWord(false);
366
                         titleArea.setEditable(false);
367
                         titleArea.setPreferredSize(new java.awt.Dimension(495,40));
368
                 }
369
                 return titleArea;
370
         }
371
         /**
372
          * This method initializes jPanel1
373
          *
374
          * @return javax.swing.JPanel
375
          */
376
         private JPanel getPreviewPanel() {
377
                 if (preview == null) {
378
                         preview = new JPanel();
379
                         preview.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
380
                         preview.setBackground(java.awt.SystemColor.text);
381
                         preview.setLayout(new BorderLayout(5,5));
382
                         preview.add(getIconLabel());
383
                         preview.setPreferredSize(new Dimension(
384
                                         getSplitPane().getDividerLocation(),
385
                                         130));
386
                         preview.setBackground(Color.white);
387
                 }
388
                 return preview;
389
         }
390

    
391
         private JLabel getIconLabel() {
392
                 if (iconLabel == null) {
393
                        iconLabel = new JLabel();
394
                        iconLabel.setVerticalAlignment(JLabel.CENTER);
395
                        iconLabel.setHorizontalAlignment(JLabel.CENTER);
396
                }
397

    
398
                return iconLabel;
399
        }
400

    
401
        /**
402
          * This method initializes jScrollPane
403
          *
404
          * @return javax.swing.JScrollPane
405
          */
406
         private JScrollPane getLegendTreeScrollPane() {
407
                 if (legendTreeScrollPane == null) {
408
                         legendTreeScrollPane = new JScrollPane();
409
                         legendTreeScrollPane.setViewportView(getJTreeLegends());
410
                 }
411
                 return legendTreeScrollPane;
412
         }
413

    
414
         /**
415
          * <p>Adds a new fully-featured legend panel to the LegendManager.<br></p>
416
          *
417
          * <p><b>CAUTION:</b> Trying to add a child page whose parent hasn't been added yet
418
          * causes the application to fall in an infinite loop. This is a known
419
          * bug, sorry. Just avoid this case or try to fix it (lol).<br></p>
420
          *
421
          * <p><b>Notice</b> that there is no type check so if you add a non-ILegendPanel class,
422
          * you'll have a runtime error later.</p>
423
          * @param page, Class of type ILegendPanel
424
          */
425
         public static void addLegendPage(Class iLegendPanelClass) {
426
                 if (!legendPool.contains(iLegendPanelClass)) {
427
                         legendPool.add(iLegendPanelClass);
428
                 }
429
         }
430

    
431
         /**
432
          * Causes the component to be autofilled with the legend pages that
433
          * were added through the static method addLegendPage(ILegendPanel page)
434
          */
435
         private void fillDialog() {
436
                 if (empty) {
437
                         for (int i = 0; i < legendPool.size(); i++) {
438
                                 Class pageClass = (Class) legendPool.get(i);
439
                                 ILegendPanel page;
440
                                 try {
441
                                         page = (ILegendPanel) pageClass.newInstance();
442
                                         if (page.isSuitableFor(layer)) {
443
                                                 // this legend can be applied to this layer
444
                                                 pages.put(page.getClass(), page);
445

    
446
                                                 if (dirtyTree) {
447
                                                         // rebuild page tree
448
                                                         dirtyTree = false;
449

    
450
                                                         ArrayList legList = new ArrayList(pages.values());
451
                                                         ArrayList alreadyAdded = new ArrayList();
452
                                                         DefaultTreeModel model = new DefaultTreeModel(root);
453
                                                         while (legList.size()>0) {
454
                                                                 ILegendPanel legend = (ILegendPanel) legList.get(0);
455
                                                                 Class parent = legend.getParentClass();
456
                                                                 while (parent != null &&
457
                                                                                 !alreadyAdded.contains(pages.get(parent))) {
458
                                                                         legend = (ILegendPanel) pages.get(parent);
459
                                                                 }
460
                                                                 doInsertNode(model, legend);
461
                                                                 legList.remove(legend);
462
                                                                 alreadyAdded.add(legend);
463
                                                         }
464
                                                         treeModel = model;
465
                                                         jTreeLegends.setModel(model);
466
                                                 }
467
                                                 doInsertNode(treeModel, page);
468

    
469
                                         }
470
                                         getJTreeLegends().setModel(treeModel);
471

    
472
                                 } catch (InstantiationException e) {
473
                                         NotificationManager.addError("Trying to instantiate an interface" +
474
                                                         " or abstract class + "+pageClass.getName(), e);
475
                                 } catch (IllegalAccessException e) {
476
                                         NotificationManager.addError("IllegalAccessException: does " +
477
                                                         pageClass.getName()        + " class have an anonymous" +
478
                                                         " constructor?", e);
479
                                 }
480

    
481
                         }
482
                         getJTreeLegends().repaint();
483
                         empty = false;
484
                 }
485
         }
486

    
487
         private DefaultMutableTreeNode findNode(Class searchID) {
488
                 String title;
489
                 try {
490
                         title = ((ILegendPanel) Class.forName(searchID.getName()).newInstance()).getTitle();
491
                 } catch (Exception e) {
492
                         // this should be impossible, but anyway this case will be treat as the node does not
493
                         // exist.
494
                         return null;
495
                 }
496

    
497
                 Enumeration e = root.breadthFirstEnumeration();
498
                 while (e.hasMoreElements()) {
499
                         DefaultMutableTreeNode nodeAux = (DefaultMutableTreeNode) e.nextElement();
500
                         if (nodeAux != null) {
501
                                 ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
502
                                 if (legend == null) continue; // Root node
503
                                 if (legend.getTitle().equals(title)) {
504
                                         return nodeAux;
505
                                 }
506
                         }
507
                 }
508
                 return null;
509
         }
510

    
511
         private void doInsertNode(DefaultTreeModel treeModel, ILegendPanel page) {
512
                 dirtyTree = ((page.getParentClass() != null) && (findNode(page.getParentClass())==null));
513
                 if (findNode(page.getClass()) != null) // It is already added
514
                         return;
515
                 if (page.getParentClass() != null) {
516
                         if (pages.containsKey(page.getParentClass())) {
517
                                 ILegendPanel parent = (ILegendPanel) pages.get(page.getParentClass());
518
                                 DefaultMutableTreeNode nodeParent = findNode(parent.getClass());
519
                                 if (nodeParent == null) {
520
                                         // the parent is empty
521
                                         // Recursively add it
522
                                         doInsertNode(treeModel, parent);
523
                                 } else {
524
                                         DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
525
                                         int children = nodeParent.getChildCount();
526
                                         int pos=0;
527
                                         for (int i = 0; i < children; i++) {
528
                                                 DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(nodeParent, i);
529
                                                 if (node.getUserObject() instanceof ILegendPanel) {
530
                                                         String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
531
                                                         if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
532
                                                 }
533
                                         }
534
                                         treeModel.insertNodeInto(nodeValue, nodeParent, pos);
535
                                 }
536
                         }
537
                 } else {
538
                         // First level node
539
                         DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
540
                         int children = root.getChildCount();
541
                         int pos=0;
542
                         for (int i = 0; i < children; i++) {
543
                                 DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(root, i);
544
                                 if (node.getUserObject() instanceof ILegendPanel) {
545
                                         String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
546
                                         if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
547
                                 }
548
                         }
549
                         treeModel.insertNodeInto(nodeValue, root, pos);
550
                 }
551
         }
552

    
553
         private JScrollPane getTitleScroll() {
554
                 if (jTitleScrollPane == null) {
555
                         jTitleScrollPane = new JScrollPane();
556
                         jTitleScrollPane.setBounds(2, 2, 498, 42);
557
                         jTitleScrollPane.setViewportView(getTitleArea());
558
                 }
559
                 return jTitleScrollPane;
560
         }
561

    
562
         private JTree getJTreeLegends() {
563
                 if (jTreeLegends == null) {
564
                         jTreeLegends = new JTree();
565
                         jTreeLegends.setRootVisible(false);
566
                         MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
567
                         treeCellRenderer.setOpenIcon(null);
568
                         treeCellRenderer.setClosedIcon(null);
569
                         treeCellRenderer.setLeafIcon(null);
570

    
571
                         jTreeLegends.setCellRenderer(treeCellRenderer);
572
                         jTreeLegends.setShowsRootHandles(true);
573
                         jTreeLegends.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
574
                                 public void valueChanged(javax.swing.event.TreeSelectionEvent e) {
575
                                         if (isTreeListenerDisabled) return;
576
                                         DefaultMutableTreeNode node = (DefaultMutableTreeNode)
577
                                         jTreeLegends.getLastSelectedPathComponent();
578

    
579
                                         if (node == null) return;
580
                                         setActivePage((ILegendPanel) node.getUserObject());
581
                                 }
582
                         });
583
                         jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
584
                         jTreeLegends.getSelectionModel().
585
                         setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
586
                 }
587
                 return jTreeLegends;
588
         }
589

    
590
         private void setActivePage(ILegendPanel page) {
591
                 if (page.getPanel() == null) {
592
                         // this is what happens when the user clicked in a parent node
593
                         // which only acts as a folder, and does not manage any legend
594
                         // then it expands and selects the first child
595
                         DefaultMutableTreeNode node = findNode(page.getClass());
596
                         if (treeModel.getChildCount(node)>0) {
597
                                 DefaultMutableTreeNode dmn = (DefaultMutableTreeNode) treeModel.getChild(node, 0);
598
                                 page = (ILegendPanel) dmn.getUserObject();
599
                                 setActivePage(page);
600
                                 expandAndSelect(page);
601
                         }
602
                 } else {
603
                         // show the page
604
                         activePanel = page;
605
                         setIcon(activePanel.getIcon());
606

    
607
                         activePanel.setData(layer, legend);
608
                         getTitleArea().setText(activePanel.getDescription());
609
                         jPanelContainer.setViewportView(activePanel.getPanel());
610
                 }
611
         }
612

    
613

    
614
         private void setIcon(ImageIcon icon) {
615
                 getIconLabel().setIcon(icon);
616
        }
617

    
618

    
619
        private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
620
                 private static final long serialVersionUID = -6013698992263578041L;
621

    
622
                 public MyTreeCellRenderer() {}
623

    
624
                 public Component getTreeCellRendererComponent(
625
                                 JTree tree,
626
                                 Object value,
627
                                 boolean sel,
628
                                 boolean expanded,
629
                                 boolean leaf,
630
                                 int row,
631
                                 boolean hasFocus) {
632

    
633
                         super.getTreeCellRendererComponent(
634
                                         tree, value, sel,
635
                                         expanded, leaf, row,
636
                                         hasFocus);
637
                         if (value instanceof DefaultMutableTreeNode)
638
                         {
639
                                 DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
640
                                 if (node.getUserObject() instanceof ILegendPanel)
641
                                 {
642
                                         ILegendPanel legend = (ILegendPanel) node.getUserObject();
643
                                         this.setText(
644
                                                         legend.getPanel() == null ? "<html><b>"+legend.getTitle()+"</b></html>":legend.getTitle());
645
                                 }
646
                         }
647
                         return this;
648
                 }
649

    
650
         }
651

    
652
         private void expandAndSelect(Object node) {
653
                 isTreeListenerDisabled = true;
654
                 // will expand the tree and select the node
655
                 int i = 0;
656
                 boolean exit = false;
657

    
658
                 TreePath tp = null;
659
                 // find the page in the tree
660
                 while (i<jTreeLegends.getRowCount() && !exit) {
661
                         //see if this row is the node that we are looking for
662

    
663
                         tp = jTreeLegends.getPathForRow(i);
664
                         Object[] obj = tp.getPath();
665
                         for (int j = 0; j < obj.length && !exit ; j++) {
666
                                 Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
667

    
668
                                 if (o!=null        && o.getClass().equals(node.getClass())        && o.equals(node)) {
669
                                         // found it! collapse the tree
670
                                         while (i>=0) {
671
                                                 jTreeLegends.collapseRow(i);
672
                                                 i--;
673
                                         }
674
                                         exit = true;
675
                                 }
676
                         }
677
                         jTreeLegends.expandRow(i);
678
                         i++;
679
                 }
680

    
681
                 // expand the tree and set the selection
682
                 if (tp != null) {
683
                         jTreeLegends.expandPath(tp);
684
                         jTreeLegends.setSelectionPath(tp);
685
                 }
686
                 isTreeListenerDisabled = false;
687
         }
688

    
689
         public String getName() {
690
                 return PluginServices.getText(this,"Simbologia");
691
         }
692

    
693
         public void acceptAction() {
694
                 // automatically handled by the ThemeManagerWindow
695
         }
696

    
697
         public void cancelAction() {
698
                 // does nothing
699
         }
700

    
701
         public void applyAction() {
702
                 legend = activePanel.getLegend();
703

    
704
                 
705
                 if (table != null && table.size() > 1) 
706
                         applyRestOfLegends(table,layer.getMapContext().getLayers());
707
                 
708
                 /* try to apply the legend to all the active layers that
709
                 can accept it */
710
                 FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
711
                 for (int i=0; i < activeLyrs.length; i++) {
712
                         FLayer laux=activeLyrs[i];
713

    
714
                         if (activeLyrs[i] instanceof FLayers){
715
                                 laux=getFirstActiveLayerVect((FLayers)activeLyrs[i]);
716
                         }
717

    
718
                         if (laux instanceof ClassifiableVectorial) {
719
                                 ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
720
                                 try {
721
                                         if (legend instanceof IClassifiedVectorLegend) {
722
                                                 // Es una leyenda que necesita un recordset con un
723
                                                 // nombre de campo. Comprobamos que ese recordset
724
                                                 // tiene ese nombre de campo y es del tipo esperado
725
                                                 IClassifiedVectorLegend cl = (IClassifiedVectorLegend) legend;
726

    
727
                                                 if (aux2 instanceof AlphanumericData) {
728

    
729
                                                         if (cl.getValues().length==0) {
730
                                                                 JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"no_es_posible_aplicar_leyenda_vacia"));
731
                                                                 return;
732
                                                         }
733

    
734
                                                         aux2.setLegend((IVectorLegend) legend);
735
                                                 }
736
                                         }
737
                                         else if (legend instanceof SingleSymbolLegend)
738
                                                 aux2.setLegend((IVectorLegend) legend);
739
                                 } catch (LegendLayerException e) {
740
                                         NotificationManager.addError(PluginServices.getText(this, "legend_exception"), e);
741
                                 }
742
                         }
743
                 }
744
         }
745

    
746
         private void applyRestOfLegends(Hashtable<FLayer, ILegend> table2,FLayers layers) {
747

    
748
                 for(int i = 0; i < layers.getLayersCount(); i++) {
749
                         FLayer my_layer= layers.getLayer(i);
750

    
751
                         if(!(my_layer instanceof FLayers)){
752
                                 if(my_layer instanceof ClassifiableVectorial){
753
                                         try {
754
                                                 if(table.containsKey(my_layer)){
755
                                                         ClassifiableVectorial lyr = (ClassifiableVectorial)my_layer;
756
                                                         lyr.setLegend((IVectorLegend) table.get(my_layer));
757
                                                 }
758

    
759
                                         } catch (LegendLayerException e) {
760
                                                 // TODO Auto-generated catch block
761
                                                 e.printStackTrace();
762
                                         }
763
                                 }
764
                         }
765
                         else 
766
                                 applyRestOfLegends(table,(FLayers) my_layer);        
767
                 }
768
         }
769

    
770
         @Override
771
         public void setModel(FLayer layer) {
772
                 this.layer = layer;
773
                 applyLegend(((Classifiable) layer).getLegend());
774
         }
775

    
776
         /**
777
          * Applies the legend to the layer.
778
          * 
779
          * @param aLegend , legend that the user wants to apply
780
          */
781
         private void applyLegend(ILegend aLegend) {
782
                 this.legend = aLegend;
783
                 fillDialog();
784
                 Enumeration en = pages.keys();
785
                 while (en.hasMoreElements()) {
786
                         ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
787
                         if (legend.getClass().equals(page.getLegendClass())) {
788
                                 setActivePage(page);
789
                                 expandAndSelect(page);
790
                         }
791
                 }
792
         }
793

    
794
         public static void addLegendDriver(Class legendDriverClass) {
795
                 if (!legendDriverPool.contains(legendDriverClass)) {
796
                         legendDriverPool.add(legendDriverClass);
797
                 }
798
         }
799
}