Statistics
| Revision:

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

History | View | Annotate | Download (16.7 KB)

1 3746 jaume
/* 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$
45
* $Log$
46 3873 jaume
* Revision 1.2.2.4  2006-02-01 16:25:23  jaume
47
* *** empty log message ***
48
*
49
* Revision 1.2.2.3  2006/01/31 16:25:24  jaume
50 3855 jaume
* correcciones de bugs
51
*
52
* Revision 1.4  2006/01/31 10:40:31  jaume
53 3807 jaume
* *** empty log message ***
54
*
55
* Revision 1.3  2006/01/26 16:07:14  jaume
56
* *** empty log message ***
57
*
58
* Revision 1.2.2.1  2006/01/26 12:59:32  jaume
59 3800 jaume
* 0.5
60
*
61
* Revision 1.2  2006/01/24 14:36:33  jaume
62 3746 jaume
* This is the new version
63
*
64
* Revision 1.1.2.11  2006/01/23 12:54:45  jaume
65
* *** empty log message ***
66
*
67
* Revision 1.1.2.10  2006/01/20 08:50:52  jaume
68
* handles time dimension for the NASA Jet Propulsion Laboratory WMS
69
*
70
* Revision 1.1.2.9  2006/01/17 12:55:40  jaume
71
* *** empty log message ***
72
*
73
* Revision 1.1.2.6  2006/01/11 12:20:30  jaume
74
* *** empty log message ***
75
*
76
* Revision 1.1.2.5  2006/01/10 11:33:31  jaume
77
* Time dimension working against Jet Propulsion Laboratory's WMS server
78
*
79
* Revision 1.1.2.4  2006/01/09 18:10:38  jaume
80
* casi con el time dimension
81
*
82
* Revision 1.1.2.3  2006/01/05 23:15:53  jaume
83
* *** empty log message ***
84
*
85
* Revision 1.1.2.2  2006/01/04 18:09:02  jaume
86
* Time dimension
87
*
88
* Revision 1.1.2.1  2006/01/03 18:08:40  jaume
89
* *** empty log message ***
90
*
91
* Revision 1.1.2.1  2006/01/02 18:08:01  jaume
92
* Tree de estilos
93
*
94
*
95
*/
96
/**
97
 *
98
 */
99
package com.iver.cit.gvsig.gui.panels;
100
101
import java.awt.Color;
102
import java.awt.Component;
103
import java.util.ArrayList;
104
import java.util.Hashtable;
105
import java.util.Vector;
106
107
import javax.swing.JLabel;
108
import javax.swing.JPanel;
109
import javax.swing.JRadioButton;
110
import javax.swing.JTree;
111
import javax.swing.event.TreeModelListener;
112
import javax.swing.tree.TreeCellRenderer;
113
import javax.swing.tree.TreeModel;
114
import javax.swing.tree.TreePath;
115
116
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode;
117
import com.iver.cit.gvsig.fmap.layers.WMSLayerNode.FMapWMSStyle;
118
119
/**
120
 * This class holds a visual tree that handles the selection of the styles in the
121
 * selected layers. It encapsulates any gui interface handling the mouse selection.
122
 * <p>
123
 * It has a method getStylesSelection that returns the current selection in a
124
 * bi-dimensional string array containing the layer name and the selected style name.
125
 * </p>
126
 * <p>
127
 * Keep in mind that although it's similar to LayersTree it is not the same.
128
 * It does not use the same instances of the WMSLayerNode that LayerTreeModel
129
 * because it allows to repeat layers. So, each layer is a completely new
130
 * WMSLayerNode containing same properties but not the same parent (which is always
131
 * the tree root) and each style is a completely new FMapStyle containing same
132
 * properties but its parent is one of the layers of the StylesTree and not one
133
 * of those of the Layers tree.
134
 * </p>
135
 *
136
 * @author jaume dominguez faus
137
 *
138
 */
139
public class StyleTree extends JTree {
140
    public StyleTree(){
141
        super();
142
        initialize();
143
    }
144
145
    private void initialize(){
146
        setToggleClickCount(1);
147
        setRowHeight(22);
148
149
        setCellRenderer(new TreeCellRenderer() {
150
            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
151
                if (leaf) {
152
                    JPanel leafComponent = new JPanel();
153
                    leafComponent.setBackground(Color.WHITE);
154 3855 jaume
                    JRadioButton leafRadioButton = new JRadioButton("", ((StyleTreeModel) getModel()).isSelected((FMapWMSStyle) value));//selected);
155 3746 jaume
                    leafRadioButton.setBackground(Color.WHITE);
156
                    leafComponent.add(leafRadioButton);
157
                    leafComponent.add(new JLabel(((FMapWMSStyle) value).title));
158
                    return leafComponent;
159
                } else {
160
                        JTree t = new JTree();
161
                            Component branchComponent = t.getCellRenderer().getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
162
                            return branchComponent;
163
                }
164
            }});
165
        addMouseListener(new java.awt.event.MouseAdapter() {
166
            public void mouseClicked(java.awt.event.MouseEvent e) {
167 3855 jaume
                ((StyleTreeModel)getModel()).setSelectedLeaf(getSelectionPath());
168 3746 jaume
                clearSelection();
169
                repaint();
170
            }
171
        });
172
    }
