Statistics
| Revision:

root / trunk / applications / appgvSIG / src / com / iver / cit / gvsig / project / documents / view / toc / gui / TOC.java @ 22072

History | View | Annotate | Download (33.9 KB)

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

    
49
import java.awt.BorderLayout;
50
import java.awt.Dimension;
51
import java.awt.Image;
52
import java.awt.Point;
53
import java.awt.Rectangle;
54
import java.awt.event.ActionEvent;
55
import java.awt.event.ActionListener;
56
import java.awt.event.ComponentEvent;
57
import java.awt.event.ComponentListener;
58
import java.awt.event.InputEvent;
59
import java.awt.event.MouseAdapter;
60
import java.awt.event.MouseEvent;
61
import java.util.ArrayList;
62
import java.util.Enumeration;
63
import java.util.HashMap;
64

    
65
import javax.swing.BorderFactory;
66
import javax.swing.JColorChooser;
67
import javax.swing.JComponent;
68
import javax.swing.JDialog;
69
import javax.swing.JScrollPane;
70
import javax.swing.JTree;
71
import javax.swing.SwingUtilities;
72
import javax.swing.UIManager;
73
import javax.swing.event.TreeExpansionEvent;
74
import javax.swing.event.TreeExpansionListener;
75
import javax.swing.tree.DefaultMutableTreeNode;
76
import javax.swing.tree.DefaultTreeModel;
77
import javax.swing.tree.TreePath;
78
import javax.swing.tree.TreeSelectionModel;
79

    
80
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
81
import com.iver.andami.PluginServices;
82
import com.iver.andami.messages.NotificationManager;
83
import com.iver.cit.gvsig.fmap.AtomicEvent;
84
import com.iver.cit.gvsig.fmap.AtomicEventListener;
85
import com.iver.cit.gvsig.fmap.MapContext;
86
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
87
import com.iver.cit.gvsig.fmap.layers.CancelationException;
88
import com.iver.cit.gvsig.fmap.layers.FLayer;
89
import com.iver.cit.gvsig.fmap.layers.FLayers;
90
import com.iver.cit.gvsig.fmap.layers.FLyrAnnotation;
91
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
92
import com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent;
93
import com.iver.cit.gvsig.fmap.layers.LayerCollectionListener;
94
import com.iver.cit.gvsig.fmap.layers.LayerPositionEvent;
95
import com.iver.cit.gvsig.fmap.layers.LegendChangedEvent;
96
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
97
import com.iver.cit.gvsig.fmap.layers.layerOperations.IHasImageLegend;
98
import com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection;
99
import com.iver.cit.gvsig.fmap.rendering.IClassifiedLegend;
100
import com.iver.cit.gvsig.fmap.rendering.ILegend;
101
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
102
import com.iver.cit.gvsig.fmap.rendering.LegendListener;
103
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
104
import com.iver.cit.gvsig.project.documents.IContextMenuAction;
105
import com.iver.cit.gvsig.project.documents.view.toc.DnDJTree;
106
import com.iver.cit.gvsig.project.documents.view.toc.ITocItem;
107
import com.iver.cit.gvsig.project.documents.view.toc.ITocOrderListener;
108
import com.iver.cit.gvsig.project.documents.view.toc.TocItemBranch;
109
import com.iver.cit.gvsig.project.documents.view.toc.TocItemLeaf;
110

    
111

    
112
/**
113
 * DOCUMENT ME!
114
 *
115
 * @author fjp To change the template for this generated type comment go to
116
 *         Window>Preferences>Java>Code Generation>Code and
117
 *         Comments
118
 */
119
public class TOC extends JComponent implements ITocOrderListener,
120
    LegendListener, LayerCollectionListener, TreeExpansionListener,
