Statistics
| Revision:

svn-gvsig-desktop / branches / v05 / extensions / extWMS / src / com / iver / cit / gvsig / gui / panels / StyleTree.java @ 3895

History | View | Annotate | Download (16.8 KB)

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

    
42
/* CVS MESSAGES:
43
*
44
* $Id: StyleTree.java 3895 2006-02-02 10:44:18Z jaume $
45
* $Log$
46
* Revision 1.2.2.5  2006-02-02 10:44:18  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.2.2.4  2006/02/01 16:25:23  jaume
50
* *** empty log message ***
51
*
52
* Revision 1.2.2.3  2006/01/31 16:25:24  jaume
53
* correcciones de bugs
54
*
55
* Revision 1.4  2006/01/31 10:40:31  jaume
56
* *** empty log message ***
57
*
58
* Revision 1.3  2006/01/26 16:07:14  jaume
59
* *** empty log message ***
60
*
61
* Revision 1.2.2.1  2006/01/26 12:59:32  jaume
62
* 0.5
63
*
64
* Revision 1.2  2006/01/24 14:36:33  jaume
65
* This is the new version
66
*
67
* Revision 1.1.2.11  2006/01/23 12:54:45  jaume
68
* *** empty log message ***
69
*
70
* Revision 1.1.2.10  2006/01/20 08:50:52  jaume
71
* handles time dimension for the NASA Jet Propulsion Laboratory WMS
72
*
73
* Revision 1.1.2.9  2006/01/17 12:55:40  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.1.2.6  2006/01/11 12:20:30  jaume
77
* *** empty log message ***
78
*
79
* Revision 1.1.2.5  2006/01/10 11:33:31  jaume
80
* Time dimension working against Jet Propulsion Laboratory's WMS server
81
*
82
* Revision 1.1.2.4  2006/01/09 18:10:38  jaume
83
* casi con el time dimension
84
*
85
* Revision 1.1.2.3  2006/01/05 23:15:53  jaume
86
* *** empty log message ***
87
*
88
* Revision 1.1.2.2  2006/01/04 18:09:02  jaume
89
* Time dimension
90
*
91
* Revision 1.1.2.1  2006/01/03 18:08:40  jaume
92
* *** empty log message ***
93
*
94
* Revision 1.1.2.1  2006/01/02 18:08:01  jaume
95
* Tree de estilos
96
*
97
*
98
*/
99
/**
100
 * 
101
 */
102
package com.iver.cit.gvsig.gui.panels;
103

    
104
import java.awt.Color;
105
import java.awt.Component;
106
import java.util.ArrayList;
107
import java.util.Hashtable;
108
import java.util.Vector;
109

    
110
import javax.swing.JLabel;
111
import javax.swing.JPanel;
112
import javax.swing.JRadioButton;
113
import javax.swing.JTree;
114
import javax.swing.event.TreeModelListener;
115
import javax.swing.tree.TreeCellRenderer;
116
import javax.swing.tree.TreeModel;
117
import javax.swing.tree.TreePath;
118

    
119
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode;
120
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode.FMapWMSStyle;
121

    
122
/**
123
 * This class holds a visual tree that handles the selection of the styles in the
124
 * selected layers. It encapsulates any gui interface handling the mouse selection.
125
 * <p>
126
 * It has a method getStylesSelection that returns the current selection in a 
127
 * bi-dimensional string array containing the layer name and the selected style name.
128
 * </p>
129
 * <p>
130
 * Keep in mind that although it's similar to LayersTree it is not the same.
131
 * It does not use the same instances of the WMSLayerNode that LayerTreeModel
132
 * because it allows to repeat layers. So, each layer is a completely new 
133
 * WMSLayerNode containing same properties but not the same parent (which is always
134
 * the tree root) and each style is a completely new FMapStyle containing same
135
 * properties but its parent is one of the layers of the StylesTree and not one
136
 * of those of the Layers tree.
137
 * </p>
138
 * 
139
 * @author jaume dominguez faus
140
 *
141
 */
142
public class StyleTree extends JTree {
143
    public StyleTree(){
144
        super();
145
        initialize();
146
    }
147
    
148
    private void initialize(){
149
        setToggleClickCount(1);
150
        setRowHeight(22);
151
        
152
        setCellRenderer(new TreeCellRenderer() {
153
            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
154
                if (leaf) {
155
                    JPanel leafComponent = new JPanel();
156
                    leafComponent.setBackground(Color.WHITE);
157
                    JRadioButton leafRadioButton = new JRadioButton("", ((StyleTreeModel) getModel()).isSelected((FMapWMSStyle) value));//selected);
158
                    leafRadioButton.setBackground(Color.WHITE);
159
                    leafComponent.add(leafRadioButton);
160
                    leafComponent.add(new JLabel(((FMapWMSStyle) value).title));
161
                    return leafComponent;
162
                } else {
163
                        JTree t = new JTree();
164
                            Component branchComponent = t.getCellRenderer().getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); 
165
                            return branchComponent;
166
                }
167
            }});
