Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / legend / gui / LegendManager.java @ 17170

History | View | Annotate | Download (27.6 KB)

1 10679 jaume
/*
2
 * Created on 08-feb-2005
3
 *
4 12805 jaume
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5 10679 jaume
 *
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 12805 jaume
 *   Av. Blasco Ib??ez, 50
27 10679 jaume
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
package com.iver.cit.gvsig.project.documents.view.legend.gui;
45
46
import java.awt.BorderLayout;
47 14313 jdominguez
import java.awt.Color;
48 10679 jaume
import java.awt.Component;
49
import java.awt.Dimension;
50 14868 jdominguez
import java.awt.FlowLayout;
51
import java.awt.event.ActionListener;
52
import java.io.File;
53
import java.io.FileNotFoundException;
54
import java.io.FileReader;
55
import java.io.FileWriter;
56 16232 jdominguez
import java.io.IOException;
57 10679 jaume
import java.util.ArrayList;
58
import java.util.Enumeration;
59
import java.util.Hashtable;
60 16232 jdominguez
import java.util.prefs.Preferences;
61 10679 jaume
62
import javax.swing.JCheckBox;
63
import javax.swing.JComboBox;
64 14868 jdominguez
import javax.swing.JComponent;
65 10679 jaume
import javax.swing.JLabel;
66
import javax.swing.JOptionPane;
67
import javax.swing.JPanel;
68
import javax.swing.JScrollPane;
69
import javax.swing.JSplitPane;
70
import javax.swing.JTextArea;
71
import javax.swing.JTree;
72
import javax.swing.tree.DefaultMutableTreeNode;
73
import javax.swing.tree.DefaultTreeCellRenderer;
74
import javax.swing.tree.DefaultTreeModel;
75
import javax.swing.tree.TreePath;
76
import javax.swing.tree.TreeSelectionModel;
77
78 14868 jdominguez
import org.exolab.castor.xml.MarshalException;
79
import org.exolab.castor.xml.Marshaller;
80
import org.exolab.castor.xml.ValidationException;
81
import org.gvsig.gui.beans.swing.JButton;
82 17170 jdominguez
import org.gvsig.gui.beans.swing.JFileChooser;
83 14868 jdominguez
84 16232 jdominguez
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
85 10679 jaume
import com.iver.andami.PluginServices;
86
import com.iver.andami.messages.NotificationManager;
87
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
88
import com.iver.cit.gvsig.fmap.layers.FLayer;
89
import com.iver.cit.gvsig.fmap.layers.FLayers;
90 16232 jdominguez
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
91 14868 jdominguez
import com.iver.cit.gvsig.fmap.layers.XMLException;
92 10679 jaume
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
93
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
94
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
95 13881 jaume
import com.iver.cit.gvsig.fmap.rendering.IClassifiedVectorLegend;
96 11558 jaume
import com.iver.cit.gvsig.fmap.rendering.ILegend;
97 13881 jaume
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
98 14868 jdominguez
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
99 12727 jaume
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
100 10679 jaume
import com.iver.cit.gvsig.gui.styling.SymbolPreviewer;
101 14868 jdominguez
import com.iver.utiles.GenericFileFilter;
102
import com.iver.utiles.XMLEntity;
103
import com.iver.utiles.xmlEntity.generate.XmlTag;
104 10679 jaume
/**
105 16232 jdominguez
 * Implements the panel which allows the user to control all the information about the
106
 * legends of a layer in order to improve the information that it offers to the user.
107
 * There are options to create, save or load an existing legend.
108 10679 jaume
 *
109
 * @author jaume dominguez faus - jaume.dominguez@iver.es
110
 */