173
174
    /**
175
     * Expands this tree.
176
     *
177
     */
178
    public void expandAll(){
179
        int row = 0;
180
        while (row < getRowCount()) {
181
          expandRow(row);
182
          row++;
183
          }
184
    }
185
186
    public Vector getStylesSelection(){
187 3855 jaume
            return ((StyleTreeModel)getModel()).getStylesSelection();
188 3746 jaume
    }
189
190
    public Vector getStyleSelectionTitles(){
191 3855 jaume
        if (getModel() instanceof StyleTreeModel)
192
            return ((StyleTreeModel)getModel()).getStyleSelectionTitles();
193 3746 jaume
        else
194
            return null;
195
    }
196
197
    /**
198
     * Sets the selected styles in the StylesTree. The argument styleNames is
199
     * a Vector with exactly the same amount of strings than the amount of
200
     * themes (layers) contained by the tree. A blank or null string will
201
     * leave the default style for that layer, but this element <b>must exist</b>
202
     * in the array in any case.
203
     *
204
     * @param styleNames, Vector containing the style names.
205
     * The styles order <b>must match</b> with the layer order.
206
     */
207 3855 jaume
208
    public void setSelections(WMSLayerNode[] selectedLayers, Vector styleNames){
209 3746 jaume
            if (styleNames!=null) {
210 3855 jaume
                    StyleTreeModel model = (StyleTreeModel) getModel();
211
                    //if (model.getChildCount(model.getRoot())!=styleNames.size()){
212
                    if (model.getCount()!=styleNames.size()){
213 3746 jaume
                            throw new RuntimeException("Bad arguments: styleNames length is "
214
                                            +styleNames.size()+", should be "
215 3855 jaume
                                            +model.getCount()+".");
216 3746 jaume
                    }
217 3855 jaume
                    model.clear();
218
                    for (int i = 0; i < selectedLayers.length; i++) {
219
                                model.addLayerBranch(selectedLayers[i]);
220
                                if (styleNames.get(i)!=null && styleNames.get(i)!="")
221
                                        model.setStyleSelected(i, (String) styleNames.get(i));
222
                        }
223 3746 jaume
            }
224
    }