168
        addMouseListener(new java.awt.event.MouseAdapter() { 
169
            public void mouseClicked(java.awt.event.MouseEvent e) {
170
                ((StyleTreeModel)getModel()).setSelectedLeaf(getSelectionPath());
171
                clearSelection();
172
                repaint();
173
            }
174
        });
175
    }
176
    
177
    /**
178
     * Expands this tree.
179
     *
180
     */
181
    public void expandAll(){
182
        int row = 0; 
183
        while (row < getRowCount()) {
184
          expandRow(row);
185
          row++;
186
          }
187
    }
188
    
189
    public Vector getStylesSelection(){
190
            return ((StyleTreeModel)getModel()).getStylesSelection();
191
    }
192
    
193
    public Vector getStyleSelectionTitles(){
194
        if (getModel() instanceof StyleTreeModel)
195
            return ((StyleTreeModel)getModel()).getStyleSelectionTitles();
196
        else
197
            return null;
198
    }
199
    
200
    /**
201
     * Sets the selected styles in the StylesTree. The argument styleNames is
202
     * a Vector with exactly the same amount of strings than the amount of
203
     * themes (layers) contained by the tree. A blank or null string will
204
     * leave the default style for that layer, but this element <b>must exist</b>
205
     * in the array in any case.
206
     * 
207
     * @param styleNames, Vector containing the style names. 
208
     * The styles order <b>must match</b> with the layer order. 
209
     */
210
    public void setSelections(WMSLayerNode[] selectedLayers, Vector styleNames){
211
            if (styleNames!=null) {
212
                    StyleTreeModel model = (StyleTreeModel) getModel();
213
                    //if (model.getChildCount(model.getRoot())!=styleNames.size()){
214
                    if (model.getCount()!=styleNames.size()){
215
                            throw new RuntimeException("Bad arguments: styleNames length is "
216
                                            +styleNames.size()+", should be "
217
                                            +model.getCount()+".");
218
                    }
219
                    model.clear();
220
                    for (int i = 0; i < selectedLayers.length; i++) {
221
                                model.addLayerBranch(selectedLayers[i]);
222
                                if (styleNames.get(i)!=null && styleNames.get(i)!="")
223
                                        model.setStyleSelected(i, (String) styleNames.get(i));
224
                        }        
225
            }
226
    }
227

    
228
//    public void _setSelections(WMSLayerNode[] selectedLayers, Vector styleNames){
229
//            if (styleNames!=null) {
230
//                    StyleTreeModel model = (StyleTreeModel) getModel();
231
//                    if (model.getChildCount(model.getRoot())!=styleNames.size()){
232
//                            throw new RuntimeException("Bad arguments: styleNames length is "
233
//                                            +styleNames.size()+", should be "
234
//                                            +model.getCount()+".");
235
//                    }
236
//                    
237
//                    for (int i = 0; i < styleNames.size(); i++) {
238
//                            if (styleNames.get(i)==null || ((String)styleNames.get(i)).equals(""))
239
//                                    continue;
240
//                            Object node = model.getChild(model.getRoot(), i);
241
//                            for (int j = 0; j < model.getChildCount(node); j++) {
242
//                                    if (((String)styleNames.get(i)).equals(((FMapWMSStyle)model.getChild(node, j)).name))
243
//                                            model.selectStyle(model.getChild(node, j));
244
//                                    
245
//                            }
246
//                    }
247
//            }
248
//    }
249
    
