Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / applications / appgvSIG / src / org / gvsig / app / project / documents / view / legend / gui / LegendManager.java @ 40337

History | View | Annotate | Download (38.4 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.TreePath;
79
import javax.swing.tree.TreeSelectionModel;
80

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

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

    
107
    private static final long serialVersionUID = 7989057553773181019L;
108
    private static ArrayList<Class<? extends ILegendPanel>> legendPool =
109
        new ArrayList<Class<? extends ILegendPanel>>();
110
    // private static ArrayList<Class<? extends IFMapLegendDriver>>
111
    // legendDriverPool = new ArrayList<Class<? extends IFMapLegendDriver>>();
112

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

    
137
    public static String defaultLegendFolderPath;
138
    {
139

    
140
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
141
        defaultLegendFolderPath = prefs.get("LegendsFolder", "");
142
    }
143
    private ActionListener loadSaveLegendAction = new ActionListener() {
144

    
145
        public void actionPerformed(java.awt.event.ActionEvent e) {
146
            JComponent c = (JComponent) e.getSource();
147
            if (c.equals(getBtnSaveLegend())) {
148
                saveLegend();
149

    
150
            } else
151
                if (c.equals(getBtnLoadLegend())) {
152
                    loadLegend();
153
                }
154
        }
155

    
156
        private void saveLegend() {
157
            ILegend legend = activePanel.getLegend();
158

    
159
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
160
            JFileChooser fileChooser = new JFileChooser();
161
            fileChooser.setAcceptAllFileFilterUsed(false);
162

    
163
            fileChooser.setFileFilter(new FileFilter() {
164

    
165
                @Override
166
                public String getDescription() {
167
                    return "Legend files (*"
168
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
169
                }
170

    
171
                @Override
172
                public boolean accept(File f) {
173
                    if (f.isDirectory()) {
174
                        return true;
175
                    } else
176
                        if (f.isFile() && getExtension(f) != null) {
177
                            return getExtension(f).equals(
178
                                SymbolManager.LEGEND_FILE_EXTENSION);
179
                        } else {
180
                            return false;
181
                        }
182
                }
183
            });
184

    
185
            if (fileChooser.showSaveDialog((Component) PluginServices
186
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
187
                OutputStream os;
188
                File selectedFile = fileChooser.getSelectedFile();
189

    
190
                if (getExtension(selectedFile) == null
191
                    || !getExtension(selectedFile).equals(
192
                        SymbolManager.LEGEND_FILE_EXTENSION)) {
193
                    File selectedFileWithExtension =
194
                        new File(selectedFile.getAbsolutePath()
195
                            + SymbolManager.LEGEND_FILE_EXTENSION);
196
                    selectedFile = selectedFileWithExtension;
197
                }
198

    
199
                try {
200
                    os = new FileOutputStream(selectedFile);
201
                } catch (FileNotFoundException e) {
202
                    JOptionPane.showMessageDialog(null,
203
                        "_cant_open_the_input_file_legend");
204
                    return;
205
                }
206

    
207
                manager.putObject(os, legend);
208
            }
209
        }
210

    
211
        private void loadLegend() {
212

    
213
            JFileChooser fileChooser = new JFileChooser();
214
            fileChooser.setAcceptAllFileFilterUsed(false);
215

    
216
            // fileChooser filter
217
            fileChooser.setFileFilter(new FileFilter() {
218

    
219
                @Override
220
                public String getDescription() {
221
                    // get this extension from manager or somewhere!
222

    
223
                    return "Legend files (*"
224
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
225
                }
226

    
227
                @Override
228
                public boolean accept(File f) {
229
                    if (f.isDirectory()) {
230
                        return true;
231
                    } else
232
                        if (f.isFile() && getExtension(f) != null) {
233

    
234
                            return getExtension(f).equals(
235
                                SymbolManager.LEGEND_FILE_EXTENSION);
236
                        } else {
237
                            return false;
238
                        }
239
                }
240
            });
241

    
242
            // open a file
243
            if (fileChooser.showOpenDialog((Component) PluginServices
244
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
245
                File file = fileChooser.getSelectedFile();
246
                PersistenceManager manager =
247
                    ToolsLocator.getPersistenceManager();
248
                InputStream is;
249

    
250
                try {
251
                    is = new FileInputStream(file);
252
                } catch (FileNotFoundException e) {
253
                    JOptionPane.showMessageDialog(null,
254
                        "_cant_open_the_input_file_legend");
255
                    return;
256
                }
257
                ILegend legend = (ILegend) manager.getObject(is);
258
                applyLegend(legend);
259
            }
260
        }
261
    };
262

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

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

    
464
    private String getExtension(File f) {
465
        String ext = null;
466
        String s = f.getName();
467
        int i = s.lastIndexOf('.');
468

    
469
        if (i > 0 && i < s.length() - 1) {
470
            // ext = s.substring(i + 1).toLowerCase();
471
            ext = s.substring(i).toLowerCase();
472
        }
473
        return ext;
474
    }
475

    
476
    public LegendManager() {
477
        initialize();
478
    }
479

    
480
    private void initialize() {
481
        setLayout(new BorderLayout());
482
        add(getTopPanel(), BorderLayout.NORTH);
483
        add(getSplitPane(), BorderLayout.CENTER);
484
        setSize(500, 360);
485
        treeModel = new DefaultTreeModel(root);
486
    }
487

    
488
    private JSplitPane getSplitPane() {
489
        if (jSplitPane == null) {
490
            jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
491
            JPanel aux = new JPanel(new BorderLayout(0, 5));
492
            aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
493
            aux.add(getPreviewPanel(), BorderLayout.SOUTH);
494
            jSplitPane.setLeftComponent(aux);
495
            jSplitPane.setRightComponent(getCentralPanel());
496
            jSplitPane.setDividerLocation(150);
497
        }
498
        return jSplitPane;
499
    }
500

    
501
    private JPanel getCentralPanel() {
502
        if (jCentralPanel == null) {
503
            jCentralPanel = new JPanel(new BorderLayout(0, 10));
504
            jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
505
            jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
506
        }
507
        return jCentralPanel;
508
    }
509

    
510
    private JScrollPane getJPanelContainer() {
511
        if (jPanelContainer == null) {
512
            jPanelContainer = new JScrollPane();
513
        }
514
        return jPanelContainer;
515
    }
516

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

    
536
    private JButton getBtnSaveLegend() {
537
        if (btnSaveLegend == null) {
538
            btnSaveLegend =
539
                new JButton(PluginServices.getText(this, "Guardar_leyenda")
540
                    + "...");
541
            btnSaveLegend.addActionListener(loadSaveLegendAction);
542
        }
543
        return btnSaveLegend;
544
    }
545

    
546
    private JButton getBtnLoadLegend() {
547
        if (btnLoadLegend == null) {
548
            btnLoadLegend =
549
                new JButton(PluginServices.getText(this, "Recuperar_leyenda")
550
                    + "...");
551
            btnLoadLegend.addActionListener(loadSaveLegendAction);
552
        }
553
        return btnLoadLegend;
554
    }
555

    
556
    /**
557
     * This method initializes jTextArea
558
     * 
559
     * @return javax.swing.JTextArea
560
     */
561
    private JTextArea getTitleArea() {
562
        if (titleArea == null) {
563
            titleArea = new JTextArea();
564
            titleArea.setBackground(java.awt.SystemColor.control);
565
            titleArea.setLineWrap(true);
566
            titleArea.setRows(0);
567
            titleArea.setWrapStyleWord(false);
568
            titleArea.setEditable(false);
569
            titleArea.setPreferredSize(new java.awt.Dimension(495, 40));
570
        }
571
        return titleArea;
572
    }
573

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

    
594
    private JLabel getIconLabel() {
595
        if (iconLabel == null) {
596
            iconLabel = new JLabel();
597
            iconLabel.setVerticalAlignment(JLabel.CENTER);
598
            iconLabel.setHorizontalAlignment(JLabel.CENTER);
599
        }
600

    
601
        return iconLabel;
602
    }
603

    
604
    /**
605
     * This method initializes jScrollPane
606
     * 
607
     * @return javax.swing.JScrollPane
608
     */
609
    private JScrollPane getLegendTreeScrollPane() {
610
        if (legendTreeScrollPane == null) {
611
            legendTreeScrollPane = new JScrollPane();
612
            legendTreeScrollPane.setViewportView(getJTreeLegends());
613
        }
614
        return legendTreeScrollPane;
615
    }
616

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

    
643
    /**
644
     * Causes the component to be autofilled with the legend pages that
645
     * were added through the static method addLegendPage(ILegendPanel page)
646
     */
647
    private void fillDialog() {
648
        if (empty) {
649
            for (int i = 0; i < legendPool.size(); i++) {
650
                Class<?> pageClass = (Class<?>) legendPool.get(i);
651
                ILegendPanel page;
652
                try {
653
                    page = (ILegendPanel) pageClass.newInstance();
654
                    if (page.isSuitableFor(layer)) {
655
                        // this legend can be applied to this layer
656
                        pages.put(page.getClass(), page);
657

    
658
                        if (dirtyTree) {
659
                            // rebuild page tree
660
                            dirtyTree = false;
661

    
662
                            ArrayList<ILegendPanel> legList =
663
                                new ArrayList<ILegendPanel>(pages.values());
664
                            ArrayList<ILegendPanel> alreadyAdded =
665
                                new ArrayList<ILegendPanel>();
666
                            DefaultTreeModel model = new DefaultTreeModel(root);
667
                            while (legList.size() > 0) {
668
                                ILegendPanel legend =
669
                                    (ILegendPanel) legList.get(0);
670
                                Class<? extends ILegendPanel> parent =
671
                                    legend.getParentClass();
672
                                while (parent != null
673
                                    && !alreadyAdded
674
                                        .contains(pages.get(parent))) {
675
                                    
676
                                    ILegendPanel par_legend =
677
                                        (ILegendPanel) pages.get(parent);
678
                                    
679
                                    if (par_legend != null) {
680
                                        doInsertNode(model, par_legend);
681
                                        alreadyAdded.add(par_legend);
682
                                        parent = par_legend.getParentClass();
683
                                    } else {
684
                                        parent = null;
685
                                    }
686
                                }
687
                                
688
                                doInsertNode(model, legend);
689
                                legList.remove(legend);
690
                                alreadyAdded.add(legend);
691
                            }
692
                            treeModel = model;
693
                            jTreeLegends.setModel(model);
694
                        }
695
                        doInsertNode(treeModel, page);
696

    
697
                    }
698
                    getJTreeLegends().setModel(treeModel);
699

    
700
                } catch (InstantiationException e) {
701
                    NotificationManager.addError(
702
                        "Trying to instantiate an interface"
703
                            + " or abstract class + " + pageClass.getName(), e);
704
                } catch (IllegalAccessException e) {
705
                    NotificationManager.addError(
706
                        "IllegalAccessException: does " + pageClass.getName()
707
                            + " class have an anonymous" + " constructor?", e);
708
                }
709

    
710
            }
711
            getJTreeLegends().repaint();
712
            empty = false;
713
        }
714
    }
715

    
716
    @SuppressWarnings("unchecked")
717
    private DefaultMutableTreeNode findNode(Class searchID) {
718
        String title;
719
        try {
720
            title =
721
                ((ILegendPanel) Class.forName(searchID.getName()).newInstance())
722
                    .getTitle();
723
        } catch (Exception e) {
724
            // this should be impossible, but anyway this case will be treat as
725
            // the node does not
726
            // exist.
727
            return null;
728
        }
729

    
730
        Enumeration e = root.breadthFirstEnumeration();
731
        while (e.hasMoreElements()) {
732
            DefaultMutableTreeNode nodeAux =
733
                (DefaultMutableTreeNode) e.nextElement();
734
            if (nodeAux != null) {
735
                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
736
                if (legend == null)
737
                    continue; // Root node
738
                if (legend.getTitle().equals(title)) {
739
                    return nodeAux;
740
                }
741
            }
742
        }
743
        return null;
744
    }
745

    
746
    private void doInsertNode(DefaultTreeModel treeModel, ILegendPanel page) {
747
        dirtyTree =
748
            ((page.getParentClass() != null) && (findNode(page.getParentClass()) == null));
749
        if (findNode(page.getClass()) != null) // It is already added
750
            return;
751
        if (page.getParentClass() != null) {
752
            if (pages.containsKey(page.getParentClass())) {
753
                ILegendPanel parent =
754
                    (ILegendPanel) pages.get(page.getParentClass());
755
                DefaultMutableTreeNode nodeParent = findNode(parent.getClass());
756
                if (nodeParent == null) {
757
                    // the parent is empty
758
                    // Recursively add it
759
                    doInsertNode(treeModel, parent);
760
                } else {
761
                    DefaultMutableTreeNode nodeValue =
762
                        new DefaultMutableTreeNode(page);
763
                    int children = nodeParent.getChildCount();
764
                    int pos = 0;
765
                    for (int i = 0; i < children; i++) {
766
                        DefaultMutableTreeNode node =
767
                            (DefaultMutableTreeNode) treeModel.getChild(
768
                                nodeParent, i);
769
                        if (node.getUserObject() instanceof ILegendPanel) {
770
                            String pageTitle =
771
                                ((ILegendPanel) node.getUserObject())
772
                                    .getTitle();
773
                            if (pageTitle.compareTo(page.getTitle()) < 0)
774
                                ++pos;
775
                        }
776
                    }
777
                    treeModel.insertNodeInto(nodeValue, nodeParent, pos);
778
                }
779
            }
780
        } else {
781
            // First level node
782
            DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
783
            int children = root.getChildCount();
784
            int pos = 0;
785
            for (int i = 0; i < children; i++) {
786
                DefaultMutableTreeNode node =
787
                    (DefaultMutableTreeNode) treeModel.getChild(root, i);
788
                if (node.getUserObject() instanceof ILegendPanel) {
789
                    String pageTitle =
790
                        ((ILegendPanel) node.getUserObject()).getTitle();
791
                    if (pageTitle.compareTo(page.getTitle()) < 0)
792
                        ++pos;
793
                }
794
            }
795
            treeModel.insertNodeInto(nodeValue, root, pos);
796
        }
797
    }
798

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

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

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

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

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

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

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

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

    
870
    private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
871

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

    
874
        public MyTreeCellRenderer() {
875
        }
876

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

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

    
896
    }
897

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

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

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

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

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

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

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

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

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

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

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

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

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

    
976
                        if (aux2 instanceof FLyrVect) {
977

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

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

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

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

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

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

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

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

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