111
public class LegendManager extends AbstractThemeManagerPage {
112 17170 jdominguez
        private static final String LEGEND_FILECHOOSER_ID = "LEGEND_FILECHOOSER";
113 10679 jaume
        private static ArrayList legendPool = new ArrayList();
114
    private FLayer layer;
115 11558 jaume
    private ILegend legend; // Le asignaremos la leyenda del primer tema activo.
116 10679 jaume
    private Hashtable pages = new Hashtable();
117
    private JPanel topPanel = null;
118
    private JLabel jLabel = null;
119
    private JComboBox jComboBox = null;
120
    private JCheckBox jCheckBox = null;
121
    private JTextArea titleArea = null;
122
    private SymbolPreviewer preview = null;
123
    private JScrollPane jTitleScrollPane = null;
124
    private JTree jTreeLegends;
125
    private ILegendPanel activePanel;
126
    private JScrollPane legendTreeScrollPane;
127
    private boolean dirtyTree;
128
    private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
129
    private DefaultTreeModel treeModel;
130
    private JScrollPane jPanelContainer;
131
        private JPanel jCentralPanel;
132
        private JSplitPane jSplitPane;
133
        private boolean isTreeListenerDisabled;
134 14868 jdominguez
        private JButton btnSaveLegend;
135
        private JButton btnLoadLegend;
136 16232 jdominguez
137
138
        public static String defaultLegendFolderPath;
139
        {
140
141
                Preferences prefs = Preferences.userRoot().node( "gvsig.foldering" );
142
                defaultLegendFolderPath = prefs.get("LegendsFolder", "");
143
        }
144 14868 jdominguez
        private ActionListener loadSaveLegendAction = new ActionListener() {
145
                public void actionPerformed(java.awt.event.ActionEvent e) {
146
                        JComponent c = (JComponent) e.getSource();
147
                        if (c.equals(getBtnSaveLegend())) {
148 17170 jdominguez
                                JFileChooser jfc = new JFileChooser(LEGEND_FILECHOOSER_ID, defaultLegendFolderPath);
149 14868 jdominguez
                                jfc.addChoosableFileFilter(new GenericFileFilter("sld","*.sld"));
150
                                jfc.addChoosableFileFilter(new GenericFileFilter("gvl",
151
                                                PluginServices.getText(this, "tipo_de_leyenda")));
152
                                File basedir = null;
153
                                Object[] options = {PluginServices.getText(this, "yes"),
154 16232 jdominguez
                                                PluginServices.getText(this, "no"),
155
                                                PluginServices.getText(this, "Cancel")};
156 10679 jaume
157 16232 jdominguez
                                jfc.setCurrentDirectory(basedir);
158
                                if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
159
                                        File file=jfc.getSelectedFile();
160
                                        if (file.exists()) {
161
                                                int answer = JOptionPane.showOptionDialog((Component)PluginServices.getMainFrame(),
162
                                                                PluginServices.getText(this, "error_file_exists"),
163
                                                                PluginServices.getText(this, "confirmation_dialog"),
164
                                                                JOptionPane.YES_NO_CANCEL_OPTION,
165
                                                                JOptionPane.QUESTION_MESSAGE,
166
                                                                null,
167
                                                                options, options[1]);
168
                                                if (answer!=JOptionPane.OK_OPTION) {
169
                                                        // 'Cancel' pressed or window closed: don't save anythig, exit save dialog
170
                                                        return;
171 14868 jdominguez
                                                }
172 16232 jdominguez
                                        }
173
                                        if (jfc.getFileFilter().accept(new File("dummy.sld")))                                         {
174
                                                if (!(file.getPath().toLowerCase().endsWith(".sld"))){
175
                                                        file=new File(file.getPath()+".sld");
176 14868 jdominguez
                                                }
177 16232 jdominguez
                                                export2SLD(file);
178
                                        } else {
179
                                                if (!(file.getPath().toLowerCase().endsWith(".gvl"))){
180
                                                        file=new File(file.getPath()+".gvl");
181 14868 jdominguez
                                                }
182 16232 jdominguez
                                                writeLegend(file);
183 14868 jdominguez
                                        }
184
                                }
185
                        } else if (c.equals(getBtnLoadLegend())) {
186 17170 jdominguez
                                JFileChooser jfc = new JFileChooser(LEGEND_FILECHOOSER_ID, defaultLegendFolderPath);
187 14868 jdominguez
                            jfc.addChoosableFileFilter(new GenericFileFilter("gvl",
188
                                            PluginServices.getText(this, "tipo_de_leyenda")));
189
                            //jfc.addChoosableFileFilter(new GenericFileFilter("sld","sld"));
190
191
                            if (jfc.showOpenDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
192
                                    File file=jfc.getSelectedFile();
193
                                    if (!(file.getPath().endsWith(".gvl") || file.getPath().endsWith(".GVL")))        {
194
                                            file=new File(file.getPath()+".gvl");
195
                                    }
196 16232 jdominguez
                                    String path = file.getAbsolutePath();
197
                                    defaultLegendFolderPath = path.substring(0, path.lastIndexOf(File.separator));
198
199 14868 jdominguez
                                    loadLegend(file);
200
                            }
201
                        }
202
                };
203
        };