250
}
251

    
252

    
253
class StyleTreeModel implements TreeModel {
254
    private WMSLayerNode root;
255
    /**
256
     * key: WMSLayerNode.
257
     * value: FMapWMSStyle
258
     */
259
    private Hashtable selections = new Hashtable();
260
    /**
261
     * this will hold the layers order even if the layer does not appear in
262
     * the tree because it has no styles.
263
     */
264
    private ArrayList layers = new ArrayList();
265
        
266
    public StyleTreeModel(WMSLayerNode root){
267
        this.root = root;
268
        
269
    }
270
    
271
    protected void clear() {
272
                layers.clear();
273
                selections.clear();
274
        }
275

    
276
        protected void setStyleSelected(int index, String styleName) {
277
            WMSLayerNode layer = (WMSLayerNode) layers.get(index);
278
            if (layer.getStyles()==null)
279
                    return;
280
            for (int i = 0; i < layer.getStyles().size(); i++) {
281
                        FMapWMSStyle sty = (FMapWMSStyle) layer.getStyles().get(i);
282
                        if (sty.name.equals(styleName))
283
                                selections.put(sty.parent, sty);
284
                }
285
        }
286

    
287
        /**
288
     * Returns the amount of layers currently selected.
289
     * @return
290
     */
291
    public int getCount() {
292
            if (layers==null)
293
                    return 0;
294
            else return layers.size();
295
        }
296

    
297
        /**
298
     * Marks this style as selected in the StylesTreeModel.
299
     * @param style
300
     */
301
    public void selectStyle(Object style) {
302
        selections.put(((FMapWMSStyle)style).parent, style);
303
    }
304

    
305
    /**
306
     * Gets the names of the selected styles into a Vector using the same order
307
     * as they was represented in the StylesTree.
308
     * @return
309
     */
310
    protected Vector getStylesSelection() {
311
            if (selections.isEmpty())
312
                    return null;
313
        Vector values = new Vector();
314
        for (int i = 0; i < layers.size(); i++) {
315
            values.add(i, "");
316
        }
317
        
318
        for (int i = 0; i < layers.size(); i++) {
319
                FMapWMSStyle sty = (FMapWMSStyle) selections.get(layers.get(i));
320
                if (sty == null)
321
                        values.set(i, "");
322
                else 
323
                        values.set(i, sty.name);
324
                }
325
        return values;
326
    }
327
    
328
    /**
329
     * Gets the names of the selected styles into a Vector using the same order
330
     * as they was represented in the StylesTree.
331
     * @return
332
     */
333
    protected Vector getStyleSelectionTitles() {
334
            if (selections.isEmpty())
335
                    return null;
336
        Vector values = new Vector();
337
        for (int i = 0; i < layers.size(); i++) {
338
            values.add(i, "");
339
        }
340
        
341
        for (int i = 0; i < layers.size(); i++) {
342
                FMapWMSStyle sty = (FMapWMSStyle) selections.get(layers.get(i));
343
                if (sty == null)
344
                        values.set(i, "");
345
                else 
346
                        values.set(i, sty.title);
347
                }
348
        return values;
349
    }
350

    
351
//    /**
352
//     * Sets a leaf (an style) selected.
353
//     * @param selectionPath to this leaf.
354
//     */
355
//    protected void _setSelectedLeaf(TreePath selectionPath) {
356
//        if (selectionPath!=null){
357
//            Object[] objects = selectionPath.getPath();
358
//            Object item = objects[objects.length-1];
359
//            if (isLeaf(item)){
360
//                selections.put(((FMapWMSStyle) item).parent, item);
361
//            }
362
//        }
363
//    }
364
    
365
    /**
366
     * Sets a leaf (an style) selected.
367
     * @param selectionPath to this leaf.
368
     */
369
    protected void setSelectedLeaf(TreePath selectionPath) {
370
        if (selectionPath!=null){
371
            Object[] objects = selectionPath.getPath();
372
            Object item = objects[objects.length-1];
373
            if (isLeaf(item)){
374
                    FMapWMSStyle style = (FMapWMSStyle) item;
375
                    String layerName = style.parent.getName();
376
                    
377
                    // find a layer with the same name of the selected style's owner one
378
                    for (int i = 0; i < layers.size(); i++) {
379
                                WMSLayerNode lyr = (WMSLayerNode) layers.get(i);
380
                                if (lyr.getName().equals(layerName)){
381
                                        
382
                                        // find the style of the layer that we have found that has the same
383
                                        // name of the selected style.
384
                                        for (int j = 0; j < lyr.getStyles().size(); j++) {
385
                                                FMapWMSStyle theStyle = (FMapWMSStyle) lyr.getStyles().get(j);
386
                                                if (theStyle.name.equals(style.name)){
387
                                                        
388
                                                        // and then, set it selected.
389
                                                selections.put(((FMapWMSStyle) theStyle).parent, theStyle);
390
                                                    return;
391
    }}}}}}}        
392
    
393
    /**
394
     * Will return true if this style is selected.
395
     * @param style
396
     * @return
397
     */
398
    protected boolean isSelected(FMapWMSStyle style){
399
            String layerName = style.parent.getName();
400
            for (int i = 0; i < layers.size(); i++) {
401
                        WMSLayerNode lyr = (WMSLayerNode) layers.get(i);
402
                        if (lyr.getName().equals(layerName))
403
                                if (((FMapWMSStyle)selections.get(lyr)).name.equals(style.name))
404
                                        return true;
405
                }
406
        return false;
407
    }
408
    
409
    /*
410
     *  (non-Javadoc)
411
     * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
412
     */
413
    public int getChildCount(Object parent) {
414
        int count=0;
415
        
416
        if (parent == root)
417
            count = ((WMSLayerNode) parent).getChildren().size();
418
        else
419
            count = ((WMSLayerNode) parent).getStyles().size();
420
        return count;
421
    }
422

    
423
    /*
424
     *  (non-Javadoc)
425
     * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
426
     */
427
    public boolean isLeaf(Object node) {
428
        return (node instanceof FMapWMSStyle);
429
        
430
    }
431

    
432
    /*
433
     *  (non-Javadoc)
434
     * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
435
     */
436
    public void addTreeModelListener(TreeModelListener l) {
437
    }
438

    
439
    /*
440
     *  (non-Javadoc)
441
     * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
442
     */
443
    public void removeTreeModelListener(TreeModelListener l) {
444
    }
445

    
446
    /*
447
     *  (non-Javadoc)
448
     * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
449
     */
450
    public Object getChild(Object parent, int index) {
451
        if (parent instanceof FMapWMSStyle)
452
            return null;
453
        if (parent == root)
454
            return ((WMSLayerNode) parent).getChildren().get(index);
455
        
456
        return ((WMSLayerNode) parent).getStyles().get(index);
457
    }
458

    
459
    /*
460
     *  (non-Javadoc)
461
     * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
462
     */
463
    public int getIndexOfChild(Object parent, Object child) {
464
        if (parent instanceof FMapWMSStyle){ 
465
            return -1;   
466
        }
467
         
468
        WMSLayerNode l = (WMSLayerNode)parent;
469
        if (l.getParent()==null){
470
            for (int i = 0; i < l.getChildren().size(); i++) {
471
                if (l.getChildren().get(i).equals(child)){
472
                   return i;
473
                }
474
            }
475
        } else {
476
            for (int i = 0; i < l.getStyles().size(); i++) {
477
                if (l.getChildren().get(i).equals(child)){
478
                    return i;
479
                }
480
            }
481
        }
482
        return -1;
483
    }
484
    
485
    /*
486
     *  (non-Javadoc)
487
     * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
488
     */
489
    public void valueForPathChanged(TreePath path, Object newValue) {
490
    }
491

    
492
    /**
493
     * Adds a new branch to this tree. It must be a layer node.
494
     * @param node
495
     * @return <b>True</b>, if the added branch actually defines any style.
496
     *         <b>False</b>, if the layer has no styles.
497
     */
498
    public boolean addLayerBranch(WMSLayerNode node){
499
            layers.add(node);
500
        if (node.getStyles()==null || node.getStyles().size()==0){
501
            return false;
502
        }
503
        
504
        WMSLayerNode myNode = (WMSLayerNode) node.clone();
505
        myNode.setParent((WMSLayerNode) getRoot());
506
        ((WMSLayerNode)getRoot()).getChildren().add(myNode);
507
        
508
        // Figure out a default style and pre-select it
509
        ArrayList sty = myNode.getStyles();
510
        selectStyle(sty.get(0));
511
        for (int i = 0; i < sty.size(); i++) {
512
            FMapWMSStyle s = (FMapWMSStyle) sty.get(i);
513
            if (s.name.toLowerCase().equals("default")){
514
                selectStyle(s);
515
                break;
516
            }
517
        }
518
   
519
        return true;
520
    }
521

    
522
    /*
523
     *  (non-Javadoc)
524
     * @see javax.swing.tree.TreeModel#getRoot()
525
     */
526
    public Object getRoot() {
527
        if (root == null) {
528
            root = new WMSLayerNode();
529
            root.setParent(null);
530
        }
531
        return root;
532
    }
533
    
534
    /**
535
     * @param node, the tree's desired node.
536
     * @return Returns the title.
537
     */
538
    public String getTitle(Object node) {
539
        if (node instanceof WMSLayerNode)
540
            return ((WMSLayerNode) node).getTitle();
541
        return ((FMapWMSStyle) node).toString();
542
    }
543
    
544
    /*
545
     *  (non-Javadoc)
546
     * @see java.lang.Object#toString()
547
     */
548
    public String toString(){
549
        return getTitle(this);
550
    }
551
}