Statistics
| Revision:

root / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / documents / view / legend / gui / LegendManager.java @ 40347

History | View | Annotate | Download (36.2 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 org.gvsig.app.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.io.FileInputStream;
54
import java.io.FileNotFoundException;
55
import java.io.FileOutputStream;
56
import java.io.InputStream;
57
import java.io.OutputStream;
58
import java.util.ArrayList;
59
import java.util.Enumeration;
60
import java.util.Hashtable;
61
import java.util.prefs.Preferences;
62

    
63
import javax.swing.ImageIcon;
64
import javax.swing.JButton;
65
import javax.swing.JComponent;
66
import javax.swing.JFileChooser;
67
import javax.swing.JLabel;
68
import javax.swing.JOptionPane;
69
import javax.swing.JPanel;
70
import javax.swing.JScrollPane;
71
import javax.swing.JSplitPane;
72
import javax.swing.JTextArea;
73
import javax.swing.JTree;
74
import javax.swing.filechooser.FileFilter;
75
import javax.swing.tree.DefaultMutableTreeNode;
76
import javax.swing.tree.DefaultTreeCellRenderer;
77
import javax.swing.tree.DefaultTreeModel;
78
import javax.swing.tree.MutableTreeNode;
79
import javax.swing.tree.TreePath;
80
import javax.swing.tree.TreeSelectionModel;
81

    
82
import org.slf4j.Logger;
83
import org.slf4j.LoggerFactory;
84

    
85
import org.gvsig.andami.PluginServices;
86
import org.gvsig.andami.messages.NotificationManager;
87
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
88
import org.gvsig.fmap.mapcontext.layers.FLayer;
89
import org.gvsig.fmap.mapcontext.layers.FLayers;
90
import org.gvsig.fmap.mapcontext.layers.operations.Classifiable;
91
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
92
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
93
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
94
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
95
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
96
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
97
import org.gvsig.tools.ToolsLocator;
98
import org.gvsig.tools.persistence.PersistenceManager;
99

    
100
/**
101
 * Implements the panel which allows the user to control all the information
102
 * about the
103
 * legends of a layer in order to improve the information that it offers to the
104
 * user.
105
 * There are options to create, save or load an existing legend.
106
 * 
107
 * @author jaume dominguez faus - jaume.dominguez@iver.es
108
 */
109
public class LegendManager extends AbstractThemeManagerPage {
110

    
111
    private static final Logger logger =
112
        LoggerFactory.getLogger(LegendManager.class);
113
    
114
    private static final long serialVersionUID = 7989057553773181019L;
115
    private static ArrayList<Class<? extends ILegendPanel>> legendPool =
116
        new ArrayList<Class<? extends ILegendPanel>>();
117
    // private static ArrayList<Class<? extends IFMapLegendDriver>>
118
    // legendDriverPool = new ArrayList<Class<? extends IFMapLegendDriver>>();
119

    
120
    private FLayer layer;
121
    private ILegend legend; // Le asignaremos la leyenda del primer tema activo.
122
    private Hashtable<Class<? extends ILegendPanel>, ILegendPanel> pages =
123
        new Hashtable<Class<? extends ILegendPanel>, ILegendPanel>();
124
    private JPanel topPanel = null;
125
    private JTextArea titleArea = null;
126
    private JPanel preview = null;
127
    private JScrollPane jTitleScrollPane = null;
128
    private JTree jTreeLegends;
129
    private ILegendPanel activePanel;
130
    private JScrollPane legendTreeScrollPane;
131
    private boolean dirtyTree_;
132
    private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
133
    private DefaultTreeModel treeModel;
134
    private JScrollPane jPanelContainer;
135
    private JPanel jCentralPanel;
136
    private JSplitPane jSplitPane;
137
    private boolean isTreeListenerDisabled;
138
    private JButton btnSaveLegend;
139
    private JButton btnLoadLegend;
140
    private Hashtable<FLayer, ILegend> table = null;
141
    private boolean empty = true;
142
    private JLabel iconLabel;
143

    
144
    public static String defaultLegendFolderPath;
145
    {
146

    
147
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
148
        defaultLegendFolderPath = prefs.get("LegendsFolder", "");
149
    }
150
    private ActionListener loadSaveLegendAction = new ActionListener() {
151

    
152
        public void actionPerformed(java.awt.event.ActionEvent e) {
153
            JComponent c = (JComponent) e.getSource();
154
            if (c.equals(getBtnSaveLegend())) {
155
                saveLegend();
156

    
157
            } else
158
                if (c.equals(getBtnLoadLegend())) {
159
                    loadLegend();
160
                }
161
        }
162

    
163
        private void saveLegend() {
164
            ILegend legend = activePanel.getLegend();
165

    
166
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
167
            JFileChooser fileChooser = new JFileChooser();
168
            fileChooser.setAcceptAllFileFilterUsed(false);
169

    
170
            fileChooser.setFileFilter(new FileFilter() {
171

    
172
                @Override
173
                public String getDescription() {
174
                    return "Legend files (*"
175
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
176
                }
177

    
178
                @Override
179
                public boolean accept(File f) {
180
                    if (f.isDirectory()) {
181
                        return true;
182
                    } else
183
                        if (f.isFile() && getExtension(f) != null) {
184
                            return getExtension(f).equals(
185
                                SymbolManager.LEGEND_FILE_EXTENSION);
186
                        } else {
187
                            return false;
188
                        }
189
                }
190
            });
191

    
192
            if (fileChooser.showSaveDialog((Component) PluginServices
193
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
194
                OutputStream os;
195
                File selectedFile = fileChooser.getSelectedFile();
196

    
197
                if (getExtension(selectedFile) == null
198
                    || !getExtension(selectedFile).equals(
199
                        SymbolManager.LEGEND_FILE_EXTENSION)) {
200
                    File selectedFileWithExtension =
201
                        new File(selectedFile.getAbsolutePath()
202
                            + SymbolManager.LEGEND_FILE_EXTENSION);
203
                    selectedFile = selectedFileWithExtension;
204
                }
205

    
206
                try {
207
                    os = new FileOutputStream(selectedFile);
208
                } catch (FileNotFoundException e) {
209
                    JOptionPane.showMessageDialog(null,
210
                        "_cant_open_the_input_file_legend");
211
                    return;
212
                }
213

    
214
                manager.putObject(os, legend);
215
            }
216
        }
217

    
218
        private void loadLegend() {
219

    
220
            JFileChooser fileChooser = new JFileChooser();
221
            fileChooser.setAcceptAllFileFilterUsed(false);
222

    
223
            // fileChooser filter
224
            fileChooser.setFileFilter(new FileFilter() {
225

    
226
                @Override
227
                public String getDescription() {
228
                    // get this extension from manager or somewhere!
229

    
230
                    return "Legend files (*"
231
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
232
                }
233

    
234
                @Override
235
                public boolean accept(File f) {
236
                    if (f.isDirectory()) {
237
                        return true;
238
                    } else
239
                        if (f.isFile() && getExtension(f) != null) {
240

    
241
                            return getExtension(f).equals(
242
                                SymbolManager.LEGEND_FILE_EXTENSION);
243
                        } else {
244
                            return false;
245
                        }
246
                }
247
            });
248

    
249
            // open a file
250
            if (fileChooser.showOpenDialog((Component) PluginServices
251
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
252
                File file = fileChooser.getSelectedFile();
253
                PersistenceManager manager =
254
                    ToolsLocator.getPersistenceManager();
255
                InputStream is;
256

    
257
                try {
258
                    is = new FileInputStream(file);
259
                } catch (FileNotFoundException e) {
260
                    JOptionPane.showMessageDialog(null,
261
                        "_cant_open_the_input_file_legend");
262
                    return;
263
                }
264
                ILegend legend = (ILegend) manager.getObject(is);
265
                applyLegend(legend);
266
            }
267
        }
268
    };
269

    
270
    //
271
    // JLegendFileChooser jfc = new
272
    // JLegendFileChooser(getLegendDrivers(),true);
273
    // jfc.setAcceptAllFileFilterUsed(false);
274
    //
275
    //
276
    // File basedir = null;
277
    // jfc.setCurrentDirectory(basedir);
278
    // if (jfc.showSaveDialog((Component) PluginServices.getMainFrame())
279
    // == JFileChooser.APPROVE_OPTION) {
280
    //
281
    // File file = jfc.getSelectedFile();
282
    // String version = jfc.getDriverVersion();
283
    // IFMapLegendDriver driver = jfc.getSuitableDriver();
284
    //
285
    // if(!(driver instanceof FMapGVLDriver)){
286
    // Object[] options = {PluginServices.getText(this, "yes"),
287
    // PluginServices.getText(this, "no")};
288
    //
289
    // int answer =
290
    // JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
291
    // PluginServices.getText(this, "not_GVSLEG_save_question")+"\n"+ //GVL
292
    // changed to GVSLEG, be aware
293
    // PluginServices.getText(this, "desea_continuar"),
294
    // PluginServices.getText(this, "confirmation_dialog"),
295
    // JOptionPane.YES_NO_OPTION,
296
    // JOptionPane.QUESTION_MESSAGE,
297
    // null,
298
    // options, options[1]);
299
    // if (answer!=JOptionPane.OK_OPTION) {
300
    // // 'Cancel' pressed or window closed: don't save anythig, exit
301
    // save dialog
302
    // return;
303
    // }
304
    // }
305
    //
306
    // if (file.exists()) {
307
    // Object[] options = {PluginServices.getText(this, "yes"),
308
    // PluginServices.getText(this, "no"),
309
    // PluginServices.getText(this, "Cancel")};
310
    //
311
    // int answer =
312
    // JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
313
    // PluginServices.getText(this,
314
    // "fichero_ya_existe_seguro_desea_guardarlo"),
315
    // PluginServices.getText(this, "confirmation_dialog"),
316
    // JOptionPane.YES_NO_CANCEL_OPTION,
317
    // JOptionPane.QUESTION_MESSAGE,
318
    // null,
319
    // options, options[1]);
320
    // if (answer!=JOptionPane.OK_OPTION) {
321
    // // 'Cancel' pressed or window closed: don't save anythig, exit
322
    // save dialog
323
    // return;
324
    // }
325
    // }
326
    //
327
    //
328
    // try {
329
    // driver.write(layer.getMapContext().getLayers(),layer,
330
    // activePanel.getLegend(), file, version);
331
    //
332
    // } catch (LegendDriverException e1) {
333
    // int type = e1.getType();
334
    // String message=PluginServices.getText(this,
335
    // "could_not_save_legend")+":\n";
336
    //
337
    // if ((type & LegendDriverException.SAVE_LEGEND_ERROR) != 0){
338
    // type = type & ~LegendDriverException.SAVE_LEGEND_ERROR;
339
    // message += PluginServices.getText(this,
340
    // "error_writing_file")+".\n";
341
    // }
342
    // if ((type & LegendDriverException.UNSUPPORTED_LEGEND_CREATION) !=
343
    // 0){
344
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_CREATION;
345
    // message += "-"+ PluginServices.getText(this,
346
    // "legend_format_not_yet_supported")+"\n";
347
    // }
348
    // if (type != 0) {
349
    // message = "-"+PluginServices.getText(this, "unknown_error")+"\n";
350
    // }
351
    // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
352
    // message);
353
    // }
354
    // }
355
    // } else if (c.equals(getBtnLoadLegend())) {
356
    //
357
    // JLegendFileChooser jfc = new
358
    // JLegendFileChooser(getLegendDrivers());
359
    // jfc.setAcceptAllFileFilterUsed(false);
360
    //
361
    // if (jfc.showOpenDialog((Component) PluginServices.getMainFrame())
362
    // == JFileChooser.APPROVE_OPTION) {
363
    // File file=jfc.getSelectedFile();
364
    // IFMapLegendDriver driver = jfc.getSuitableDriver();
365
    // String path = file.getAbsolutePath();
366
    // defaultLegendFolderPath = path.substring(0,
367
    // path.lastIndexOf(File.separator));
368
    //
369
    // try {
370
    // table = driver.read(layer.getMapContext().getLayers(),layer,
371
    // file);
372
    //
373
    // if(table.containsKey(layer))
374
    // applyLegend((ILegend) table.get(layer));
375
    //
376
    //
377
    // } catch (LegendDriverException e1) {
378
    // int type = e1.getType();
379
    // String message = PluginServices.getText(this,
380
    // "the_legend_will_not_be_applied")+":\n";
381
    // boolean hasReason = false;
382
    //
383
    // if ((type &
384
    // LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND) != 0){
385
    // type = type &
386
    // ~LegendDriverException.CLASSIFICATION_FIELDS_NOT_FOUND;
387
    // message +="-"+ PluginServices.getText(this,
388
    // "classification_field_does_not_exists")+"\n";
389
    // hasReason = true;
390
    // }
391
    // if ((type & LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED)
392
    // != 0){
393
    // type = type &
394
    // ~LegendDriverException.LEGEND_TYPE_NOT_YET_SUPPORTED;
395
    // message += "-"+ PluginServices.getText(this,
396
    // "legend_type_not_yet_supported")+"\n";
397
    // hasReason = true;
398
    // }
399
    // if ((type & LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED)
400
    // != 0){
401
    // type = type &
402
    // ~LegendDriverException.SYMBOL_TYPE_NOT_YET_SUPPORTED;
403
    // message += "-"+ PluginServices.getText(this,
404
    // "unsupported_symbol_type")+"\n";
405
    // hasReason = true;
406
    // }
407
    // if ((type & LegendDriverException.LAYER_SHAPETYPE_MISMATCH) !=
408
    // 0){
409
    // type = type & ~LegendDriverException.LAYER_SHAPETYPE_MISMATCH;
410
    // message += "-"+ PluginServices.getText(this,
411
    // "layer_geometry_and_legend_types_are_incompatible")+"\n";
412
    // hasReason = true;
413
    // }
414
    // if ((type & LegendDriverException.PARSE_LEGEND_FILE_ERROR) != 0){
415
    // type = type & ~LegendDriverException.PARSE_LEGEND_FILE_ERROR;
416
    // message += "-"+ PluginServices.getText(this,
417
    // "failed_reading_file")+"\n";
418
    // hasReason = true;
419
    // }
420
    // if ((type &
421
    // LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION) != 0){
422
    // type = type &
423
    // ~LegendDriverException.UNSUPPORTED_LEGEND_FILE_VERSION;
424
    // message += "-"+ PluginServices.getText(this,
425
    // "unsupported_legend_file_version")+"\n";
426
    // hasReason = true;
427
    // }
428
    // if ((type & LegendDriverException.UNSUPPORTED_LEGEND_READING) !=
429
    // 0){
430
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
431
    // message +="-"+ PluginServices.getText(this,
432
    // "unsupported_legend_file_format")+"\n";
433
    // hasReason = true;
434
    // }
435
    // if ((type & LegendDriverException.LAYER_NAME_NOT_FOUND) != 0){
436
    // type = type & ~LegendDriverException.UNSUPPORTED_LEGEND_READING;
437
    // message +="-"+ PluginServices.getText(this,
438
    // "could_not_find_layer")+"\n";
439
    // hasReason = true;
440
    // }
441
    // if (!hasReason) {
442
    // message = "-"+ PluginServices.getText(this,
443
    // "unknown_error")+"\n";
444
    // }
445
    // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),
446
    // message);
447
    // }
448
    // }
449
    // }
450

    
451
    // private IFMapLegendDriver[] getLegendDrivers() {
452
    // Class<?>[] legendDriverClasses = legendDriverPool.toArray(new Class[0]);
453
    // ArrayList<IFMapLegendDriver> drivers = new
454
    // ArrayList<IFMapLegendDriver>();
455
    // for (int i = 0; i < legendDriverClasses.length; i++) {
456
    // String message = PluginServices.getText(this,
457
    // "adding_legend_file_format_support")+": ";
458
    // try {
459
    // Class<?> c = legendDriverClasses[i];
460
    // drivers.add((IFMapLegendDriver) c.newInstance());
461
    // } catch (Exception e) {
462
    // NotificationManager.addError(message+PluginServices.getText(this,
463
    // "failed"), e);
464
    // }
465
    // NotificationManager.addInfo(message+PluginServices.getText(this, "OK"));
466
    //
467
    // }
468
    // return (IFMapLegendDriver[]) drivers.toArray(new IFMapLegendDriver[0]);
469
    // };
470

    
471
    private String getExtension(File f) {
472
        String ext = null;
473
        String s = f.getName();
474
        int i = s.lastIndexOf('.');
475

    
476
        if (i > 0 && i < s.length() - 1) {
477
            // ext = s.substring(i + 1).toLowerCase();
478
            ext = s.substring(i).toLowerCase();
479
        }
480
        return ext;
481
    }
482

    
483
    public LegendManager() {
484
        initialize();
485
    }
486

    
487
    private void initialize() {
488
        setLayout(new BorderLayout());
489
        add(getTopPanel(), BorderLayout.NORTH);
490
        add(getSplitPane(), BorderLayout.CENTER);
491
        setSize(500, 360);
492
        treeModel = new DefaultTreeModel(root);
493
    }
494

    
495
    private JSplitPane getSplitPane() {
496
        if (jSplitPane == null) {
497
            jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
498
            JPanel aux = new JPanel(new BorderLayout(0, 5));
499
            aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
500
            aux.add(getPreviewPanel(), BorderLayout.SOUTH);
501
            jSplitPane.setLeftComponent(aux);
502
            jSplitPane.setRightComponent(getCentralPanel());
503
            jSplitPane.setDividerLocation(150);
504
        }
505
        return jSplitPane;
506
    }
507

    
508
    private JPanel getCentralPanel() {
509
        if (jCentralPanel == null) {
510
            jCentralPanel = new JPanel(new BorderLayout(0, 10));
511
            jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
512
            jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
513
        }
514
        return jCentralPanel;
515
    }
516

    
517
    private JScrollPane getJPanelContainer() {
518
        if (jPanelContainer == null) {
519
            jPanelContainer = new JScrollPane();
520
        }
521
        return jPanelContainer;
522
    }
523

    
524
    /**
525
     * This method initializes jPanel
526
     * 
527
     * @return javax.swing.JPanel
528
     */
529
    private JPanel getTopPanel() {
530
        if (topPanel == null) {
531
            topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
532
            topPanel.setPreferredSize(new Dimension(638, 31));
533
            topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
534
                null, "",
535
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
536
                javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
537
            topPanel.add(getBtnSaveLegend(), null);
538
            topPanel.add(getBtnLoadLegend(), null);
539
        }
540
        return topPanel;
541
    }
542

    
543
    private JButton getBtnSaveLegend() {
544
        if (btnSaveLegend == null) {
545
            btnSaveLegend =
546
                new JButton(PluginServices.getText(this, "Guardar_leyenda")
547
                    + "...");
548
            btnSaveLegend.addActionListener(loadSaveLegendAction);
549
        }
550
        return btnSaveLegend;
551
    }
552

    
553
    private JButton getBtnLoadLegend() {
554
        if (btnLoadLegend == null) {
555
            btnLoadLegend =
556
                new JButton(PluginServices.getText(this, "Recuperar_leyenda")
557
                    + "...");
558
            btnLoadLegend.addActionListener(loadSaveLegendAction);
559
        }
560
        return btnLoadLegend;
561
    }
562

    
563
    /**
564
     * This method initializes jTextArea
565
     * 
566
     * @return javax.swing.JTextArea
567
     */
568
    private JTextArea getTitleArea() {
569
        if (titleArea == null) {
570
            titleArea = new JTextArea();
571
            titleArea.setBackground(java.awt.SystemColor.control);
572
            titleArea.setLineWrap(true);
573
            titleArea.setRows(0);
574
            titleArea.setWrapStyleWord(false);
575
            titleArea.setEditable(false);
576
            titleArea.setPreferredSize(new java.awt.Dimension(495, 40));
577
        }
578
        return titleArea;
579
    }
580

    
581
    /**
582
     * This method initializes jPanel1
583
     * 
584
     * @return javax.swing.JPanel
585
     */
586
    private JPanel getPreviewPanel() {
587
        if (preview == null) {
588
            preview = new JPanel();
589
            preview.setBorder(javax.swing.BorderFactory
590
                .createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
591
            preview.setBackground(java.awt.SystemColor.text);
592
            preview.setLayout(new BorderLayout(5, 5));
593
            preview.add(getIconLabel());
594
            preview.setPreferredSize(new Dimension(getSplitPane()
595
                .getDividerLocation(), 130));
596
            preview.setBackground(Color.white);
597
        }
598
        return preview;
599
    }
600

    
601
    private JLabel getIconLabel() {
602
        if (iconLabel == null) {
603
            iconLabel = new JLabel();
604
            iconLabel.setVerticalAlignment(JLabel.CENTER);
605
            iconLabel.setHorizontalAlignment(JLabel.CENTER);
606
        }
607

    
608
        return iconLabel;
609
    }
610

    
611
    /**
612
     * This method initializes jScrollPane
613
     * 
614
     * @return javax.swing.JScrollPane
615
     */
616
    private JScrollPane getLegendTreeScrollPane() {
617
        if (legendTreeScrollPane == null) {
618
            legendTreeScrollPane = new JScrollPane();
619
            legendTreeScrollPane.setViewportView(getJTreeLegends());
620
        }
621
        return legendTreeScrollPane;
622
    }
623

    
624
    /**
625
     * <p>
626
     * Adds a new fully-featured legend panel to the LegendManager.<br>
627
     * </p>
628
     * 
629
     * <p>
630
     * <b>CAUTION:</b> Trying to add a child page whose parent hasn't been added
631
     * yet causes the application to fall in an infinite loop. This is a known
632
     * bug, sorry. Just avoid this case or try to fix it (lol).<br>
633
     * </p>
634
     * 
635
     * <p>
636
     * <b>Notice</b> that there is no type check so if you add a
637
     * non-ILegendPanel class, you'll have a runtime error later.
638
     * </p>
639
     * 
640
     * @param page
641
     *            , Class of type ILegendPanel
642
     */
643
    public static void addLegendPage(
644
        Class<? extends ILegendPanel> iLegendPanelClass) {
645
        if (!legendPool.contains(iLegendPanelClass)) {
646
            legendPool.add(iLegendPanelClass);
647
        }
648
    }
649

    
650
    /**
651
     * Causes the component to be autofilled with the legend pages that
652
     * were added through the static method addLegendPage(ILegendPanel page)
653
     */
654
    private void fillDialog() {
655
        if (empty) {
656
            
657
            Class<?> pageClass = null;
658
            ILegendPanel page = null;
659
            
660
            for (int i = 0; i < legendPool.size(); i++) {
661
                pageClass = (Class<?>) legendPool.get(i);
662
                try {
663
                    page = (ILegendPanel) pageClass.newInstance();
664
                } catch (Exception e) {
665
                    logger.info("Unable to instantiate legend panel.", e);
666
                }
667
                if (page != null && page.isSuitableFor(layer)) {
668
                    pages.put(page.getClass(), page); // this legend can be applied
669
                }
670
            }
671
            
672
            Enumeration<ILegendPanel> enume = pages.elements();
673
            while (enume.hasMoreElements()) {
674
                page = enume.nextElement();
675
                doInsertNode(treeModel, page);
676
            }
677

    
678
            getJTreeLegends().setModel(treeModel);
679
            getJTreeLegends().repaint();
680
            empty = false;
681
        }
682
    }
683

    
684
    @SuppressWarnings("unchecked")
685
    private DefaultMutableTreeNode findNode(Class searchID) {
686
        String title;
687
        try {
688
            title =
689
                ((ILegendPanel) Class.forName(searchID.getName()).newInstance())
690
                    .getTitle();
691
        } catch (Exception e) {
692
            // this should be impossible, but anyway this case will be treat as
693
            // the node does not
694
            // exist.
695
            return null;
696
        }
697

    
698
        Enumeration e = root.breadthFirstEnumeration();
699
        while (e.hasMoreElements()) {
700
            DefaultMutableTreeNode nodeAux =
701
                (DefaultMutableTreeNode) e.nextElement();
702
            if (nodeAux != null) {
703
                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
704
                if (legend == null)
705
                    continue; // Root node
706
                if (legend.getTitle().equals(title)) {
707
                    return nodeAux;
708
                }
709
            }
710
        }
711
        return null;
712
    }
713

    
714
    /**
715
     * If parent_node == null, add to root.
716
     * Returns added node
717
     * 
718
     * @param tm
719
     * @param parent_node
720
     * @param item
721
     */
722
    private MutableTreeNode insertNodeHere(
723
        DefaultTreeModel tm,
724
        MutableTreeNode parent_node,
725
        ILegendPanel item) {
726
        
727
        MutableTreeNode pn = null;
728
        
729
        if (parent_node == null) {
730
            pn = root;
731
        } else {
732
            pn = parent_node;
733
        }
734
        
735
        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(item);
736
        int children = pn.getChildCount();
737
        int pos = 0;
738
        String pTitle = null;
739
        
740
        for (int i = 0; i < children; i++) {
741
            DefaultMutableTreeNode node =
742
                (DefaultMutableTreeNode) tm.getChild(pn, i);
743
            if (node.getUserObject() instanceof ILegendPanel) {
744
                pTitle = ((ILegendPanel) node.getUserObject()).getTitle();
745
                if (pTitle.compareTo(item.getTitle()) < 0) {
746
                    pos++;
747
                }
748
            }
749
        }
750
        tm.insertNodeInto(nodeValue, pn, pos);
751
        return nodeValue;
752
    }
753
    
754
    /**
755
     * Returns inserted node
756
     * 
757
     * @param tm
758
     * @param page
759
     * @return
760
     */
761
    private MutableTreeNode doInsertNode(DefaultTreeModel tm, ILegendPanel page) {
762
        
763
        if (tm == null || page == null) {
764
            return null;
765
        }
766
        
767
        MutableTreeNode aux = findNode(page.getClass()); 
768
        if (aux != null) {
769
            return aux;
770
        }
771

    
772
        Class parent_class = page.getParentClass();
773
        
774
        if (parent_class != null) {
775
            if (pages.containsKey(parent_class)) {
776
                ILegendPanel parent = (ILegendPanel) pages.get(parent_class);
777
                
778
                aux = doInsertNode(tm, parent); 
779
                if (aux != null) {
780
                    return insertNodeHere(tm, aux, page);
781
                } else {
782
                    return null;
783
                }
784
                
785
            } else {
786
                return null;
787
            }
788
        } else {
789
            // add to root
790
            return insertNodeHere(tm, null, page);
791
        }
792
        
793

    
794
    }
795
    
796
    
797
    
798
    
799

    
800
    private JScrollPane getTitleScroll() {
801
        if (jTitleScrollPane == null) {
802
            jTitleScrollPane = new JScrollPane();
803
            jTitleScrollPane.setBounds(2, 2, 498, 42);
804
            jTitleScrollPane.setViewportView(getTitleArea());
805
        }
806
        return jTitleScrollPane;
807
    }
808

    
809
    private JTree getJTreeLegends() {
810
        if (jTreeLegends == null) {
811
            jTreeLegends = new JTree();
812
            jTreeLegends.setRootVisible(false);
813
            MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
814
            treeCellRenderer.setOpenIcon(null);
815
            treeCellRenderer.setClosedIcon(null);
816
            treeCellRenderer.setLeafIcon(null);
817

    
818
            jTreeLegends.setCellRenderer(treeCellRenderer);
819
            jTreeLegends.setShowsRootHandles(true);
820
            jTreeLegends
821
                .addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
822

    
823
                    public void valueChanged(
824
                        javax.swing.event.TreeSelectionEvent e) {
825
                        if (isTreeListenerDisabled)
826
                            return;
827
                        DefaultMutableTreeNode node =
828
                            (DefaultMutableTreeNode) jTreeLegends
829
                                .getLastSelectedPathComponent();
830

    
831
                        if (node == null)
832
                            return;
833
                        setActivePage((ILegendPanel) node.getUserObject());
834
                    }
835
                });
836
            jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
837
            jTreeLegends.getSelectionModel().setSelectionMode(
838
                TreeSelectionModel.SINGLE_TREE_SELECTION);
839
        }
840
        return jTreeLegends;
841
    }
842

    
843
    private void setActivePage(ILegendPanel page) {
844
        if (page.getPanel() == null) {
845
            // this is what happens when the user clicked in a parent node
846
            // which only acts as a folder, and does not manage any legend
847
            // then it expands and selects the first child
848
            DefaultMutableTreeNode node = findNode(page.getClass());
849
            if (treeModel.getChildCount(node) > 0) {
850
                DefaultMutableTreeNode dmn =
851
                    (DefaultMutableTreeNode) treeModel.getChild(node, 0);
852
                page = (ILegendPanel) dmn.getUserObject();
853
                setActivePage(page);
854
                expandAndSelect(page);
855
            }
856
        } else {
857
            // show the page
858
            activePanel = page;
859
            setIcon(activePanel.getIcon());
860

    
861
            activePanel.setData(layer, legend);
862
            getTitleArea().setText(activePanel.getDescription());
863
            jPanelContainer.setViewportView(activePanel.getPanel());
864
        }
865
    }
866

    
867
    private void setIcon(ImageIcon icon) {
868
        getIconLabel().setIcon(icon);
869
    }
870

    
871
    private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
872

    
873
        private static final long serialVersionUID = -6013698992263578041L;
874

    
875
        public MyTreeCellRenderer() {
876
        }
877

    
878
        public Component getTreeCellRendererComponent(JTree tree, Object value,
879
            boolean sel, boolean expanded, boolean leaf, int row,
880
            boolean hasFocus) {
881

    
882
            super.getTreeCellRendererComponent(tree, value, sel, expanded,
883
                leaf, row, hasFocus);
884
            if (value instanceof DefaultMutableTreeNode) {
885
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
886
                if (node.getUserObject() instanceof ILegendPanel) {
887
                    ILegendPanel legend = (ILegendPanel) node.getUserObject();
888
                    this
889
                        .setText(legend.getPanel() == null ? "<html><b>"
890
                            + legend.getTitle() + "</b></html>" : legend
891
                            .getTitle());
892
                }
893
            }
894
            return this;
895
        }
896

    
897
    }
898

    
899
    private void expandAndSelect(Object node) {
900
        isTreeListenerDisabled = true;
901
        // will expand the tree and select the node
902
        int i = 0;
903
        boolean exit = false;
904

    
905
        TreePath tp = null;
906
        // find the page in the tree
907
        while (i < jTreeLegends.getRowCount() && !exit) {
908
            // see if this row is the node that we are looking for
909

    
910
            tp = jTreeLegends.getPathForRow(i);
911
            Object[] obj = tp.getPath();
912
            for (int j = 0; j < obj.length && !exit; j++) {
913
                Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
914

    
915
                if (o != null && o.getClass().equals(node.getClass())
916
                    && o.equals(node)) {
917
                    // found it! collapse the tree
918
                    while (i >= 0) {
919
                        jTreeLegends.collapseRow(i);
920
                        i--;
921
                    }
922
                    exit = true;
923
                }
924
            }
925
            jTreeLegends.expandRow(i);
926
            i++;
927
        }
928

    
929
        // expand the tree and set the selection
930
        if (tp != null) {
931
            jTreeLegends.expandPath(tp);
932
            jTreeLegends.setSelectionPath(tp);
933
        }
934
        isTreeListenerDisabled = false;
935
    }
936

    
937
    public String getName() {
938
        return PluginServices.getText(this, "Simbologia");
939
    }
940

    
941
    public void acceptAction() {
942
        // automatically handled by the ThemeManagerWindow
943
    }
944

    
945
    public void cancelAction() {
946
        // does nothing
947
    }
948

    
949
    public void applyAction() {
950
        legend = activePanel.getLegend();
951

    
952
        if (table != null && table.size() > 1)
953
            applyRestOfLegends(table, layer.getMapContext().getLayers());
954

    
955
        /*
956
         * try to apply the legend to all the active layers that
957
         * can accept it
958
         */
959
        FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
960
        for (int i = 0; i < activeLyrs.length; i++) {
961
            FLayer laux = activeLyrs[i];
962

    
963
            if (activeLyrs[i] instanceof FLayers) {
964
                laux = getFirstActiveLayerVect((FLayers) activeLyrs[i]);
965
            }
966

    
967
            if (laux instanceof ClassifiableVectorial) {
968
                ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
969
                try {
970
                    if (legend instanceof IClassifiedVectorLegend) {
971
                        // Es una leyenda que necesita un recordset con un
972
                        // nombre de campo. Comprobamos que ese recordset
973
                        // tiene ese nombre de campo y es del tipo esperado
974
                        IClassifiedVectorLegend cl =
975
                            (IClassifiedVectorLegend) legend;
976

    
977
                        if (aux2 instanceof FLyrVect) {
978

    
979
                            if (cl.getValues().length == 0) {
980
                                JOptionPane.showMessageDialog(
981
                                    (Component) PluginServices.getMainFrame(),
982
                                    PluginServices.getText(this,
983
                                        "no_es_posible_aplicar_leyenda_vacia"));
984
                                return;
985
                            }
986

    
987
                            aux2.setLegend((IVectorLegend) legend);
988
                        }
989
                    } else
990
                        if (legend instanceof IVectorLegend) {
991
                            aux2.setLegend((IVectorLegend) legend);
992
                        }
993
                } catch (LegendLayerException e) {
994
                    NotificationManager.addError(PluginServices.getText(this,
995
                        "legend_exception"), e);
996
                }
997
            }
998
        }
999
    }
1000

    
1001
    private void applyRestOfLegends(Hashtable<FLayer, ILegend> table2,
1002
        FLayers layers) {
1003

    
1004
        for (int i = 0; i < layers.getLayersCount(); i++) {
1005
            FLayer my_layer = layers.getLayer(i);
1006

    
1007
            if (!(my_layer instanceof FLayers)) {
1008
                if (my_layer instanceof ClassifiableVectorial) {
1009
                    try {
1010
                        if (table.containsKey(my_layer)) {
1011
                            ClassifiableVectorial lyr =
1012
                                (ClassifiableVectorial) my_layer;
1013
                            lyr.setLegend((IVectorLegend) table.get(my_layer));
1014
                        }
1015

    
1016
                    } catch (LegendLayerException e) {
1017
                        // TODO Auto-generated catch block
1018
                        e.printStackTrace();
1019
                    }
1020
                }
1021
            } else
1022
                applyRestOfLegends(table, (FLayers) my_layer);
1023
        }
1024
    }
1025

    
1026
    @Override
1027
    public void setModel(FLayer layer) {
1028
        this.layer = layer;
1029
        applyLegend(((Classifiable) layer).getLegend());
1030
    }
1031

    
1032
    /**
1033
     * Applies the legend to the layer.
1034
     * 
1035
     * @param aLegend
1036
     *            , legend that the user wants to apply
1037
     */
1038
    private void applyLegend(ILegend aLegend) {
1039
        this.legend = aLegend;
1040
        fillDialog();
1041
        Enumeration<Class<? extends ILegendPanel>> en = pages.keys();
1042
        while (en.hasMoreElements()) {
1043
            ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
1044
            if (legend.getClass().equals(page.getLegendClass())) {
1045
                setActivePage(page);
1046
                expandAndSelect(page);
1047
                return;
1048
            }
1049
        }
1050
        NotificationManager.addWarning(PluginServices.getText(this,
1051
            "caution_no_registered_panel_associated_to_"
1052
                + "loaded_legend_the_legend_wont_be_applied"));
1053
    }
1054

    
1055
    // public static void addLegendDriver(Class<? extends IFMapLegendDriver>
1056
    // legendDriverClass) {
1057
    // if (!legendDriverPool.contains(legendDriverClass)) {
1058
    // legendDriverPool.add(legendDriverClass);
1059
    // }
1060
    // }
1061
}