204 16232 jdominguez
205
        /**
206
         * Stores all the information of a legend in .gvl format
207
         *
208
         * @param file where the legend will be written
209
         */
210
        private void writeLegend(File file) {
211 14868 jdominguez
                try {
212
                        FileWriter writer = new FileWriter(file.getAbsolutePath());
213
                        Marshaller m = new Marshaller(writer);
214
                        m.setEncoding("ISO-8859-1");
215
                        m.marshal(legend.getXMLEntity().getXmlTag());
216
                } catch (Exception e) {
217
                        NotificationManager.addError(PluginServices.getText(this, "Error_guardando_la_leyenda"), e);
218
                }
219
        }
220
221 16232 jdominguez
        /**
222
         * Stores all the information of a legend in .sld format
223
         *
224
         * @param file where the legend will be written
225
         * @deprecated (very bad implementation)
226
         */
227 14868 jdominguez
        private void export2SLD(File file) {
228
                try {
229
                        FileWriter writer = new FileWriter(file.getAbsolutePath());
230
                        writer.write( legend.getSLDString(layer.getName()));
231
                        writer.close();
232
233
                } catch (Exception e) {
234
                        NotificationManager.addError(PluginServices.getText(this, "Error_exportando_SLD"), e);
235
                }
236
        }
237
238
239
         /**
240
    * Reads a legend file and loads into the this LegendManager
241
    * @param file
242
    */
243 16232 jdominguez
        private void loadLegend(File file) {
244
                File xmlFile = new File(file.getAbsolutePath());
245
                FileReader reader = null;
246
                try {
247
                        reader = new FileReader(xmlFile);
248 14868 jdominguez
249 16232 jdominguez
                        XmlTag tag = (XmlTag) XmlTag.unmarshal(reader);
250
                        ILegend myLegend = LegendFactory.createFromXML(new XMLEntity(tag));
251 14868 jdominguez
252 16232 jdominguez
                        if(myLegend != null ) {
253
                                //CAPA DE LINEAS
254
                                if (layer instanceof FLyrVect) {
255
                                        FLyrVect m = (FLyrVect) layer;
256
                                        IVectorLegend l = (IVectorLegend) myLegend;
257
258
                                        // check general conditions for IVectorLegend
259
                                        try {
260
261
                                                // check shape type
262
                                                if (l.getShapeType() != 0 && m.getShapeType() != l.getShapeType()) {
263
                                                        JOptionPane.showMessageDialog(this, PluginServices.getText(this,"El tipo de shape de capa y de leyenda no coinciden\n"));
264
                                                        return;
265
                                                }
266
267
                                        } catch (ReadDriverException e) {
268
                                                throw new Error("error" + e.getMessage());
269
                                        }
270
271
272
                                        if(myLegend instanceof IClassifiedVectorLegend) {
273
                                                IClassifiedVectorLegend cl = (IClassifiedVectorLegend) myLegend;
274
275
                                                String[] fNames = cl.getClassifyingFieldNames();
276
                                                int[] fTypes = cl.getClassifyingFieldTypes();
277
278
279
                                                try {
280
                                                        for (int i = 0; i < fNames.length; i++) {
281
                                                                int fieldIndex = m.getSource().getRecordset().getFieldIndexByName(fNames[i]);
282
                                                                if (fieldIndex != -1) {
283
                                                                        if(fTypes != null)
284
                                                                                if(fTypes[i] !=  m.getSource().getRecordset().getFieldType(fieldIndex)) {
285
                                                                                        JOptionPane.showMessageDialog(this, PluginServices.getText(this,"Los tipos no coinciden\n"));
286
                                                                                        return;
287
                                                                                }
288
                                                                } else {
289
                                                                        JOptionPane.showMessageDialog(this, PluginServices.getText(this,"El campo de clasificaci?n de la leyenda no existe.\n"));
290
                                                                        return;
291
                                                                }
292
                                                        }
293
                                                } catch (ReadDriverException e) {
294
                                                        NotificationManager.addError(PluginServices.getText(this, "error accessing to the properties of the fields of the legend"), e);
295
                                                }
296
                                        }
297
298
                                        applyLegend(myLegend);
299
                                }
300
                        }
301
                } catch (FileNotFoundException e) {
302
                        // should be unreachable code
303
                        NotificationManager.addError(PluginServices.getText(this, "file_not_found"), e);
304
                } catch (MarshalException e) {
305
                        NotificationManager.addError(PluginServices.getText(this, "file_corrupt"), e);
306
                } catch (ValidationException e) {
307
                        // should be unreachable code
308
                        NotificationManager.addError("ValidationException", e);
309
                } catch (XMLException e) {
310
                        NotificationManager.addError(PluginServices.getText(this, "unsupported_legend"), e);
311
                } finally {
312
                        try {
313
                                if (reader!=null) {
314
                                        reader.close();
315
                                }
316
                        } catch (IOException e) {
317
                                NotificationManager.addWarning(
318
                                                PluginServices.getText(this, "file_closing_failed") +
319
                                                " " + xmlFile.getAbsolutePath(), e);
320
                        }
321
                }
322
        }