121
    ComponentListener {
122
    private MapContext mapContext;
123
    private DnDJTree m_Tree;
124
    private DefaultTreeModel m_TreeModel;
125
    private DefaultMutableTreeNode m_Root;
126
    private TOCRenderer m_TocRenderer;
127
    private JScrollPane m_Scroller;
128

    
129
    //private ArrayList m_Listeners;
130
    private HashMap m_ItemsExpanded = new HashMap();
131
    private NodeSelectionListener nodeSelectionListener = null;
132

    
133
    /**
134
     * Crea un nuevo TOC.
135
     */
136
    public TOC() {
137
            this.setName("TOC");
138
        this.setLayout(new BorderLayout());
139
        this.setMinimumSize(new Dimension(100, 80));
140
        this.setPreferredSize(new Dimension(100, 80));
141

    
142
        //Construct the tree.
143
        m_Root = new DefaultMutableTreeNode(java.lang.Object.class);
144
        m_TreeModel = new DefaultTreeModel(m_Root);
145
        m_Tree = new DnDJTree(m_TreeModel);
146

    
147
        m_TocRenderer = new TOCRenderer();
148
        m_Tree.setCellRenderer(m_TocRenderer);
149

    
150
        m_Tree.setRootVisible(false);
151

    
152
        // m_Tree.setExpandsSelectedPaths(true);
153
        // m_Tree.setAutoscrolls(true);
154
        m_Tree.setShowsRootHandles(true);
155

    
156
        //Posibilidad de seleccionar de forma aleatoria nodos de la leyenda.
157
        m_Tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
158
        nodeSelectionListener=new NodeSelectionListener(m_Tree);
159
        m_Tree.addMouseListener(nodeSelectionListener);
160
        m_Tree.setBackground(UIManager.getColor("Button.background"));
161
        m_Tree.setBorder(BorderFactory.createEtchedBorder());
162

    
163
        this.addComponentListener(this);
164

    
165
        m_Tree.addTreeExpansionListener(this);
166

    
167
        m_Tree.addOrderListener(this);
168

    
169
        m_Tree.setRowHeight(0); // Para que lo determine el renderer
170

    
171
        m_Scroller = new JScrollPane(m_Tree);
172
        m_Scroller.setBorder(BorderFactory.createEmptyBorder());
173

    
174
        // scrollPane.setPreferredSize(new Dimension(80,80));
175
        //Add everything to this panel.
176
        /* GridBagLayout gridbag = new GridBagLayout();
177
           GridBagConstraints c = new GridBagConstraints();
178
           setLayout(gridbag);
179
           c.fill = GridBagConstraints.BOTH;
180
           c.weightx = 1.0;
181
           gridbag.setConstraints(check,c); */
182
        add(m_Scroller); //, BorderLayout.WEST);
183

    
184
        //                refresh();
185
    }
186

    
187
    /**
188
     * Elimina los listeners que actuan sobre el TOC, lo ?nico que deja hacer
189
     * es desplegar la leyenda de las capas.
190
     */
191
    public void removeListeners() {
192
        m_Tree.removeMouseListener(nodeSelectionListener);
193
        m_Tree.invalidateListeners();
194
    }
195

    
196
    /**
197
     * Inserta el FMap.
198
     *
199
     * @param mc FMap.
200
     */
201
    public void setMapContext(MapContext mc) {
202
        mapContext = mc;
203
        mapContext.addAtomicEventListener(new AtomicEventListener() {
204
                /**
205
                 * @see com.iver.cit.gvsig.fmap.AtomicEventListener#atomicEvent(com.iver.cit.gvsig.fmap.AtomicEvent)
206
                 */
207
                public void atomicEvent(AtomicEvent e) {
208
                    if ((e.getLayerCollectionEvents().length > 0) ||
209
                            (e.getLegendEvents().length > 0)) {
210
                        SwingUtilities.invokeLater(new Runnable() {
211
                                public void run() {
212
                                    refresh();
213
                                }
214
                            });
215
                    }
216

    
217
                    if (e.getLayerEvents().length > 0) {
218
                        repaint();
219
                    }
220

    
221
                    if (e.getExtentEvents().length > 0) {
222
                        repaint();
223
                    }
224
                }
225
            });
226

    
227
        SwingUtilities.invokeLater(new Runnable() {
228
                public void run() {
229
                    refresh();
230
                }
231
            });
232
    }
233

    
234
    /**
235
     * DOCUMENT ME!
236
     */
237
     private void setExpandedNodes(DefaultMutableTreeNode node) {
238
        //int i = 0;
239
        // Las claves sobrantes de m_ItemsExpanded (provocadas
240
        // por layerRemove, se quitan en el evento layerRemoved
241
        // de este TOC
242
        DefaultMutableTreeNode n;
243
       Enumeration enumeration = node.children();
244

    
245
        while (enumeration.hasMoreElements()) {
246
            n = (DefaultMutableTreeNode) enumeration.nextElement();
247
                        if (n.getChildCount()>0){
248
                    setExpandedNodes(n);
249
            }
250
            TreePath path = new TreePath(m_TreeModel.getPathToRoot(n));
251
            ITocItem item = (ITocItem) n.getUserObject();
252
            Boolean b = (Boolean) m_ItemsExpanded.get(item.getLabel());
253

    
254
            if (b == null) // No estaba en el hash todav?a: valor por defecto
255
             {
256
                // System.out.println("Primera expansi?n de " + item.getLabel());
257
                m_Tree.expandPath(path);
258

    
259
                return;
260
            }
261

    
262
            if (b.booleanValue()) {
263
                // System.out.println("Expansi?n de " + item.getLabel());
264
                m_Tree.expandPath(path);
265
            } else {
266
                // System.out.println("Colapso de " + item.getLabel());
267
                m_Tree.collapsePath(path);
268
            }
269
        }
270
    }
271

    
272
    /* (non-Javadoc)
273
     * @see com.iver.cit.opensig.gui.IToc#refresh()
274
     */
275
    public void refresh() {
276
        LayerCollection theLayers = mapContext.getLayers();
277
        m_Root.removeAllChildren();
278
        m_Root.setAllowsChildren(true);
279
        //System.out.println("Refresh del toc");
280
        doRefresh(theLayers, m_Root);
281

    
282
        m_TreeModel.reload();
283

    
284
       setExpandedNodes(m_Root);
285
    }
286

    
287
    /**
288
     * DOCUMENT ME!
289
     *
290
     * @param theLayers DOCUMENT ME!
291
     * @param parentNode DOCUMENT ME!
292
     */
293
    private void doRefresh(LayerCollection theLayers,
294
        DefaultMutableTreeNode parentNode) {
295
        Dimension sizeLeaf = new Dimension(m_Tree.getWidth(), 15);
296
        Dimension sizeBranch = new Dimension(m_Tree.getWidth(), 25);
297

    
298
        for (int i = theLayers.getLayersCount() - 1; i >= 0; i--) {
299
            FLayer lyr = theLayers.getLayer(i);
300
            if (!lyr.isInTOC())
301
                    continue;
302
            TocItemBranch elTema = new TocItemBranch(lyr);
303
            elTema.setSize(sizeBranch);
304

    
305
            DefaultMutableTreeNode nodeLayer = new DefaultMutableTreeNode(elTema);
306

    
307
            m_TreeModel.insertNodeInto(nodeLayer, parentNode,
308
                parentNode.getChildCount());
309

    
310
            //TreePath path = new TreePath(m_TreeModel.getPathToRoot(nodeLayer));
311
            // m_Tree.makeVisible(path);
312
            if (lyr instanceof LayerCollection) {
313
                LayerCollection group = (LayerCollection) lyr;
314
                doRefresh(group, nodeLayer);
315
            } else {
316
                if (lyr instanceof Classifiable && !(lyr instanceof FLyrAnnotation)) {
317

    
318
                    Classifiable aux = (Classifiable) lyr;
319
                    ILegend legendInfo = aux.getLegend();
320

    
321
                    try {
322
                        if (legendInfo instanceof IClassifiedLegend) {
323
                            IClassifiedLegend cl = (IClassifiedLegend) legendInfo;
324
                            String[] descriptions = cl.getDescriptions();
325
                            ISymbol[] symbols = cl.getSymbols();
326

    
327
                            for (int j = 0; j < descriptions.length; j++) {
328
                                TocItemLeaf itemLeaf;
329
                                itemLeaf = new TocItemLeaf(symbols[j],
330
                                        descriptions[j], aux.getShapeType());
331
                                itemLeaf.setSize(sizeLeaf);
332

    
333
                                DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(itemLeaf);
334
                                m_TreeModel.insertNodeInto(nodeValue,
335
                                    nodeLayer, nodeLayer.getChildCount());
336

    
337
                                //TreePath pathSymbol = new TreePath(m_TreeModel.getPathToRoot(
338
                                //                        nodeValue));
339
                                // m_Tree.makeVisible(pathSymbol);
340
                            }
341
                        }
342

    
343
                        if (legendInfo instanceof SingleSymbolLegend &&
344
                                (legendInfo.getDefaultSymbol() != null)) {
345
                            TocItemLeaf itemLeaf;
346
                            itemLeaf = new TocItemLeaf(legendInfo.getDefaultSymbol(),
347
                                    "Default", aux.getShapeType());
348
                            itemLeaf.setSize(sizeLeaf);
349

    
350
                            DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(itemLeaf);
351
                            m_TreeModel.insertNodeInto(nodeValue, nodeLayer,
352
                                nodeLayer.getChildCount());
353

    
354
                            //TreePath pathSymbol = new TreePath(m_TreeModel.getPathToRoot(
355
                            //                        nodeValue));
356
                            // m_Tree.makeVisible(pathSymbol);
357
                        }
358
                    } catch (ReadDriverException e) {
359
                                                e.printStackTrace();
360
                                        }
361
                }
362
                else if (lyr instanceof IHasImageLegend)
363
                {
364
                    TocItemLeaf itemLeaf;
365
                    IHasImageLegend aux = (IHasImageLegend) lyr;
366
                    Image image = aux.getImageLegend();
367

    
368
                    if (image != null)
369
                    {
370
                            itemLeaf = new TocItemLeaf();
371
                               itemLeaf.setImageLegend(image, "",
372
                                                                               new Dimension(image.getWidth( null ),
373
                                                                               image.getHeight( null )));//new Dimension(150,200));
374

    
375
                        DefaultMutableTreeNode nodeValue = new DefaultMutableTreeNode(itemLeaf);
376
                        m_TreeModel.insertNodeInto(nodeValue, nodeLayer,
377
                            nodeLayer.getChildCount());
378
                    }
379
                }
380
            } // if instanceof layers
381
        }
382
    }
383

    
384
    /**
385
     * @see com.iver.cit.opensig.gui.toc.ITocOrderListener#orderChanged(int,
386
     *      int)
387
     */
388
    public void orderChanged(int oldPos, int newPos, FLayers lpd) {
389
        //LayerCollection layers = mapContext.getLayers();
390
        // El orden es el contrario, hay que traducir.
391
        // El orden es el contrario, hay que traducir.
392
        ///oldPos = layers.getLayersCount() - 1 - oldPos;
393
        ///newPos = layers.getLayersCount() - 1 - newPos;
394
        try {
395
            lpd.moveTo(oldPos, newPos);
396
        } catch (CancelationException e) {
397
            // TODO Auto-generated catch block
398
            e.printStackTrace();
399
        }
400

    
401
        // No hace falta un refresh, lo hace mediante eventos.
402
        //refresh();
403
        mapContext.invalidate();
404
    }
405

    
406
    /**
407
     * DOCUMENT ME!
408
     *
409
     * @param lpo DOCUMENT ME!
410
     * @param lpd DOCUMENT ME!
411
     * @param ls DOCUMENT ME!
412
     */
413
    public void parentChanged(FLayers lpo, FLayers lpd, FLayer ls) {
414
        lpo.removeLayer(ls);
415
        lpd.addLayer(ls);
416

    
417
        /*if (lpo.getLayersCount()==0){
418
           lpo.getParentLayer().removeLayer(lpo);
419
           }*/
420
        mapContext.invalidate();
421
    }
422

    
423
    /* (non-Javadoc)
424
     * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
425
     */
426
    public void componentHidden(ComponentEvent e) {
427
    }
428

    
429
    /* (non-Javadoc)
430
     * @see java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent)
431
     */
432
    public void componentMoved(ComponentEvent e) {
433
    }
434

    
435
    /* (non-Javadoc)
436
     * @see java.awt.event.ComponentListener#componentResized(java.awt.event.ComponentEvent)
437
     */
438
    public void componentResized(ComponentEvent e) {
439
        System.out.println("Cambiando tama?o.");
440

    
441
        int i = 0;
442
        DefaultMutableTreeNode n;
443
        Enumeration enumeration = m_Root.children();
444

    
445
        while (enumeration.hasMoreElements()) {
446
            n = (DefaultMutableTreeNode) enumeration.nextElement();
447

    
448
            if (n.getUserObject() instanceof TocItemBranch) {
449
                ITocItem item = (ITocItem) n.getUserObject();
450
                Dimension szAnt = item.getSize();
451
                item.setSize(new Dimension(this.getWidth() - 40, szAnt.height));
452
            }
453

    
454
        }
455

    
456
        // m_Tree.setSize(this.getSize());
457
        System.out.println("Ancho del tree=" + m_Tree.getWidth() + " " +
458
            m_Tree.getComponentCount());
459
        System.out.println("Ancho del TOC=" + this.getWidth());
460

    
461
        // m_Tree.repaint();
462
    }
463

    
464
    /* (non-Javadoc)
465
     * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
466
     */
467
    public void componentShown(ComponentEvent e) {
468
    }
469

    
470
    /* (non-Javadoc)
471
     * @see com.iver.cit.gvsig.fmap.layers.LayerListener#legendChanged(com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent)
472
     */
473
    public void legendChanged(LegendChangedEvent e) {
474
        System.out.println("Refrescando TOC");
475
        refresh();
476
    }
477

    
478
    /* (non-Javadoc)
479
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdded(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
480
     */
481
    public void layerAdded(LayerCollectionEvent e) {
482
        refresh();
483
    }
484

    
485
    /* (non-Javadoc)
486
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoved(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
487
     */
488
    public void layerMoved(LayerPositionEvent e) {
489
        refresh();
490
    }
491

    
492
    /* (non-Javadoc)
493
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoved(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
494
     */
495
    public void layerRemoved(LayerCollectionEvent e) {
496
        m_ItemsExpanded.remove(e.getAffectedLayer().getName());
497
        refresh();
498
    }
499

    
500
    /* (non-Javadoc)
501
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerAdding(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
502
     */
503
    public void layerAdding(LayerCollectionEvent e) throws CancelationException {
504
    }
505

    
506
    /* (non-Javadoc)
507
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerMoving(com.iver.cit.gvsig.fmap.layers.LayerPositionEvent)
508
     */
509
    public void layerMoving(LayerPositionEvent e) throws CancelationException {
510
    }
511

    
512
    /* (non-Javadoc)
513
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#layerRemoving(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
514
     */
515
    public void layerRemoving(LayerCollectionEvent e)
516
        throws CancelationException {
517
    }
518

    
519
    /* (non-Javadoc)
520
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#activationChanged(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
521
     */
522
    public void activationChanged(LayerCollectionEvent e)
523
        throws CancelationException {
524
        repaint();
525
    }
526

    
527
    /* (non-Javadoc)
528
     * @see com.iver.cit.gvsig.fmap.layers.LayerCollectionListener#visibilityChanged(com.iver.cit.gvsig.fmap.layers.LayerCollectionEvent)
529
     */
530
    public void visibilityChanged(LayerCollectionEvent e)
531
        throws CancelationException {
532
        repaint();
533
    }
534

    
535
    /* (non-Javadoc)
536
     * @see javax.swing.event.TreeExpansionListener#treeCollapsed(javax.swing.event.TreeExpansionEvent)
537
     */
538
    public void treeCollapsed(TreeExpansionEvent event) {
539
        TreePath path = event.getPath();
540
        DefaultMutableTreeNode n = (DefaultMutableTreeNode) path.getLastPathComponent();
541

    
542
        if (n.getUserObject() instanceof ITocItem) {
543
            ITocItem item = (ITocItem) n.getUserObject();
544
            Boolean b = Boolean.FALSE;
545

    
546
            // System.out.println("Collapsed: " + item.getLabel());
547
            m_ItemsExpanded.put(item.getLabel(), b);
548
        }
549
    }
550

    
551
    /* (non-Javadoc)
552
     * @see javax.swing.event.TreeExpansionListener#treeExpanded(javax.swing.event.TreeExpansionEvent)
553
     */
554
    public void treeExpanded(TreeExpansionEvent event) {
555
        TreePath path = event.getPath();
556
        DefaultMutableTreeNode n = (DefaultMutableTreeNode) path.getLastPathComponent();
557

    
558
        if (n.getUserObject() instanceof ITocItem) {
559
            ITocItem item = (ITocItem) n.getUserObject();
560
            Boolean b = Boolean.TRUE;
561

    
562
            // System.out.println("Expanded: " + item.getLabel());
563
            m_ItemsExpanded.put(item.getLabel(), b);
564
        }
565
    }
566

    
567
    /**
568
     * Obtiene el JScrollPane que contiene el TOC
569
     *
570
     * @return JScrollPane que contiene el TOC
571
     */
572
    public JScrollPane getJScrollPane() {
573
        return this.m_Scroller;
574
    }
575

    
576
    /**
577
     * DOCUMENT ME!
578
     *
579
     * @return DOCUMENT ME!
580
     */
581
    public DnDJTree getTree() {
582
        return m_Tree;
583
    }
584

    
585
    /**
586
     * Clase Listener que reacciona al pulsar sobre el checkbox de un nodo y
587
     * crea un popupmenu al pulsar el bot?n derecho.
588
     */
589
    class NodeSelectionListener extends MouseAdapter implements ActionListener {
590
        JTree tree;
591
        JDialog dlg;
592
        JColorChooser colorChooser;
593
        FPopupMenu popmenu = null;
594
        DefaultMutableTreeNode node;
595
        
596
        /**
597
         * Crea un nuevo NodeSelectionListener.
598
         *
599
         * @param tree DOCUMENT ME!
600
         */
601
        NodeSelectionListener(JTree tree) {
602
            this.tree = tree;
603
        }
604

    
605
        /**
606
         * DOCUMENT ME!
607
         *
608
         * @param e DOCUMENT ME!
609
         */
610
        public void mouseClicked(MouseEvent e) {
611
                int x = e.getX();
612
                int y = e.getY();
613
                int row = tree.getRowForLocation(x, y);
614
                TreePath path = tree.getPathForRow(row);
615
                LayerCollection layers = mapContext.getLayers();
616

    
617
                // System.out.println(e.getSource());
618
                if (path != null) {
619
                        if (e.getClickCount() == 1) {
620
                                // this fixes a bug when double-clicking. JTree by default
621
                                // expands the tree when double-clicking, so we capture a 
622
                                // different node in the second click than in the first
623
                                node = (DefaultMutableTreeNode) path.getLastPathComponent();
624
                        }
625

    
626
                        // System.out.println("Evento de rat?n originado por " +
627
                        // e.getSource().getClass().toString());
628
                        if (node != null && node.getUserObject() instanceof TocItemBranch) {
629
                                // double click with left button ON A BRANCH/NODE (layer)
630
                                if (e.getClickCount()>=2 && e.getButton() == MouseEvent.BUTTON1) {
631
                                        e.consume();
632
                                        PluginServices.getMDIManager().setWaitCursor();
633
                                        try {
634
                                                TocItemBranch leaf = (TocItemBranch) node.getUserObject();
635

    
636
                                                IContextMenuAction action = leaf.getDoubleClickAction();
637
                                                if (action != null) {
638
                                                        /* if there is an action associated with the double-clicked element
639
                                                         * it will be fired for it and FOR ALL OTHER COMPATIBLES THAT HAVE 
640
                                                         * BEEN ACTIVATED.
641
                                                         */ 
642
                                                        ArrayList<FLayer> targetLayers = new ArrayList<FLayer>();
643

    
644
                                                        TocItemBranch owner = (TocItemBranch) node.getUserObject();
645
                                                        
646
                                                        FLayer masterLayer = owner.getLayer();
647
                                                        targetLayers.add(masterLayer);
648
                                                        FLayer[] actives = mapContext.getLayers().getActives();
649
                                                        for (int i = 0; i < actives.length; i++) {
650
                                                                        if (actives[i].getClass().equals(masterLayer.getClass())) {
651
                                                                                if (actives[i] instanceof FLyrVect) {
652
                                                                                        FLyrVect vectorLayer = (FLyrVect) actives[i];
653
                                                                                        FLyrVect vectorMaster = (FLyrVect) masterLayer;
654
                                                                                        if (vectorLayer.getShapeType() == vectorMaster.getShapeType()) {
655
                                                                                                targetLayers.add(vectorLayer);
656
                                                                                        } else {
657
                                                                                                vectorLayer.setActive(false);
658
                                                                                        }
659
                                                                                } 
660
                                                                                // TODO for the rest of layer types (i.e. FLyrRaster)
661
                                                                        } else {
662
                                                                                actives[i].setActive(false);
663
                                                                        }
664
                                                                }
665
                                                        action.execute(leaf, targetLayers.toArray(new FLayer[0]));
666
                                                }
667
                                        } catch (Exception ex) {
668
                                                NotificationManager.addError(ex);
669
                                        } finally {
670
                                                PluginServices.getMDIManager().restoreCursor();
671
                                        }
672
                                        return;
673
                                }
674

    
675
                                TocItemBranch elTema = (TocItemBranch) node.getUserObject();
676
                                FLayer lyr = elTema.getLayer();
677
                                lyr.getMapContext().beginAtomicEvent();
678

    
679
                                if (((e.getModifiers() & InputEvent.SHIFT_MASK) != 0)
680
                                                && (e.getButton() == MouseEvent.BUTTON1)) {
681
                                        FLayer[] activeLayers = layers.getActives();
682
                                        if (activeLayers.length > 0) {
683
                                                selectInterval(layers,lyr);
684
                                        } else {
685
                                                updateActive(lyr, !lyr.isActive());
686
                                        }
687

    
688
                                } else {
689
                                        if (!((e.getModifiers() & InputEvent.CTRL_MASK) != 0)
690
                                                        && (e.getButton() == MouseEvent.BUTTON1)) {
691
                                                layers.setAllActives(false);
692
                                        }
693
                                        if (e.getButton() == MouseEvent.BUTTON1) {
694
                                                // lyr.setActive(true);
695
                                                updateActive(lyr, !lyr.isActive());
696
                                        }
697
                                }
698
                                // Si pertenece a un grupo, lo ponemos activo tambi?n.
699
                                // FLayer parentLayer = lyr.getParentLayer();
700

    
701
                                /*
702
                                 * if (parentLayer != null) { parentLayer.setActive(true); }
703
                                 */
704
                                Point layerNodeLocation = tree.getUI().getPathBounds(tree,
705
                                                path).getLocation();
706

    
707
                                // Rect?ngulo que representa el checkbox
708
                                Rectangle checkBoxBounds = m_TocRenderer
709
                                .getCheckBoxBounds();
710
                                checkBoxBounds.translate((int) layerNodeLocation.getX(),
711
                                                (int) layerNodeLocation.getY());
712

    
713
                                if (checkBoxBounds.contains(e.getPoint())) {
714
                                        updateVisible(lyr);
715
                                }
716

    
717
                                // }
718
                                if (e.getButton() == MouseEvent.BUTTON3) {
719
                                        // Boton derecho sobre un nodo del arbol
720
                                        // if ((e.getModifiers() & InputEvent.META_MASK) != 0) {
721
                                        popmenu = new FPopupMenu(mapContext, node);
722
                                        tree.add(popmenu);
723

    
724
                                        popmenu.show(e.getComponent(), e.getX(), e.getY());
725

    
726
                                        // }
727
                                }
728

    
729
                                lyr.getMapContext().endAtomicEvent();
730
                        }
731

    
732
                        if (node!=null && node.getUserObject() instanceof TocItemLeaf) {
733
                                // double click with left button ON A LEAF (ISymbol)
734
                                if (e.getClickCount()>=2 && e.getButton() == MouseEvent.BUTTON1) {
735
                                        e.consume();
736

    
737
                                        PluginServices.getMDIManager().setWaitCursor();
738
                                        try {
739
                                                TocItemLeaf leaf = (TocItemLeaf) node.getUserObject();
740
                                                IContextMenuAction action = leaf.getDoubleClickAction();
741
                                                if (action != null) {
742
                                                        /* if there is an action associated with the double-clicked element
743
                                                         * it will be fired for it and FOR ALL OTHER COMPATIBLES THAT HAVE 
744
                                                         * BEEN ACTIVATED.
745
                                                         */ 
746
                                                        ArrayList<FLayer> targetLayers = new ArrayList<FLayer>();
747
                                                        
748
                                                        TocItemBranch owner = (TocItemBranch) ((DefaultMutableTreeNode) node.getParent())
749
                                                                                                                .getUserObject();
750
                                                        
751
                                                        FLayer masterLayer = owner.getLayer();
752
                                                        targetLayers.add(masterLayer);
753
                                                        FLayer[] actives = mapContext.getLayers().getActives();
754
                                                        for (int i = 0; i < actives.length; i++) {
755
                                                                        if (actives[i].getClass().equals(masterLayer.getClass())) {
756
                                                                                if (actives[i] instanceof FLyrVect) {
757
                                                                                        FLyrVect vectorLayer = (FLyrVect) actives[i];
758
                                                                                        FLyrVect vectorMaster = (FLyrVect) masterLayer;
759
                                                                                        int masterLayerShapetypeOF_THE_LEGEND = ((IVectorLegend) vectorMaster.getLegend()).getShapeType();
760
                                                                                        int anotherVectorLayerShapetypeOF_THE_LEGEND = ((IVectorLegend) vectorLayer.getLegend()).getShapeType();
761
                                                                                        if ( masterLayerShapetypeOF_THE_LEGEND == anotherVectorLayerShapetypeOF_THE_LEGEND) {
762
                                                                                                targetLayers.add(vectorLayer);
763
                                                                                        } else {
764
                                                                                                vectorLayer.setActive(false);
765
                                                                                        }
766
                                                                                } 
767
                                                                                // TODO for the rest of layer types (i.e. FLyrRaster)
768
                                                                        } else {
769
                                                                                actives[i].setActive(false);
770
                                                                        }
771
                                                                }
772
                                                        action.execute(leaf, targetLayers.toArray(new FLayer[0]));
773
                                                }
774
                                        } catch (Exception ex) {
775
                                                NotificationManager.addError(ex);
776
                                        } finally {
777
                                                PluginServices.getMDIManager().restoreCursor();
778
                                        }
779
                                        return;
780
                                }
781
                                
782
                                
783
                                // Boton derecho sobre un Simbolo
784
                                // TocItemLeaf auxLeaf = (TocItemLeaf) node.getUserObject();
785
                                // FSymbol theSym = auxLeaf.getSymbol();
786
                                if ((e.getModifiers() & InputEvent.META_MASK) != 0) {
787
                                        popmenu = new FPopupMenu(mapContext, node);
788
                                        tree.add(popmenu);
789
                                        popmenu.show(e.getComponent(), e.getX(), e.getY());
790
                                }
791
                        }
792

    
793
                        ((DefaultTreeModel) tree.getModel()).nodeChanged(node);
794

    
795
                        if (row == 0) {
796
                                tree.revalidate();
797
                                tree.repaint();
798
                        }
799

    
800
                        if (PluginServices.getMainFrame() != null) {
801
                                PluginServices.getMainFrame().enableControls();
802
                        }
803
                } else {
804
                        if (e.getButton() == MouseEvent.BUTTON3) {
805
                                popmenu = new FPopupMenu(mapContext, null);
806
                                tree.add(popmenu);
807
                                popmenu.show(e.getComponent(), e.getX(), e.getY());
808
                        }
809

    
810
                }
811
        }
812

    
813
        private void selectInterval(LayerCollection layers, FLayer lyr) {
814
                FLayer[] activeLayers = layers.getActives();
815
                                //if (activeLayers[0].getParentLayer() instanceof FLayers && activeLayers[0].getParentLayer().getParentLayer()!=null) {
816
                                //        selectInterval((LayerCollection)activeLayers[0].getParentLayer(),lyr);
817
                                //}
818
                                for (int j = 0; j < layers.getLayersCount(); j++) {
819
                                        FLayer layerAux=layers.getLayer(j);
820
                                        //Si se cumple esta condici?n es porque la primera capa que nos encontramos en el TOC es la que estaba activa
821
                                        if (activeLayers[0].equals(layerAux)) {
822
                                                boolean isSelected = false;
823
                                                for (int i = 0; i < layers.getLayersCount(); i++) {
824
                                                        FLayer layer = layers.getLayer(i);
825
                                                        if (!isSelected)
826
                                                                isSelected = layer.isActive();
827
                                                        else {
828
                                                                updateActive(layer, true);
829
                                                                if (lyr.equals(layer)) {
830
                                                                        isSelected = false;
831
                                                                }
832
                                                        }
833
                                                }
834
                                                break;
835
                                        } else
836
                                                //Si se cumple esta condici?n es porque la primera capa que nos encontramos en el TOC es la que acabamos de seleccionar
837
                                                if (lyr.equals(layerAux)) {
838
                                                boolean isSelected = false;
839
                                                for (int i = layers.getLayersCount() - 1; i >= 0; i--) {
840
                                                        FLayer layer = layers.getLayer(i);
841
                                                        if (!isSelected)
842
                                                                isSelected = layer.isActive();
843
                                                        else {
844
                                                                updateActive(layer, true);
845
                                                                if (lyr.equals(layer)) {
846
                                                                        isSelected = false;
847
                                                                }
848
                                                        }
849
                                                }
850
                                                break;
851
                                        }
852
                                }
853

    
854
                }
855

    
856
                /**
857
                 * DOCUMENT ME!
858
                 *
859
                 * @param lyr
860
                 *            DOCUMENT ME!
861
                 * @param active
862
                 *            DOCUMENT ME!
863
                 */
864
        private void updateActive(FLayer lyr, boolean active) {
865
            lyr.setActive(active);
866
            updateActiveChild(lyr);
867
        }
868

    
869
        /**
870
                 * DOCUMENT ME!
871
                 *
872
                 * @param lyr
873
                 *            DOCUMENT ME!
874
                 */
875
        private void updateActiveChild(FLayer lyr) {
876
            if (lyr instanceof FLayers) { // Es la raiz de una rama o
877
                                                                                        // cualquier nodo intermedio.
878

    
879
                FLayers layergroup = (FLayers) lyr;
880

    
881
                for (int i = 0; i < layergroup.getLayersCount(); i++) {
882
                    layergroup.getLayer(i).setActive(lyr.isActive());
883
                    updateActiveChild(layergroup.getLayer(i));
884
                }
885
            }
886
        }
887

    
888
        /**
889
                 * Actualiza la visibilidad de la capas.
890
                 *
891
                 * @param lyr
892
                 *            Capa sobre la que se est? clickando.
893
                 */
894
        private void updateVisible(FLayer lyr) {
895
                if (lyr.isAvailable()) {
896
                        lyr.setVisible(!lyr.visibleRequired());
897
                        updateVisibleChild(lyr);
898
                        updateVisibleParent(lyr);
899
                }
900
        }
901

    
902
        /**
903
                 * Actualiza de forma recursiva la visibilidad de los hijos de la capa
904
                 * que se pasa como par?metro.
905
                 *
906
                 * @param lyr
907
                 *            Capa a actualizar.
908
                 */
909
        private void updateVisibleChild(FLayer lyr) {
910
            if (lyr instanceof FLayers) { //Es la raiz de una rama o cualquier nodo intermedio.
911

    
912
                FLayers layergroup = (FLayers) lyr;
913

    
914
                for (int i = 0; i < layergroup.getLayersCount(); i++) {
915
                    layergroup.getLayer(i).setVisible(lyr.visibleRequired());
916
                    updateVisibleChild(layergroup.getLayer(i));
917
                }
918
            }
919
        }
920

    
921
        /**
922
         * Actualiza de forma recursiva la visibilidad del padre de la capa que
923
         * se pasa como par?metro.
924
         *
925
         * @param lyr Capa a actualizar.
926
         */
927
        private void updateVisibleParent(FLayer lyr) {
928
            FLayers parent = (FLayers) lyr.getParentLayer();
929

    
930
            if (parent != null) {
931
                boolean parentVisible = false;
932

    
933
                for (int i = 0; i < parent.getLayersCount(); i++) {
934
                    if (parent.getLayer(i).visibleRequired()) {
935
                        parentVisible = true;
936
                    }
937
                }
938

    
939
                parent.setVisible(parentVisible);
940
                updateVisibleParent(parent);
941
            }
942
        }
943

    
944
        /**
945
         * DOCUMENT ME!
946
         *
947
         * @param arg0 DOCUMENT ME!
948
         */
949
        public void actionPerformed(ActionEvent arg0) {
950
        }
951

    
952
        /**
953
         * DOCUMENT ME!
954
         *
955
         * @param arg0 DOCUMENT ME!
956
         */
957
        public void mouseReleased(MouseEvent arg0) {
958
            super.mouseReleased(arg0);
959
        }
960

    
961
        /**
962
         * DOCUMENT ME!
963
         *
964
         * @param arg0 DOCUMENT ME!
965
         */
966
        public void mouseEntered(MouseEvent arg0) {
967
            // TODO Auto-generated method stub
968
            super.mouseEntered(arg0);
969

    
970
            // FJP: COMENTO ESTO.
971
            // LO CORRECTO CREO QUE ES IMPLEMENTAR CORRECTAMENTE
972
            // LOS METODOS DE DRAG AND DROP
973

    
974
            /* if (m_Root.getChildCount()==0){
975
               m_Tree.dropRoot(m_Root);
976
               }*/
977
        }
978
    }
979

    
980
}