225 3855 jaume
226
//    public void _setSelections(WMSLayerNode[] selectedLayers, Vector styleNames){
227
//            if (styleNames!=null) {
228
//                    StyleTreeModel model = (StyleTreeModel) getModel();
229
//                    if (model.getChildCount(model.getRoot())!=styleNames.size()){
230
//                            throw new RuntimeException("Bad arguments: styleNames length is "
231
//                                            +styleNames.size()+", should be "
232
//                                            +model.getCount()+".");
233
//                    }
234
//
235
//                    for (int i = 0; i < styleNames.size(); i++) {
236
//                            if (styleNames.get(i)==null || ((String)styleNames.get(i)).equals(""))
237
//                                    continue;
238
//                            Object node = model.getChild(model.getRoot(), i);
239
//                            for (int j = 0; j < model.getChildCount(node); j++) {
240
//                                    if (((String)styleNames.get(i)).equals(((FMapWMSStyle)model.getChild(node, j)).name))
241
//                                            model.selectStyle(model.getChild(node, j));
242
//
243
//                            }
244
//                    }
245
//            }
246
//    }
247 3746 jaume
248
}
249
250
251 3855 jaume
class StyleTreeModel implements TreeModel {
252
    private WMSLayerNode root;
253 3746 jaume
    /**
254 3855 jaume
     * key: WMSLayerNode.
255 3746 jaume
     * value: FMapWMSStyle
256
     */
257 3855 jaume
    private Hashtable selections = new Hashtable();
258 3746 jaume
    /**
259
     * this will hold the layers order even if the layer does not appear in
260
     * the tree because it has no styles.
261
     */
262 3855 jaume
    private ArrayList layers = new ArrayList();
263
264
    public StyleTreeModel(WMSLayerNode root){
265 3746 jaume
        this.root = root;
266
267
    }
268
269 3855 jaume
    protected void clear() {
270
                layers.clear();
271
                selections.clear();
272
        }
273
274
        protected void setStyleSelected(int index, String styleName) {
275
            WMSLayerNode layer = (WMSLayerNode) layers.get(index);
276
            if (layer.getStyles()==null)
277
                    return;
278
            for (int i = 0; i < layer.getStyles().size(); i++) {
279
                        FMapWMSStyle sty = (FMapWMSStyle) layer.getStyles().get(i);
280
                        if (sty.name.equals(styleName))
281
                                selections.put(sty.parent, sty);
282
                }
283
        }
284
285
        /**
286
     * Returns the amount of layers currently selected.
287
     * @return
288
     */
289
    public int getCount() {
290
            if (layers==null)
291
                    return 0;
292
            else return layers.size();
293
        }
294
295
        /**
296 3746 jaume
     * Marks this style as selected in the StylesTreeModel.
297
     * @param style
298
     */
299
    public void selectStyle(Object style) {
300
        selections.put(((FMapWMSStyle)style).parent, style);
301
    }
302
303
    /**
304
     * Gets the names of the selected styles into a Vector using the same order
305
     * as they was represented in the StylesTree.
306
     * @return
307
     */
308
    protected Vector getStylesSelection() {
309
            if (selections.isEmpty())
310
                    return null;
311
        Vector values = new Vector();
312
        for (int i = 0; i < layers.size(); i++) {
313
            values.add(i, "");
314
        }
315
316
        for (int i = 0; i < layers.size(); i++) {
317
                FMapWMSStyle sty = (FMapWMSStyle) selections.get(layers.get(i));
318
                if (sty == null)
319
                        values.set(i, "");
320
                else
321
                        values.set(i, sty.name);
322
                }
323
        return values;
324
    }
325
326
    /**
327
     * Gets the names of the selected styles into a Vector using the same order
328
     * as they was represented in the StylesTree.
329
     * @return
330
     */
331
    protected Vector getStyleSelectionTitles() {
332
            if (selections.isEmpty())
333
                    return null;
334
        Vector values = new Vector();
335
        for (int i = 0; i < layers.size(); i++) {
336
            values.add(i, "");
337
        }
338
339
        for (int i = 0; i < layers.size(); i++) {
340
                FMapWMSStyle sty = (FMapWMSStyle) selections.get(layers.get(i));
341
                if (sty == null)
342
                        values.set(i, "");
343
                else
344
                        values.set(i, sty.title);
345
                }
346
        return values;
347
    }
348
349 3873 jaume
//    /**
350
//     * Sets a leaf (an style) selected.
351
//     * @param selectionPath to this leaf.
352
//     */
353
//    protected void _setSelectedLeaf(TreePath selectionPath) {
354
//        if (selectionPath!=null){
355
//            Object[] objects = selectionPath.getPath();
356
//            Object item = objects[objects.length-1];
357
//            if (isLeaf(item)){
358
//                selections.put(((FMapWMSStyle) item).parent, item);
359
//            }
360
//        }
361
//    }
362
363 3746 jaume
    /**
364
     * Sets a leaf (an style) selected.
365
     * @param selectionPath to this leaf.
366
     */
367
    protected void setSelectedLeaf(TreePath selectionPath) {
368
        if (selectionPath!=null){
369
            Object[] objects = selectionPath.getPath();
370
            Object item = objects[objects.length-1];
371
            if (isLeaf(item)){
372 3873 jaume
                    FMapWMSStyle style = (FMapWMSStyle) item;
373
                    String layerName = style.parent.getName();
374
375
                    // find a layer with the same name of the selected style's owner one
376
                    for (int i = 0; i < layers.size(); i++) {
377
                                WMSLayerNode lyr = (WMSLayerNode) layers.get(i);
378
                                if (lyr.getName().equals(layerName)){
379
380
                                        // find the style of the layer that we have found that has the same
381
                                        // name of the selected style.
382
                                        for (int j = 0; j < lyr.getStyles().size(); j++) {
383
                                                FMapWMSStyle theStyle = (FMapWMSStyle) lyr.getStyles().get(j);
384
                                                if (theStyle.name.equals(style.name)){
385
386
                                                        // and then, set it selected.
387
                                                selections.put(((FMapWMSStyle) theStyle).parent, theStyle);
388
                                                    return;
389
    }}}}}}}
390 3746 jaume
391
    /**
392
     * Will return true if this style is selected.
393
     * @param style
394
     * @return
395
     */
396
    protected boolean isSelected(FMapWMSStyle style){
397 3855 jaume
            String layerName = style.parent.getName();
398
            for (int i = 0; i < layers.size(); i++) {
399
                        WMSLayerNode lyr = (WMSLayerNode) layers.get(i);
400
                        if (lyr.getName().equals(layerName))
401
                                if (((FMapWMSStyle)selections.get(lyr)).name.equals(style.name))
402
                                        return true;
403
                }
404
        return false;
405 3746 jaume
    }
406
407
    /*
408
     *  (non-Javadoc)
409
     * @see javax.swing.tree.TreeModel#getChildCount(java.lang.Object)
410
     */
411
    public int getChildCount(Object parent) {
412
        int count=0;
413
414
        if (parent == root)
415
            count = ((WMSLayerNode) parent).getChildren().size();
416
        else
417
            count = ((WMSLayerNode) parent).getStyles().size();
418
        return count;
419
    }
420
421
    /*
422
     *  (non-Javadoc)
423
     * @see javax.swing.tree.TreeModel#isLeaf(java.lang.Object)
424
     */
425
    public boolean isLeaf(Object node) {
426
        return (node instanceof FMapWMSStyle);
427
428
    }
429
430
    /*
431
     *  (non-Javadoc)
432
     * @see javax.swing.tree.TreeModel#addTreeModelListener(javax.swing.event.TreeModelListener)
433
     */
434
    public void addTreeModelListener(TreeModelListener l) {
435
    }
436
437
    /*
438
     *  (non-Javadoc)
439
     * @see javax.swing.tree.TreeModel#removeTreeModelListener(javax.swing.event.TreeModelListener)
440
     */
441
    public void removeTreeModelListener(TreeModelListener l) {
442
    }
443
444
    /*
445
     *  (non-Javadoc)
446
     * @see javax.swing.tree.TreeModel#getChild(java.lang.Object, int)
447
     */
448
    public Object getChild(Object parent, int index) {
449
        if (parent instanceof FMapWMSStyle)
450
            return null;
451
        if (parent == root)
452
            return ((WMSLayerNode) parent).getChildren().get(index);
453
454
        return ((WMSLayerNode) parent).getStyles().get(index);
455
    }
456
457
    /*
458
     *  (non-Javadoc)
459
     * @see javax.swing.tree.TreeModel#getIndexOfChild(java.lang.Object, java.lang.Object)
460
     */
461
    public int getIndexOfChild(Object parent, Object child) {
462
        if (parent instanceof FMapWMSStyle){
463
            return -1;
464
        }
465
466
        WMSLayerNode l = (WMSLayerNode)parent;
467
        if (l.getParent()==null){
468
            for (int i = 0; i < l.getChildren().size(); i++) {
469
                if (l.getChildren().get(i).equals(child)){
470
                   return i;
471
                }
472
            }
473
        } else {
474
            for (int i = 0; i < l.getStyles().size(); i++) {
475
                if (l.getChildren().get(i).equals(child)){
476
                    return i;
477
                }
478
            }
479
        }
480
        return -1;
481
    }
482
483
    /*
484
     *  (non-Javadoc)
485
     * @see javax.swing.tree.TreeModel#valueForPathChanged(javax.swing.tree.TreePath, java.lang.Object)
486
     */
487
    public void valueForPathChanged(TreePath path, Object newValue) {
488
    }
489
490
    /**
491
     * Adds a new branch to this tree. It must be a layer node.
492
     * @param node
493
     * @return <b>True</b>, if the added branch actually defines any style.
494
     *         <b>False</b>, if the layer has no styles.
495
     */
496
    public boolean addLayerBranch(WMSLayerNode node){
497
            layers.add(node);
498
        if (node.getStyles()==null || node.getStyles().size()==0){
499
            return false;
500
        }
501
502
        WMSLayerNode myNode = (WMSLayerNode) node.clone();
503
        myNode.setParent((WMSLayerNode) getRoot());
504
        ((WMSLayerNode)getRoot()).getChildren().add(myNode);
505
506
        // Figure out a default style and pre-select it
507
        ArrayList sty = myNode.getStyles();
508
        selectStyle(sty.get(0));
509
        for (int i = 0; i < sty.size(); i++) {
510
            FMapWMSStyle s = (FMapWMSStyle) sty.get(i);
511
            if (s.name.toLowerCase().equals("default")){
512
                selectStyle(s);
513
                break;
514
            }
515
        }
516
517
        return true;
518
    }
519
520
    /*
521
     *  (non-Javadoc)
522
     * @see javax.swing.tree.TreeModel#getRoot()
523
     */
524
    public Object getRoot() {
525
        if (root == null) {
526
            root = new WMSLayerNode();
527
            root.setParent(null);
528
        }
529
        return root;
530
    }
531
532
    /**
533
     * @param node, the tree's desired node.
534
     * @return Returns the title.
535
     */
536
    public String getTitle(Object node) {
537
        if (node instanceof WMSLayerNode)
538
            return ((WMSLayerNode) node).getTitle();
539
        return ((FMapWMSStyle) node).toString();
540
    }
541
542
    /*
543
     *  (non-Javadoc)
544
     * @see java.lang.Object#toString()
545
     */
546
    public String toString(){
547
        return getTitle(this);
548
    }
549
}