323 10679 jaume
    public LegendManager() {
324
        initialize();
325
    }
326
327
    private void initialize() {
328
        setLayout(new BorderLayout());
329
        add(getTopPanel(), BorderLayout.NORTH);
330
        add(getSplitPane(), BorderLayout.CENTER);
331
        setSize(500, 360);
332
        treeModel = new DefaultTreeModel(root);
333
    }
334
335
    private JSplitPane getSplitPane() {
336
            if (jSplitPane == null) {
337
                    jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
338
                    JPanel aux = new JPanel(new BorderLayout(0, 5));
339
            aux.add(getLegendTreeScrollPane(), BorderLayout.CENTER);
340
            aux.add(getPreviewPanel(), BorderLayout.SOUTH);
341
                    jSplitPane.setLeftComponent(aux);
342
                    jSplitPane.setRightComponent(getCentralPanel());
343
                       jSplitPane.setDividerLocation(150);
344
            }
345
            return jSplitPane;
346
    }
347
348
    private JPanel getCentralPanel() {
349
        if (jCentralPanel == null) {
350
                jCentralPanel = new JPanel(new BorderLayout(0,10));
351
                jCentralPanel.add(getTitleScroll(), BorderLayout.NORTH);
352
                jCentralPanel.add(getJPanelContainer(), BorderLayout.CENTER);
353
        }
354
        return jCentralPanel;
355
    }
356
357
    private JScrollPane getJPanelContainer() {
358
        if (jPanelContainer == null) {
359
            jPanelContainer = new JScrollPane();
360
        }
361
        return jPanelContainer;
362
    }
363
364
    /**
365
     * This method initializes jPanel
366
     *
367
     * @return javax.swing.JPanel
368
     */
369
    private JPanel getTopPanel() {
370
        if (topPanel == null) {
371 14868 jdominguez
            topPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 5, 0));
372 10679 jaume
            topPanel.setPreferredSize(new Dimension(638, 31));
373
            topPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, null, null));
374 14868 jdominguez
            topPanel.add(getBtnSaveLegend(), null);
375
            topPanel.add(getBtnLoadLegend(), null);
376 10679 jaume
        }
377
        return topPanel;
378
    }
379 14868 jdominguez
380
    private JButton getBtnSaveLegend() {
381
        if (btnSaveLegend == null) {
382
            btnSaveLegend = new JButton(PluginServices.getText(this,"Guardar_leyenda")+"...");
383
            btnSaveLegend.addActionListener(loadSaveLegendAction);
384 10679 jaume
        }
385 14868 jdominguez
        return btnSaveLegend;
386 10679 jaume
    }
