Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / view / legend / gui / LegendManager.java @ 40558

History | View | Annotate | Download (35.9 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.project.documents.view.legend.gui;
25

    
26
import java.awt.BorderLayout;
27
import java.awt.Color;
28
import java.awt.Component;
29
import java.awt.Dimension;
30
import java.awt.FlowLayout;
31
import java.awt.event.ActionListener;
32
import java.io.File;
33
import java.io.FileInputStream;
34
import java.io.FileNotFoundException;
35
import java.io.FileOutputStream;
36
import java.io.InputStream;
37
import java.io.OutputStream;
38
import java.util.ArrayList;
39
import java.util.Enumeration;
40
import java.util.Hashtable;
41
import java.util.prefs.Preferences;
42

    
43
import javax.swing.ImageIcon;
44
import javax.swing.JButton;
45
import javax.swing.JComponent;
46
import javax.swing.JFileChooser;
47
import javax.swing.JLabel;
48
import javax.swing.JOptionPane;
49
import javax.swing.JPanel;
50
import javax.swing.JScrollPane;
51
import javax.swing.JSplitPane;
52
import javax.swing.JTextArea;
53
import javax.swing.JTree;
54
import javax.swing.filechooser.FileFilter;
55
import javax.swing.tree.DefaultMutableTreeNode;
56
import javax.swing.tree.DefaultTreeCellRenderer;
57
import javax.swing.tree.DefaultTreeModel;
58
import javax.swing.tree.MutableTreeNode;
59
import javax.swing.tree.TreePath;
60
import javax.swing.tree.TreeSelectionModel;
61

    
62
import org.slf4j.Logger;
63
import org.slf4j.LoggerFactory;
64

    
65
import org.gvsig.andami.PluginServices;
66
import org.gvsig.andami.messages.NotificationManager;
67
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
68
import org.gvsig.fmap.mapcontext.layers.FLayer;
69
import org.gvsig.fmap.mapcontext.layers.FLayers;
70
import org.gvsig.fmap.mapcontext.layers.operations.Classifiable;
71
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
72
import org.gvsig.fmap.mapcontext.layers.vectorial.FLyrVect;
73
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
74
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
75
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
76
import org.gvsig.fmap.mapcontext.rendering.symbols.SymbolManager;
77
import org.gvsig.tools.ToolsLocator;
78
import org.gvsig.tools.persistence.PersistenceManager;
79

    
80
/**
81
 * Implements the panel which allows the user to control all the information
82
 * about the
83
 * legends of a layer in order to improve the information that it offers to the
84
 * user.
85
 * There are options to create, save or load an existing legend.
86
 * 
87
 * @author jaume dominguez faus - jaume.dominguez@iver.es
88
 */
89
public class LegendManager extends AbstractThemeManagerPage {
90

    
91
    private static final Logger logger =
92
        LoggerFactory.getLogger(LegendManager.class);
93
    
94
    private static final long serialVersionUID = 7989057553773181019L;
95
    private static ArrayList<Class<? extends ILegendPanel>> legendPool =
96
        new ArrayList<Class<? extends ILegendPanel>>();
97
    // private static ArrayList<Class<? extends IFMapLegendDriver>>
98
    // legendDriverPool = new ArrayList<Class<? extends IFMapLegendDriver>>();
99

    
100
    private FLayer layer;
101
    private ILegend legend; // Le asignaremos la leyenda del primer tema activo.
102
    private Hashtable<Class<? extends ILegendPanel>, ILegendPanel> pages =
103
        new Hashtable<Class<? extends ILegendPanel>, ILegendPanel>();
104
    private JPanel topPanel = null;
105
    private JTextArea titleArea = null;
106
    private JPanel preview = null;
107
    private JScrollPane jTitleScrollPane = null;
108
    private JTree jTreeLegends;
109
    private ILegendPanel activePanel;
110
    private JScrollPane legendTreeScrollPane;
111
    private boolean dirtyTree_;
112
    private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
113
    private DefaultTreeModel treeModel;
114
    private JScrollPane jPanelContainer;
115
    private JPanel jCentralPanel;
116
    private JSplitPane jSplitPane;
117
    private boolean isTreeListenerDisabled;
118
    private JButton btnSaveLegend;
119
    private JButton btnLoadLegend;
120
    private Hashtable<FLayer, ILegend> table = null;
121
    private boolean empty = true;
122
    private JLabel iconLabel;
123

    
124
    public static String defaultLegendFolderPath;
125
    {
126

    
127
        Preferences prefs = Preferences.userRoot().node("gvsig.foldering");
128
        defaultLegendFolderPath = prefs.get("LegendsFolder", "");
129
    }
130
    private ActionListener loadSaveLegendAction = new ActionListener() {
131

    
132
        public void actionPerformed(java.awt.event.ActionEvent e) {
133
            JComponent c = (JComponent) e.getSource();
134
            if (c.equals(getBtnSaveLegend())) {
135
                saveLegend();
136

    
137
            } else
138
                if (c.equals(getBtnLoadLegend())) {
139
                    loadLegend();
140
                }
141
        }
142

    
143
        private void saveLegend() {
144
            ILegend legend = activePanel.getLegend();
145

    
146
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
147
            JFileChooser fileChooser = new JFileChooser();
148
            fileChooser.setAcceptAllFileFilterUsed(false);
149

    
150
            fileChooser.setFileFilter(new FileFilter() {
151

    
152
                @Override
153
                public String getDescription() {
154
                    return "Legend files (*"
155
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
156
                }
157

    
158
                @Override
159
                public boolean accept(File f) {
160
                    if (f.isDirectory()) {
161
                        return true;
162
                    } else
163
                        if (f.isFile() && getExtension(f) != null) {
164
                            return getExtension(f).equals(
165
                                SymbolManager.LEGEND_FILE_EXTENSION);
166
                        } else {
167
                            return false;
168
                        }
169
                }
170
            });
171

    
172
            if (fileChooser.showSaveDialog((Component) PluginServices
173
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
174
                OutputStream os;
175
                File selectedFile = fileChooser.getSelectedFile();
176

    
177
                if (getExtension(selectedFile) == null
178
                    || !getExtension(selectedFile).equals(
179
                        SymbolManager.LEGEND_FILE_EXTENSION)) {
180
                    File selectedFileWithExtension =
181
                        new File(selectedFile.getAbsolutePath()
182
                            + SymbolManager.LEGEND_FILE_EXTENSION);
183
                    selectedFile = selectedFileWithExtension;
184
                }
185

    
186
                try {
187
                    os = new FileOutputStream(selectedFile);
188
                } catch (FileNotFoundException e) {
189
                    JOptionPane.showMessageDialog(null,
190
                        "_cant_open_the_input_file_legend");
191
                    return;
192
                }
193

    
194
                manager.putObject(os, legend);
195
            }
196
        }
197

    
198
        private void loadLegend() {
199

    
200
            JFileChooser fileChooser = new JFileChooser();
201
            fileChooser.setAcceptAllFileFilterUsed(false);
202

    
203
            // fileChooser filter
204
            fileChooser.setFileFilter(new FileFilter() {
205

    
206
                @Override
207
                public String getDescription() {
208
                    // get this extension from manager or somewhere!
209

    
210
                    return "Legend files (*"
211
                        + SymbolManager.LEGEND_FILE_EXTENSION + ")";
212
                }
213

    
214
                @Override
215
                public boolean accept(File f) {
216
                    if (f.isDirectory()) {
217
                        return true;
218
                    } else
219
                        if (f.isFile() && getExtension(f) != null) {
220

    
221
                            return getExtension(f).equals(
222
                                SymbolManager.LEGEND_FILE_EXTENSION);
223
                        } else {
224
                            return false;
225
                        }
226
                }
227
            });
228

    
229
            // open a file
230
            if (fileChooser.showOpenDialog((Component) PluginServices
231
                .getMainFrame()) == JFileChooser.APPROVE_OPTION) {
232
                File file = fileChooser.getSelectedFile();
233
                PersistenceManager manager =
234
                    ToolsLocator.getPersistenceManager();
235
                InputStream is;
236

    
237
                try {
238
                    is = new FileInputStream(file);
239
                } catch (FileNotFoundException e) {
240
                    JOptionPane.showMessageDialog(null,
241
                        "_cant_open_the_input_file_legend");
242
                    return;
243
                }
244
                ILegend legend = (ILegend) manager.getObject(is);
245
                applyLegend(legend);
246
            }
247
        }
248
    };
249

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

    
431
    // private IFMapLegendDriver[] getLegendDrivers() {
432
    // Class<?>[] legendDriverClasses = legendDriverPool.toArray(new Class[0]);
433
    // ArrayList<IFMapLegendDriver> drivers = new
434
    // ArrayList<IFMapLegendDriver>();
435
    // for (int i = 0; i < legendDriverClasses.length; i++) {
436
    // String message = PluginServices.getText(this,
437
    // "adding_legend_file_format_support")+": ";
438
    // try {
439
    // Class<?> c = legendDriverClasses[i];
440
    // drivers.add((IFMapLegendDriver) c.newInstance());
441
    // } catch (Exception e) {
442
    // NotificationManager.addError(message+PluginServices.getText(this,
443
    // "failed"), e);
444
    // }
445
    // NotificationManager.addInfo(message+PluginServices.getText(this, "OK"));
446
    //
447
    // }
448
    // return (IFMapLegendDriver[]) drivers.toArray(new IFMapLegendDriver[0]);
449
    // };
450

    
451
    private String getExtension(File f) {
452
        String ext = null;
453
        String s = f.getName();
454
        int i = s.lastIndexOf('.');
455

    
456
        if (i > 0 && i < s.length() - 1) {
457
            // ext = s.substring(i + 1).toLowerCase();
458
            ext = s.substring(i).toLowerCase();
459
        }
460
        return ext;
461
    }
462

    
463
    public LegendManager() {
464
        initialize();
465
    }
466

    
467
    private void initialize() {
468
        setLayout(new BorderLayout());
469
        add(getTopPanel(), BorderLayout.NORTH);
470
        add(getSplitPane(), BorderLayout.CENTER);
471
        setSize(500, 360);
472
        treeModel = new DefaultTreeModel(root);
473
    }
474

    
475
    private JSplitPane getSplitPane() {
476
        if (jSplitPane == null) {
477
            jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
478
            JPanel aux = new JPanel(new BorderLayout(0, 5));
479
            aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
480
            aux.add(getPreviewPanel(), BorderLayout.SOUTH);
481
            jSplitPane.setLeftComponent(aux);
482
            jSplitPane.setRightComponent(getCentralPanel());
483
            jSplitPane.setDividerLocation(150);
484
        }
485
        return jSplitPane;
486
    }
487

    
488
    private JPanel getCentralPanel() {
489
        if (jCentralPanel == null) {
490
            jCentralPanel = new JPanel(new BorderLayout(0, 10));
491
            jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
492
            jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
493
        }
494
        return jCentralPanel;
495
    }
496

    
497
    private JScrollPane getJPanelContainer() {
498
        if (jPanelContainer == null) {
499
            jPanelContainer = new JScrollPane();
500
        }
501
        return jPanelContainer;
502
    }
503

    
504
    /**
505
     * This method initializes jPanel
506
     * 
507
     * @return javax.swing.JPanel
508
     */
509
    private JPanel getTopPanel() {
510
        if (topPanel == null) {
511
            topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
512
            topPanel.setPreferredSize(new Dimension(638, 31));
513
            topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(
514
                null, "",
515
                javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
516
                javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
517
            topPanel.add(getBtnSaveLegend(), null);
518
            topPanel.add(getBtnLoadLegend(), null);
519
        }
520
        return topPanel;
521
    }
522

    
523
    private JButton getBtnSaveLegend() {
524
        if (btnSaveLegend == null) {
525
            btnSaveLegend =
526
                new JButton(PluginServices.getText(this, "Guardar_leyenda")
527
                    + "...");
528
            btnSaveLegend.addActionListener(loadSaveLegendAction);
529
        }
530
        return btnSaveLegend;
531
    }
532

    
533
    private JButton getBtnLoadLegend() {
534
        if (btnLoadLegend == null) {
535
            btnLoadLegend =
536
                new JButton(PluginServices.getText(this, "Recuperar_leyenda")
537
                    + "...");
538
            btnLoadLegend.addActionListener(loadSaveLegendAction);
539
        }
540
        return btnLoadLegend;
541
    }
542

    
543
    /**
544
     * This method initializes jTextArea
545
     * 
546
     * @return javax.swing.JTextArea
547
     */
548
    private JTextArea getTitleArea() {
549
        if (titleArea == null) {
550
            titleArea = new JTextArea();
551
            titleArea.setBackground(java.awt.SystemColor.control);
552
            titleArea.setLineWrap(true);
553
            titleArea.setRows(0);
554
            titleArea.setWrapStyleWord(false);
555
            titleArea.setEditable(false);
556
            titleArea.setPreferredSize(new java.awt.Dimension(495, 40));
557
        }
558
        return titleArea;
559
    }
560

    
561
    /**
562
     * This method initializes jPanel1
563
     * 
564
     * @return javax.swing.JPanel
565
     */
566
    private JPanel getPreviewPanel() {
567
        if (preview == null) {
568
            preview = new JPanel();
569
            preview.setBorder(javax.swing.BorderFactory
570
                .createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
571
            preview.setBackground(java.awt.SystemColor.text);
572
            preview.setLayout(new BorderLayout(5, 5));
573
            preview.add(getIconLabel());
574
            preview.setPreferredSize(new Dimension(getSplitPane()
575
                .getDividerLocation(), 130));
576
            preview.setBackground(Color.white);
577
        }
578
        return preview;
579
    }
580

    
581
    private JLabel getIconLabel() {
582
        if (iconLabel == null) {
583
            iconLabel = new JLabel();
584
            iconLabel.setVerticalAlignment(JLabel.CENTER);
585
            iconLabel.setHorizontalAlignment(JLabel.CENTER);
586
        }
587

    
588
        return iconLabel;
589
    }
590

    
591
    /**
592
     * This method initializes jScrollPane
593
     * 
594
     * @return javax.swing.JScrollPane
595
     */
596
    private JScrollPane getLegendTreeScrollPane() {
597
        if (legendTreeScrollPane == null) {
598
            legendTreeScrollPane = new JScrollPane();
599
            legendTreeScrollPane.setViewportView(getJTreeLegends());
600
        }
601
        return legendTreeScrollPane;
602
    }
603

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

    
630
    /**
631
     * Causes the component to be autofilled with the legend pages that
632
     * were added through the static method addLegendPage(ILegendPanel page)
633
     */
634
    private void fillDialog() {
635
        if (empty) {
636
            
637
            Class<?> pageClass = null;
638
            ILegendPanel page = null;
639
            
640
            for (int i = 0; i < legendPool.size(); i++) {
641
                pageClass = (Class<?>) legendPool.get(i);
642
                try {
643
                    page = (ILegendPanel) pageClass.newInstance();
644
                } catch (Exception e) {
645
                    logger.info("Unable to instantiate legend panel.", e);
646
                }
647
                if (page != null && page.isSuitableFor(layer)) {
648
                    pages.put(page.getClass(), page); // this legend can be applied
649
                }
650
            }
651
            
652
            Enumeration<ILegendPanel> enume = pages.elements();
653
            while (enume.hasMoreElements()) {
654
                page = enume.nextElement();
655
                doInsertNode(treeModel, page);
656
            }
657

    
658
            getJTreeLegends().setModel(treeModel);
659
            getJTreeLegends().repaint();
660
            empty = false;
661
        }
662
    }
663

    
664
    @SuppressWarnings("unchecked")
665
    private DefaultMutableTreeNode findNode(Class searchID) {
666
        String title;
667
        try {
668
            title =
669
                ((ILegendPanel) Class.forName(searchID.getName()).newInstance())
670
                    .getTitle();
671
        } catch (Exception e) {
672
            // this should be impossible, but anyway this case will be treat as
673
            // the node does not
674
            // exist.
675
            return null;
676
        }
677

    
678
        Enumeration e = root.breadthFirstEnumeration();
679
        while (e.hasMoreElements()) {
680
            DefaultMutableTreeNode nodeAux =
681
                (DefaultMutableTreeNode) e.nextElement();
682
            if (nodeAux != null) {
683
                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
684
                if (legend == null)
685
                    continue; // Root node
686
                if (legend.getTitle().equals(title)) {
687
                    return nodeAux;
688
                }
689
            }
690
        }
691
        return null;
692
    }
693

    
694
    /**
695
     * If parent_node == null, add to root.
696
     * Returns added node
697
     * 
698
     * @param tm
699
     * @param parent_node
700
     * @param item
701
     */
702
    private MutableTreeNode insertNodeHere(
703
        DefaultTreeModel tm,
704
        MutableTreeNode parent_node,
705
        ILegendPanel item) {
706
        
707
        MutableTreeNode pn = null;
708
        
709
        if (parent_node == null) {
710
            pn = root;
711
        } else {
712
            pn = parent_node;
713
        }
714
        
715
        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(item);
716
        int children = pn.getChildCount();
717
        int pos = 0;
718
        String pTitle = null;
719
        
720
        for (int i = 0; i < children; i++) {
721
            DefaultMutableTreeNode node =
722
                (DefaultMutableTreeNode) tm.getChild(pn, i);
723
            if (node.getUserObject() instanceof ILegendPanel) {
724
                pTitle = ((ILegendPanel) node.getUserObject()).getTitle();
725
                if (pTitle.compareTo(item.getTitle()) < 0) {
726
                    pos++;
727
                }
728
            }
729
        }
730
        tm.insertNodeInto(nodeValue, pn, pos);
731
        return nodeValue;
732
    }
733
    
734
    /**
735
     * Returns inserted node
736
     * 
737
     * @param tm
738
     * @param page
739
     * @return
740
     */
741
    private MutableTreeNode doInsertNode(DefaultTreeModel tm, ILegendPanel page) {
742
        
743
        if (tm == null || page == null) {
744
            return null;
745
        }
746
        
747
        MutableTreeNode aux = findNode(page.getClass()); 
748
        if (aux != null) {
749
            return aux;
750
        }
751

    
752
        Class parent_class = page.getParentClass();
753
        
754
        if (parent_class != null) {
755
            if (pages.containsKey(parent_class)) {
756
                ILegendPanel parent = (ILegendPanel) pages.get(parent_class);
757
                
758
                aux = doInsertNode(tm, parent); 
759
                if (aux != null) {
760
                    return insertNodeHere(tm, aux, page);
761
                } else {
762
                    return null;
763
                }
764
                
765
            } else {
766
                return null;
767
            }
768
        } else {
769
            // add to root
770
            return insertNodeHere(tm, null, page);
771
        }
772
        
773

    
774
    }
775
    
776
    
777
    
778
    
779

    
780
    private JScrollPane getTitleScroll() {
781
        if (jTitleScrollPane == null) {
782
            jTitleScrollPane = new JScrollPane();
783
            jTitleScrollPane.setBounds(2, 2, 498, 42);
784
            jTitleScrollPane.setViewportView(getTitleArea());
785
        }
786
        return jTitleScrollPane;
787
    }
788

    
789
    private JTree getJTreeLegends() {
790
        if (jTreeLegends == null) {
791
            jTreeLegends = new JTree();
792
            jTreeLegends.setRootVisible(false);
793
            MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
794
            treeCellRenderer.setOpenIcon(null);
795
            treeCellRenderer.setClosedIcon(null);
796
            treeCellRenderer.setLeafIcon(null);
797

    
798
            jTreeLegends.setCellRenderer(treeCellRenderer);
799
            jTreeLegends.setShowsRootHandles(true);
800
            jTreeLegends
801
                .addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
802

    
803
                    public void valueChanged(
804
                        javax.swing.event.TreeSelectionEvent e) {
805
                        if (isTreeListenerDisabled)
806
                            return;
807
                        DefaultMutableTreeNode node =
808
                            (DefaultMutableTreeNode) jTreeLegends
809
                                .getLastSelectedPathComponent();
810

    
811
                        if (node == null)
812
                            return;
813
                        setActivePage((ILegendPanel) node.getUserObject());
814
                    }
815
                });
816
            jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
817
            jTreeLegends.getSelectionModel().setSelectionMode(
818
                TreeSelectionModel.SINGLE_TREE_SELECTION);
819
        }
820
        return jTreeLegends;
821
    }
822

    
823
    private void setActivePage(ILegendPanel page) {
824
        if (page.getPanel() == null) {
825
            // this is what happens when the user clicked in a parent node
826
            // which only acts as a folder, and does not manage any legend
827
            // then it expands and selects the first child
828
            DefaultMutableTreeNode node = findNode(page.getClass());
829
            if (treeModel.getChildCount(node) > 0) {
830
                DefaultMutableTreeNode dmn =
831
                    (DefaultMutableTreeNode) treeModel.getChild(node, 0);
832
                page = (ILegendPanel) dmn.getUserObject();
833
                setActivePage(page);
834
                expandAndSelect(page);
835
            }
836
        } else {
837
            // show the page
838
            activePanel = page;
839
            setIcon(activePanel.getIcon());
840

    
841
            activePanel.setData(layer, legend);
842
            getTitleArea().setText(activePanel.getDescription());
843
            jPanelContainer.setViewportView(activePanel.getPanel());
844
        }
845
    }
846

    
847
    private void setIcon(ImageIcon icon) {
848
        getIconLabel().setIcon(icon);
849
    }
850

    
851
    private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
852

    
853
        private static final long serialVersionUID = -6013698992263578041L;
854

    
855
        public MyTreeCellRenderer() {
856
        }
857

    
858
        public Component getTreeCellRendererComponent(JTree tree, Object value,
859
            boolean sel, boolean expanded, boolean leaf, int row,
860
            boolean hasFocus) {
861

    
862
            super.getTreeCellRendererComponent(tree, value, sel, expanded,
863
                leaf, row, hasFocus);
864
            if (value instanceof DefaultMutableTreeNode) {
865
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
866
                if (node.getUserObject() instanceof ILegendPanel) {
867
                    ILegendPanel legend = (ILegendPanel) node.getUserObject();
868
                    this
869
                        .setText(legend.getPanel() == null ? "<html><b>"
870
                            + legend.getTitle() + "</b></html>" : legend
871
                            .getTitle());
872
                }
873
            }
874
            return this;
875
        }
876

    
877
    }
878

    
879
    private void expandAndSelect(Object node) {
880
        isTreeListenerDisabled = true;
881
        // will expand the tree and select the node
882
        int i = 0;
883
        boolean exit = false;
884

    
885
        TreePath tp = null;
886
        // find the page in the tree
887
        while (i < jTreeLegends.getRowCount() && !exit) {
888
            // see if this row is the node that we are looking for
889

    
890
            tp = jTreeLegends.getPathForRow(i);
891
            Object[] obj = tp.getPath();
892
            for (int j = 0; j < obj.length && !exit; j++) {
893
                Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
894

    
895
                if (o != null && o.getClass().equals(node.getClass())
896
                    && o.equals(node)) {
897
                    // found it! collapse the tree
898
                    while (i >= 0) {
899
                        jTreeLegends.collapseRow(i);
900
                        i--;
901
                    }
902
                    exit = true;
903
                }
904
            }
905
            jTreeLegends.expandRow(i);
906
            i++;
907
        }
908

    
909
        // expand the tree and set the selection
910
        if (tp != null) {
911
            jTreeLegends.expandPath(tp);
912
            jTreeLegends.setSelectionPath(tp);
913
        }
914
        isTreeListenerDisabled = false;
915
    }
916

    
917
    public String getName() {
918
        return PluginServices.getText(this, "Simbologia");
919
    }
920

    
921
    public void acceptAction() {
922
        // automatically handled by the ThemeManagerWindow
923
    }
924

    
925
    public void cancelAction() {
926
        // does nothing
927
    }
928

    
929
    public void applyAction() {
930
        legend = activePanel.getLegend();
931

    
932
        if (table != null && table.size() > 1)
933
            applyRestOfLegends(table, layer.getMapContext().getLayers());
934

    
935
        /*
936
         * try to apply the legend to all the active layers that
937
         * can accept it
938
         */
939
        FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
940
        for (int i = 0; i < activeLyrs.length; i++) {
941
            FLayer laux = activeLyrs[i];
942

    
943
            if (activeLyrs[i] instanceof FLayers) {
944
                laux = getFirstActiveLayerVect((FLayers) activeLyrs[i]);
945
            }
946

    
947
            if (laux instanceof ClassifiableVectorial) {
948
                ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
949
                try {
950
                    if (legend instanceof IClassifiedVectorLegend) {
951
                        // Es una leyenda que necesita un recordset con un
952
                        // nombre de campo. Comprobamos que ese recordset
953
                        // tiene ese nombre de campo y es del tipo esperado
954
                        IClassifiedVectorLegend cl =
955
                            (IClassifiedVectorLegend) legend;
956

    
957
                        if (aux2 instanceof FLyrVect) {
958

    
959
                            if (cl.getValues().length == 0) {
960
                                JOptionPane.showMessageDialog(
961
                                    (Component) PluginServices.getMainFrame(),
962
                                    PluginServices.getText(this,
963
                                        "no_es_posible_aplicar_leyenda_vacia"));
964
                                return;
965
                            }
966

    
967
                            aux2.setLegend((IVectorLegend) legend);
968
                        }
969
                    } else
970
                        if (legend instanceof IVectorLegend) {
971
                            aux2.setLegend((IVectorLegend) legend);
972
                        }
973
                } catch (LegendLayerException e) {
974
                    NotificationManager.addError(PluginServices.getText(this,
975
                        "legend_exception"), e);
976
                }
977
            }
978
        }
979
    }
980

    
981
    private void applyRestOfLegends(Hashtable<FLayer, ILegend> table2,
982
        FLayers layers) {
983

    
984
        for (int i = 0; i < layers.getLayersCount(); i++) {
985
            FLayer my_layer = layers.getLayer(i);
986

    
987
            if (!(my_layer instanceof FLayers)) {
988
                if (my_layer instanceof ClassifiableVectorial) {
989
                    try {
990
                        if (table.containsKey(my_layer)) {
991
                            ClassifiableVectorial lyr =
992
                                (ClassifiableVectorial) my_layer;
993
                            lyr.setLegend((IVectorLegend) table.get(my_layer));
994
                        }
995

    
996
                    } catch (LegendLayerException e) {
997
                        // TODO Auto-generated catch block
998
                        e.printStackTrace();
999
                    }
1000
                }
1001
            } else
1002
                applyRestOfLegends(table, (FLayers) my_layer);
1003
        }
1004
    }
1005

    
1006
    @Override
1007
    public void setModel(FLayer layer) {
1008
        this.layer = layer;
1009
        applyLegend(((Classifiable) layer).getLegend());
1010
    }
1011

    
1012
    /**
1013
     * Applies the legend to the layer.
1014
     * 
1015
     * @param aLegend
1016
     *            , legend that the user wants to apply
1017
     */
1018
    private void applyLegend(ILegend aLegend) {
1019
        this.legend = aLegend;
1020
        fillDialog();
1021
        Enumeration<Class<? extends ILegendPanel>> en = pages.keys();
1022
        while (en.hasMoreElements()) {
1023
            ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
1024
            if (legend.getClass().equals(page.getLegendClass())) {
1025
                setActivePage(page);
1026
                expandAndSelect(page);
1027
                return;
1028
            }
1029
        }
1030
        NotificationManager.addWarning(PluginServices.getText(this,
1031
            "caution_no_registered_panel_associated_to_"
1032
                + "loaded_legend_the_legend_wont_be_applied"));
1033
    }
1034

    
1035
    // public static void addLegendDriver(Class<? extends IFMapLegendDriver>
1036
    // legendDriverClass) {
1037
    // if (!legendDriverPool.contains(legendDriverClass)) {
1038
    // legendDriverPool.add(legendDriverClass);
1039
    // }
1040
    // }
1041
}