387 14868 jdominguez
388
    private JButton getBtnLoadLegend() {
389
        if (btnLoadLegend == null) {
390
            btnLoadLegend = new JButton(PluginServices.getText(this,"Recuperar_leyenda")+"...");
391
            btnLoadLegend.addActionListener(loadSaveLegendAction);
392 10679 jaume
        }
393 14868 jdominguez
        return btnLoadLegend;
394 10679 jaume
    }
395
396
    /**
397
     * This method initializes jTextArea
398
     *
399
     * @return javax.swing.JTextArea
400
     */
401
    private JTextArea getTitleArea() {
402
        if (titleArea == null) {
403
            titleArea = new JTextArea();
404
            titleArea.setBackground(java.awt.SystemColor.control);
405
            titleArea.setLineWrap(true);
406
            titleArea.setRows(0);
407
            titleArea.setWrapStyleWord(false);
408
            titleArea.setEditable(false);
409
            titleArea.setPreferredSize(new java.awt.Dimension(495,40));
410
        }
411
        return titleArea;
412
    }
413 17170 jdominguez
414 10679 jaume
    /**
415
     * This method initializes jPanel1
416
     *
417
     * @return javax.swing.JPanel
418
     */
419
    private SymbolPreviewer getPreviewPanel() {
420
        if (preview == null) {
421
            preview = new SymbolPreviewer();
422
            preview.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
423
            preview.setBackground(java.awt.SystemColor.text);
424 14313 jdominguez
            preview.setPreferredSize(new Dimension(
425
                            getSplitPane().getDividerLocation(),
426
                            130));
427
            preview.setBackground(Color.white);
428 10679 jaume
        }
429
        return preview;
430
    }
431
432
    /**
433
     * This method initializes jScrollPane
434
     *
435
     * @return javax.swing.JScrollPane
436
     */
437
    private JScrollPane getLegendTreeScrollPane() {
438
        if (legendTreeScrollPane == null) {
439
            legendTreeScrollPane = new JScrollPane();
440
            legendTreeScrollPane.setViewportView(getJTreeLegends());
441
        }
442
        return legendTreeScrollPane;
443
    }
444
445
    /**
446
     * <p>Adds a new fully-featured legend panel to the LegendManager.<br></p>
447
     *
448
     * <p><b>CAUTION:</b> Trying to add a child page whose parent hasn't been added yet
449
     * causes the application to fall in an infinite loop. This is a known
450
     * bug, sorry. Just avoid this case or try to fix it (lol).<br></p>
451
     *
452
     * <p><b>Notice</b> that there is no type check so if you add a non-ILegendPanel class,
453
     * you'll have a runtime error later.</p>
454
     * @param page, Class of type ILegendPanel
455
     */
456
    public static void addLegendPage(Class iLegendPanelClass) {
457
            if (!legendPool.contains(iLegendPanelClass)) {
458
                    legendPool.add(iLegendPanelClass);
459
            }
460
    }
461
462
    /**
463
     * Causes the component to be autofilled with the legend pages that
464
     * were added through the static method addLegendPage(ILegendPanel page)
465
     */
466
    private void fillDialog() {
467
            for (int i = 0; i < legendPool.size(); i++) {
468
                    Class pageClass = (Class) legendPool.get(i);
469
                    ILegendPanel page;
470
                    try {
471
                            page = (ILegendPanel) pageClass.newInstance();
472 11704 jaume
                            if (page.isSuitableFor(layer)) {
473
                                    // this legend can be applied to this layer
474
                                    pages.put(page.getClass(), page);
475 10679 jaume
476 11704 jaume
                                    if (dirtyTree) {
477
                                            // rebuild page tree
478
                                            dirtyTree = false;
479
480
                                            ArrayList legList = new ArrayList(pages.values());
481
                                            ArrayList alreadyAdded = new ArrayList();
482
                                            DefaultTreeModel model = new DefaultTreeModel(root);
483
                                            while (legList.size()>0) {
484
                                                    ILegendPanel legend = (ILegendPanel) legList.get(0);
485
                                                    Class parent = legend.getParentClass();
486
                                                    while (parent != null &&
487
                                                                    !alreadyAdded.contains(pages.get(parent))) {
488
                                                            legend = (ILegendPanel) pages.get(parent);
489
                                                    }
490
                                                    doInsertNode(model, legend);
491
                                                    legList.remove(legend);
492
                                                    alreadyAdded.add(legend);
493 10679 jaume
                                            }
494 11704 jaume
                                            treeModel = model;
495
                                            jTreeLegends.setModel(model);
496 10679 jaume
                                    }
497 11704 jaume
                                    doInsertNode(treeModel, page);
498
499 10679 jaume
                            }
500 11704 jaume
                            getJTreeLegends().setModel(treeModel);
501 10679 jaume
502
                    } catch (InstantiationException e) {
503
                            NotificationManager.addError("Trying to instantiate an interface" +
504
                                            " or abstract class + "+pageClass.getName(), e);
505
                    } catch (IllegalAccessException e) {
506
                            NotificationManager.addError("IllegalAccessException: does " +
507
                                            pageClass.getName()        + " class have an anonymous" +
508
                                            " constructor?", e);
509
                    }
510
511
            }
512
            getJTreeLegends().repaint();
513
514
    }
515
516
    private DefaultMutableTreeNode findNode(Class searchID) {
517
            String title;
518
            try {
519
                    title = ((ILegendPanel) Class.forName(searchID.getName()).newInstance()).getTitle();
520
            } catch (Exception e) {
521
                    // this should be impossible, but anyway this case will be treat as the node does not
522
                    // exist.
523
                    return null;
524
            }
525
526
        Enumeration e = root.breadthFirstEnumeration();
527
        while (e.hasMoreElements()) {
528
            DefaultMutableTreeNode nodeAux = (DefaultMutableTreeNode) e.nextElement();
529
            if (nodeAux != null) {
530
                ILegendPanel legend = (ILegendPanel) nodeAux.getUserObject();
531
                if (legend == null) continue; // Root node
532
                if (legend.getTitle().equals(title)) {
533
                    return nodeAux;
534
                }
535
            }
536
        }
537
        return null;
538
    }
539
540
    private void doInsertNode(DefaultTreeModel treeModel, ILegendPanel page) {
541
        dirtyTree = ((page.getParentClass() != null) && (findNode(page.getParentClass())==null));
542
        if (findNode(page.getClass()) != null) // It is already added
543
            return;
544
        if (page.getParentClass() != null) {
545
            if (pages.containsKey(page.getParentClass())) {
546
                ILegendPanel parent = (ILegendPanel) pages.get(page.getParentClass());
547
                DefaultMutableTreeNode nodeParent = findNode(parent.getClass());
548
                if (nodeParent == null) {
549
                        // the parent is empty
550
                    // Recursively add it
551
                    doInsertNode(treeModel, parent);
552
                } else {
553
                    DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
554
                    int children = nodeParent.getChildCount();
555
                    int pos=0;
556
                    for (int i = 0; i < children; i++) {
557
                        DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(nodeParent, i);
558
                        if (node.getUserObject() instanceof ILegendPanel) {
559
                            String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
560
                            if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
561
                        }
562
                    }
563
                    treeModel.insertNodeInto(nodeValue, nodeParent, pos);
564
                }
565
            }
566
        } else {
567
                // First level node
568
            DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(page);
569
            int children = root.getChildCount();
570
            int pos=0;
571
            for (int i = 0; i < children; i++) {
572
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeModel.getChild(root, i);
573
                if (node.getUserObject() instanceof ILegendPanel) {
574
                    String pageTitle = ((ILegendPanel) node.getUserObject()).getTitle();
575
                    if (pageTitle.compareTo(page.getTitle()) < 0) ++pos;
576
                }
577
            }
578
            treeModel.insertNodeInto(nodeValue, root, pos);
579
        }
580
    }
581
582
    private JScrollPane getTitleScroll() {
583
        if (jTitleScrollPane == null) {
584
            jTitleScrollPane = new JScrollPane();
585
            jTitleScrollPane.setBounds(2, 2, 498, 42);
586
            jTitleScrollPane.setViewportView(getTitleArea());
587
        }
588
        return jTitleScrollPane;
589
    }
590
591
    private JTree getJTreeLegends() {
592
        if (jTreeLegends == null) {
593
            jTreeLegends = new JTree();
594
            jTreeLegends.setRootVisible(false);
595
            MyTreeCellRenderer treeCellRenderer = new MyTreeCellRenderer();
596
            treeCellRenderer.setOpenIcon(null);
597
            treeCellRenderer.setClosedIcon(null);
598
            treeCellRenderer.setLeafIcon(null);
599
600
            jTreeLegends.setCellRenderer(treeCellRenderer);
601
            jTreeLegends.setShowsRootHandles(true);
602
            jTreeLegends.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
603
                    public void valueChanged(javax.swing.event.TreeSelectionEvent e) {
604
                            if (isTreeListenerDisabled) return;
605
                            DefaultMutableTreeNode node = (DefaultMutableTreeNode)
606
                            jTreeLegends.getLastSelectedPathComponent();
607
608
                            if (node == null) return;
609
                            setActivePage((ILegendPanel) node.getUserObject());
610
                    }
611
            });
612
            jTreeLegends.putClientProperty("JTree.linestyle", "Angled");
613
            jTreeLegends.getSelectionModel().
614
                    setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
615
        }
616
        return jTreeLegends;
617
    }
618
619
    private void setActivePage(ILegendPanel page) {
620
        if (page.getPanel() == null) {
621 10737 jaume
                // this is what happens when the user clicked in a parent node
622
                // which only acts as a folder, and does not manage any legend
623
                // then it expands and selects the first child
624 10679 jaume
            DefaultMutableTreeNode node = findNode(page.getClass());
625
            if (treeModel.getChildCount(node)>0) {
626
                DefaultMutableTreeNode dmn = (DefaultMutableTreeNode) treeModel.getChild(node, 0);
627
                page = (ILegendPanel) dmn.getUserObject();
628
                setActivePage(page);
629
                expandAndSelect(page);
630
            }
631
        } else {
632
                // show the page
633
            activePanel = page;
634 14313 jdominguez
            getPreviewPanel().setSymbol(activePanel.getIconSymbol());
635
636 10679 jaume
            activePanel.setData(layer, legend);
637
            getTitleArea().setText(activePanel.getDescription());
638
            jPanelContainer.setViewportView(activePanel.getPanel());
639
        }
640
    }
641
642
643 14868 jdominguez
    private class MyTreeCellRenderer extends DefaultTreeCellRenderer {
644
              private static final long serialVersionUID = -6013698992263578041L;
645 10679 jaume
646 14868 jdominguez
                public MyTreeCellRenderer() {}
647
648 10679 jaume
        public Component getTreeCellRendererComponent(
649
                            JTree tree,
650
                            Object value,
651
                            boolean sel,
652
                            boolean expanded,
653
                            boolean leaf,
654
                            int row,
655
                            boolean hasFocus) {
656
657
            super.getTreeCellRendererComponent(
658
                            tree, value, sel,
659
                            expanded, leaf, row,
660
                            hasFocus);
661
            if (value instanceof DefaultMutableTreeNode)
662
            {
663
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
664
                if (node.getUserObject() instanceof ILegendPanel)
665
                {
666
                    ILegendPanel legend = (ILegendPanel) node.getUserObject();
667
                    this.setText(
668
                            legend.getPanel() == null ? "<html><b>"+legend.getTitle()+"</b></html>":legend.getTitle());
669
                }
670
            }
671
            return this;
672
        }
673
674
    }
675
676
        private void expandAndSelect(Object node) {
677
                isTreeListenerDisabled = true;
678
            // will expand the tree and select the node
679
            int i = 0;
680
            boolean exit = false;
681
682
            TreePath tp = null;
683
            // find the page in the tree
684
            while (i<jTreeLegends.getRowCount() && !exit) {
685
                    //see if this row is the node that we are looking for
686
687
                    tp = jTreeLegends.getPathForRow(i);
688
                    Object[] obj = tp.getPath();
689
                    for (int j = 0; j < obj.length && !exit ; j++) {
690
                                Object o = ((DefaultMutableTreeNode) obj[j]).getUserObject();
691
692
                                if (o!=null        && o.getClass().equals(node.getClass())        && o.equals(node)) {
693
                                // found it! collapse the tree
694
                                while (i>=0) {
695
                                        jTreeLegends.collapseRow(i);
696
                                        i--;
697
                                }
698
                                exit = true;
699
                        }
700
                        }
701
                    jTreeLegends.expandRow(i);
702
                    i++;
703
            }
704
705
            // expand the tree and set the selection
706
            if (tp != null) {
707
                    jTreeLegends.expandPath(tp);
708
                    jTreeLegends.setSelectionPath(tp);
709
            }
710
            isTreeListenerDisabled = false;
711
        }
712
713
        public String getName() {
714
                return PluginServices.getText(this,"Simbologia");
715
        }
716
717
        public void acceptAction() {
718 14313 jdominguez
                // automatically handled by the ThemeManagerWindow
719 10679 jaume
        }
720
721
        public void cancelAction() {
722
                // does nothing
723
        }
724
725
        public void applyAction() {
726
                legend = activePanel.getLegend();
727
728
                /* try to apply the legend to all the active layers that
729
                 can accept it */
730
                FLayer[] activeLyrs = layer.getMapContext().getLayers().getActives();
731
                for (int i=0; i < activeLyrs.length; i++) {
732
                        FLayer laux=activeLyrs[i];
733
734
                        if (activeLyrs[i] instanceof FLayers){
735
                                laux=getFirstActiveLayerVect((FLayers)activeLyrs[i]);
736
                        }
737
738
                        if (laux instanceof ClassifiableVectorial) {
739
                                ClassifiableVectorial aux2 = (ClassifiableVectorial) laux;
740
                                try {
741 13881 jaume
                                        if (legend instanceof IClassifiedVectorLegend) {
742 10679 jaume
                                                // Es una leyenda que necesita un recordset con un
743
                                                // nombre de campo. Comprobamos que ese recordset
744
                                                // tiene ese nombre de campo y es del tipo esperado
745 13881 jaume
                                                IClassifiedVectorLegend cl = (IClassifiedVectorLegend) legend;
746 10679 jaume
747
                                                if (aux2 instanceof AlphanumericData) {
748 14868 jdominguez
749 10679 jaume
                                                        if (cl.getValues().length==0) {
750
                                                                JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"no_es_posible_aplicar_leyenda_vacia"));
751
                                                                return;
752
                                                        }
753 14868 jdominguez
754 13881 jaume
                                                                aux2.setLegend((IVectorLegend) legend);
755 10679 jaume
                                                }
756
                                        }
757
                                        else if (legend instanceof SingleSymbolLegend)
758 13881 jaume
                                                aux2.setLegend((IVectorLegend) legend);
759 10679 jaume
                                } catch (LegendLayerException e) {
760
                                        NotificationManager.addError(PluginServices.getText(this, "legend_exception"), e);
761
                                }
762
                        }
763
                }
764
        }
765
766 16232 jdominguez
        @Override
767 10679 jaume
        public void setModel(FLayer layer) {
768
                this.layer = layer;
769 16232 jdominguez
                applyLegend(((Classifiable) layer).getLegend());
770
        }
771
772
        /**
773
         * Applies the legend to the layer.
774
         *
775
         * @param aLegend , legend that the user wants to apply
776
         */
777
        private void applyLegend(ILegend aLegend) {
778
                this.legend = aLegend;
779 11704 jaume
                fillDialog();
780 16232 jdominguez
                Enumeration en = pages.keys();
781
                while (en.hasMoreElements()) {
782
                        ILegendPanel page = (ILegendPanel) pages.get(en.nextElement());
783
                        if (legend.getClass().equals(page.getLegendClass())) {
784
                                setActivePage(page);
785
                                expandAndSelect(page);
786
                        }
787
                }
788 10679 jaume
        }
789
}