Statistics
| Revision:

gvsig-tools / org.gvsig.tools / library / trunk / org.gvsig.tools / org.gvsig.tools.swing / org.gvsig.tools.swing.impl / src / main / java / org / gvsig / tools / swing / impl / icontheme / BaseIconTheme.java @ 3039

History | View | Annotate | Download (22.9 KB)

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

    
26
import java.awt.Image;
27
import java.io.File;
28
import java.io.IOException;
29
import java.io.InputStream;
30
import java.net.URL;
31
import java.util.ArrayList;
32
import java.util.Collections;
33
import java.util.HashMap;
34
import java.util.HashSet;
35
import java.util.Iterator;
36
import java.util.List;
37
import java.util.Map;
38
import java.util.Set;
39

    
40
import javax.swing.ImageIcon;
41

    
42
import org.apache.commons.io.FileUtils;
43
import org.apache.commons.lang3.StringUtils;
44
import org.gvsig.tools.swing.api.SimpleImage;
45
import org.gvsig.tools.swing.api.ToolsSwingLocator;
46
import org.gvsig.tools.swing.api.ToolsSwingManager;
47
import org.slf4j.Logger;
48
import org.slf4j.LoggerFactory;
49

    
50
import org.gvsig.tools.swing.icontheme.IconTheme;
51
import org.gvsig.tools.swing.impl.DefaultSimpleImage;
52

    
53
/**
54
 * <p>
55
 * This class represents an icon theme, which is basically a mapping of symbolic
56
 * icon names, and real icons (or icon paths). This is useful to change an
57
 * application's icons in an easy way. An icon theme is usually read from disk
58
 * on start up, but can also be created or modified on a later time.</p>
59
 *
60
 */
61
public class BaseIconTheme implements IconTheme {
62

    
63
    protected static Logger logger = LoggerFactory.getLogger(BaseIconTheme.class);
64

    
65
    protected String id = null;
66
    protected String name = null;
67
    protected String description = null;
68
    protected Map<String, Icon> iconList = null;
69
    protected IconTheme defaultTheme = null;
70
    protected String defaultIconName = null;
71
    protected Map<String,String> groupsDescriptions;
72
    protected Map<String,String> subgroupsDescriptions;
73

    
74
    private Map<String,List<URL>> groupsImages;
75
    private Map<String,List<URL>> subgroupsImages;
76
    
77
    class DefaultIcon implements Icon {
78

    
79
        private ImageIcon image;
80
        private ImageIcon scaledImage;
81
        private final URL resource;
82
        private final String name;
83
        private final String group;
84
        private final String provider;
85
        private String description;
86
        private String subgroup;
87

    
88
        DefaultIcon(String provider, String group, String name, ImageIcon image, URL resource) {
89
            this.image = image;
90
            this.scaledImage = this.image;
91
            if (this.image != null ) {
92
                double scaleFactor = ToolsSwingLocator.getIconThemeManager().getScaleFactor();
93
                if (scaleFactor != 1) {
94
                    SimpleImage simpleImage = new DefaultSimpleImage(this.image);
95
                    simpleImage = simpleImage.resize(scaleFactor);
96
                    this.scaledImage = new ImageIcon(simpleImage.getBufferedImage());
97
                }
98
            }
99
            this.resource = resource;
100
            this.group = group;
101
            this.name = name;
102
            this.provider = provider;
103
        }
104

    
105
        public boolean existsIcon() {
106
            if (image != null) {
107
                return true;
108
            }
109

    
110
            InputStream ist = null;
111
            boolean resp;
112

    
113
            try {
114
                ist = resource.openStream();
115
                resp = true;
116
            } catch (Exception ex) {
117
                resp = false;
118
            }
119
            try {
120
                if (ist != null) {
121
                    ist.close();
122
                }
123
            } catch (Exception ex) {
124
            }
125
            return resp;
126
        }
127

    
128
        @Override
129
        public ImageIcon getImageIcon() {
130
            if (this.image == null) {
131
                try {
132
                    this.image = new ImageIcon((URL) this.resource);
133
                    double scaleFactor = ToolsSwingLocator.getIconThemeManager().getScaleFactor();
134
                    if (scaleFactor != 1) {
135
                        SimpleImage simpleImage = new DefaultSimpleImage(this.image);
136
                        simpleImage = simpleImage.resize(scaleFactor);
137
                        this.scaledImage = new ImageIcon(simpleImage.getBufferedImage());
138
                    } else {
139
                        this.scaledImage = this.image;
140
                    }
141
                } catch (Exception ex) {
142
                    return null;
143
                }
144
            }
145
            return this.scaledImage;
146
        }
147

    
148
        @Override
149
        public Image getImage() {
150
            ImageIcon icon = this.getImageIcon();
151
            if (icon == null) {
152
                return null;
153
            }
154
            return icon.getImage();
155
        }
156

    
157
        @Override
158
        public String getName() {
159
            return name;
160
        }
161

    
162
        @Override
163
        public String getGroup() {
164
            return group;
165
        }
166

    
167
        @Override
168
        public Object getResource() {
169
            return resource;
170
        }
171

    
172
        @Override
173
        public URL getURL() {
174
            if (resource instanceof URL) {
175
                return (URL) this.resource;
176
            }
177
            return null;
178
        }
179

    
180
        @Override
181
        public String getLabel() {
182
            if (resource != null) {
183
                return resource.toString();
184
            }
185
            if (image != null) {
186
                return image.toString();
187
            }
188
            return "";
189
        }
190

    
191
        @Override
192
        public int compareTo(Icon other) {
193
            String this_id = this.getProviderName() + "/" + this.getGroup() + "/" + this.getName();
194
            String other_id = other.getProviderName() + "/" + other.getGroup() + "/" + other.getName();
195
            return this_id.compareTo(other_id);
196
        }
197

    
198
        @Override
199
        public String getProviderName() {
200
            return provider;
201
        }
202

    
203
        @Override
204
        public String getDescription() {
205
            return this.description;
206
        }
207

    
208
        @Override
209
        public String getSubgroup() {
210
            return this.subgroup;
211
        }
212

    
213
        @Override
214
        public String getGroupDescription() {
215
            if( defaultTheme == null ) {
216
                return groupsDescriptions.get(this.group);
217
            }
218
            return defaultTheme.getGroupDescription(this.group);            
219
        }
220

    
221
        @Override
222
        public String getSubgroupDescription() {
223
            if( defaultTheme == null ) {
224
                return subgroupsDescriptions.get(this.group + "|" + this.subgroup);
225
//                return getSubgroupDescription(this.group, this.subgroup);
226
            }
227
            return defaultTheme.getSubgroupDescription(this.group, this.subgroup);            
228
        }
229

    
230
        @Override
231
        public void setDescription(String description) {
232
            this.description = description;
233
        }
234

    
235
        @Override
236
        public void setSubgroup(String subgroup) {
237
            this.subgroup = subgroup;
238
        }
239
        
240
    }
241

    
242
    public BaseIconTheme() {
243
        this(null);
244
    }
245

    
246
    public BaseIconTheme(IconTheme defaultIconTheme) {
247
        this.groupsDescriptions = new HashMap<>();
248
        this.subgroupsDescriptions = new HashMap<>();
249
        this.groupsImages = new HashMap<>();
250
        this.subgroupsImages = new HashMap<>();
251
        this.setDefault(defaultIconTheme);
252
        this.id = "default"; // El id no traducirlo
253
        this.name = "default";
254
        this.description = "Default icon theme";
255
        this.iconList = new HashMap<>();
256
    }
257

    
258
    /**
259
     * Load the icons of the theme
260
     *
261
     * @param resource
262
     */
263
    @Override
264
    public void load(Object resource) {
265
        // Do nothing.
266
    }
267

    
268
    /**
269
     * Override this to load icons on demand instead of load on the creation of
270
     * the theme.
271
     */
272
    protected void deferredLoad() {
273
        // Do nothing
274
    }
275

    
276
    private void logstack(String msg) {
277
        try {
278
            throw new IllegalArgumentException();
279
        } catch (IllegalArgumentException e) {
280
            logger.debug(msg, e);
281
        }
282
    }
283

    
284
    @Override
285
    public void setDefault(IconTheme def) {
286
        if (def == this) {
287
            defaultTheme = null;
288
        } else {
289
            defaultTheme = def;
290
        }
291
    }
292

    
293
    @Override
294
    public IconTheme getDefault() {
295
        return defaultTheme;
296
    }
297

    
298
    @Override
299
    public boolean exists(String iconName) {
300
        if (StringUtils.isEmpty(iconName)) {
301
            return false;
302
        }
303
        deferredLoad();
304

    
305
        if (iconList.containsKey(iconName)) {
306
            return true;
307
        }
308
        return defaultTheme != null && defaultTheme.exists(iconName);
309
    }
310

    
311
    @Override
312
    public Iterator<String> iterator() {
313
        Set<String> names = new HashSet<>();
314

    
315
        deferredLoad();
316

    
317
        if (defaultTheme != null) {
318
            Iterator<String> it = defaultTheme.iterator();
319
            while (it.hasNext()) {
320
                names.add(it.next());
321
            }
322
        }
323
        Iterator<String> it = iconList.keySet().iterator();
324
        while (it.hasNext()) {
325
            names.add(it.next());
326
        }
327
        List<String> names2 = new ArrayList<>(names);
328
        Collections.sort(names2);
329
        return names2.iterator();
330
    }
331

    
332
    @Override
333
    public Iterator<Icon> getThemeIcons() {
334
        Map<String, Icon> themeIcons = new HashMap<>();
335

    
336
        deferredLoad();
337
        if (defaultTheme != null) {
338
            Iterator<Icon> it = defaultTheme.getThemeIcons();
339
            while (it.hasNext()) {
340
                Icon icon = it.next();
341
                themeIcons.put(icon.getName(), icon);
342
            }
343
        }
344
        Iterator<Icon> it = iconList.values().iterator();
345
        while (it.hasNext()) {
346
            Icon icon = it.next();
347
            themeIcons.put(icon.getName(), icon);
348
        }
349
        List<Icon> themeIcons2 = new ArrayList<>(themeIcons.values());
350
        Collections.sort(themeIcons2);
351
        return themeIcons2.iterator();
352
    }
353

    
354
    @Override
355
    public Icon getThemeIcon(String name) {
356
        if (StringUtils.isEmpty(name)) {
357
            return null;
358
        }
359
        deferredLoad();
360
        Icon themeIcon = (Icon) iconList.get(name);
361
        if (themeIcon != null) {
362
            return themeIcon;
363
        }
364
        if (defaultTheme != null && defaultTheme.exists(name)) {
365
            return defaultTheme.getThemeIcon(name);
366
        }
367
        return null;
368
    }
369
    
370
    public boolean isMyIcon(String name) {
371
        if (StringUtils.isEmpty(name)) {
372
            return false;
373
        }
374
        deferredLoad();
375
        Icon themeIcon = (Icon) iconList.get(name);
376
        return (themeIcon != null);
377
    }
378

    
379
    @Override
380
    public ImageIcon get(String name) {
381
        ImageIcon icon;
382

    
383
        if (!StringUtils.isEmpty(name)) {
384
            deferredLoad();
385
            Icon themeIcon = (Icon) iconList.get(name);
386
            if (themeIcon != null) {
387
                icon = themeIcon.getImageIcon();
388
                if (icon != null) {
389
                    return icon;
390
                }
391
            }
392
            if (defaultTheme != null && defaultTheme.exists(name)) {
393
                return defaultTheme.get(name);
394
            }
395
        }
396
        logger.info("get('" + name + "') icon not found");
397
        logstack("get('" + name + "') icon not found");
398
        return getNoIcon();
399
    }
400

    
401
    @Override
402
    public String getName() {
403
        return name;
404
    }
405

    
406
    @Override
407
    public void setName(String themeName) {
408
        name = themeName;
409
    }
410

    
411
    @Override
412
    public String getID() {
413
        return this.id;
414
    }
415

    
416
    @Override
417
    public void setID(String id) {
418
        this.id = id;
419
    }
420

    
421
    @Override
422
    public String getDescription() {
423
        return description;
424
    }
425

    
426
    @Override
427
    public void setDescription(String description) {
428
        this.description = description;
429
    }
430

    
431
    /**
432
     * Returns the name of the icon theme
433
     */
434
    @Override
435
    public String toString() {
436
        String s = this.getName();
437
        if (StringUtils.isEmpty(s)) {
438
            s = this.getID();
439
        }
440
        return s;
441
//                if( StringUtils.isEmpty(this.getDescription()) ) {
442
//                        return s;
443
//                }
444
//                return s + " - " + this.getDescription();
445
    }
446

    
447
    @Override
448
    public ImageIcon getDefaultIcon() {
449
        ImageIcon imageIcon;
450
        Icon icon;
451

    
452
        icon = this.getThemeIcon(defaultIconName);
453
        if (icon != null) {
454
            imageIcon = icon.getImageIcon();
455
            if (imageIcon != null) {
456
                return imageIcon;
457
            }
458
        }
459
        icon = this.getThemeIcon(NO_ICON_NAME);
460
        if (icon != null) {
461
            imageIcon = icon.getImageIcon();
462
            if (imageIcon != null) {
463
                return imageIcon;
464
            }
465
        }
466
        return new ImageIcon();
467
    }
468

    
469
    @Override
470
    public void setDefaultIcon(ImageIcon icon) {
471
        this.defaultIconName = null;
472
        this.register(null, null, NO_ICON_NAME, icon, null);
473
    }
474

    
475
    @Override
476
    public void setDefaultIcon(URL resource) {
477
        this.defaultIconName = null;
478
        this.register(null, null, NO_ICON_NAME, null, resource);
479
    }
480

    
481
    @Override
482
    public void setDefaultIcon(String name) {
483
        this.defaultIconName = name;
484
    }
485

    
486
    @Override
487
    public void register(String provider, String group,  
488
            String name,
489
            ImageIcon icon, URL resource) {
490
        this.register(provider, group, null, name, icon, resource);
491
    }
492
    
493
    @Override
494
    public IconTheme.Icon register(String provider, String group, String subgroup, 
495
            String name,
496
            ImageIcon icon, URL resource) {
497
        if (StringUtils.isEmpty(name)) {
498
            throw new IllegalArgumentException("name is empty");
499
        }
500
        deferredLoad();
501
        if (icon == null && resource == null) {
502
            Icon themeIcon = new DefaultIcon(provider, group, name, null, null);
503
            themeIcon.setSubgroup(subgroup);
504
            iconList.put(name, themeIcon);
505
            throw new IllegalArgumentException("icon and resource for '" + getIconIdentifier(provider, group, name) + "' are null");
506
        }
507
        DefaultIcon themeIcon = new DefaultIcon(provider, group, name, icon, resource);
508
        themeIcon.setSubgroup(subgroup);
509

    
510
        iconList.put(name, themeIcon);
511
        if (!themeIcon.existsIcon()) {
512
            throw new IllegalArgumentException("Resource not found for icon '" + getIconIdentifier(provider, group, name) + "'");
513
        }
514
        return themeIcon;
515
    }
516

    
517
    private String getIconIdentifier(String provider, String group, String name) {
518
        deferredLoad();
519
        String identifier = null;
520
        if (!StringUtils.isEmpty(provider)) {
521
            identifier = provider;
522
        }
523
        if (group != null) {
524
            identifier = identifier + "/" + group;
525
        }
526
        if (name == null) {
527
            identifier = identifier + "/unknow";
528
        } else {
529
            identifier = identifier + "/" + name;
530
        }
531
        return identifier;
532
    }
533

    
534
    @Override
535
    public void registerDefault(String provider, String group, String name, ImageIcon icon, URL resource) throws IllegalArgumentException {
536
        this.registerDefault(provider, group, null, name, icon, resource);
537
    }
538

    
539
    @Override
540
    public IconTheme.Icon registerDefault(String provider, String group, String subgroup,
541
            String name, ImageIcon icon, URL resource) {
542
        deferredLoad();
543
        if (defaultTheme != null) {
544
            Icon themeIcon = defaultTheme.getThemeIcon(name);
545
            if (themeIcon==null ) {
546
                return defaultTheme.register(provider, group, subgroup, name, icon, resource);
547
            }
548
            return themeIcon;
549
        }
550
        return this.register(provider, group, subgroup, name, icon, resource);
551
    }
552

    
553
    @Override
554
    public void export(File folder) {
555
        if (!folder.exists()) {
556
            folder.mkdir();
557
        }
558
        folder = new File(folder, this.getID());
559
        if (!folder.exists()) {
560
            folder.mkdir();
561
        }
562
        URL url_no_icon = this.getThemeIcon(NO_ICON_NAME).getURL();
563

    
564
        Iterator<Icon> themeIcons = this.getThemeIcons();
565
        while (themeIcons.hasNext()) {
566
            Icon themeIcon = themeIcons.next();
567
            URL url_src = themeIcon.getURL();
568
            if (url_src == null) {
569
                url_src = url_no_icon;
570
            }
571
            File target;
572
            if (themeIcon.getGroup() != null) {
573
                target = new File(folder, themeIcon.getGroup());
574
                target.mkdir();
575
            } else {
576
                target = new File(folder.getAbsolutePath());
577
            }
578
            target = new File(target, themeIcon.getName() + ".png");
579
            try {
580
                FileUtils.copyURLToFile(url_src, target);
581
            } catch (IOException e) {
582
                // TODO 
583
            }
584
        }
585
    }
586

    
587
    // ===================================================================
588
    /**
589
     * @deprecated use getDefaultIcon
590
     */
591
    @Override
592
    public ImageIcon getNoIcon() {
593
        return this.getDefaultIcon();
594
    }
595

    
596
    /**
597
     * @param name
598
     * @param image
599
     * @deprecated use
600
     * {@link #registerDefault(PluginServices, String, String, ImageIcon, Object)}
601
     */
602
    @Override
603
    public void registerDefault(String name, ImageIcon image) {
604
        logstack("registerDefault('" + name + "'), deprecated method.");
605
        try {
606
            registerDefault(null, null, name, image, null);
607
        } catch (IllegalArgumentException e) {
608
            logger.info(e.getLocalizedMessage(), e);
609
        }
610
    }
611

    
612
    /**
613
     * @param name
614
     * @param resource
615
     * @deprecated use
616
     * {@link #registerDefault(PluginServices, String, String, ImageIcon, Object)}
617
     */
618
    @Override
619
    public void registerDefault(String name, Object resource) {
620
        logstack("registerDefault('" + name + "'), deprecated method.");
621
        try {
622
            registerDefault(null, null, name, null, (URL) resource);
623
        } catch (IllegalArgumentException e) {
624
            logger.info(e.getLocalizedMessage(), e);
625
        }
626
    }
627

    
628
    /**
629
     * @param name
630
     * @param image
631
     * @deprecated use
632
     * {@link #registerDefault(PluginServices, String, String, ImageIcon, Object)}
633
     */
634
    @Override
635
    public void register(String name, ImageIcon image) {
636
        logstack("register('" + name + "'), deprecated method.");
637
        try {
638
            register(null, null, name, image, null);
639
        } catch (IllegalArgumentException e) {
640
            logger.info(e.getLocalizedMessage(), e);
641
        }
642
    }
643

    
644
    /**
645
     * @param name
646
     * @param resource
647
     * @deprecated use
648
     * {@link #registerDefault(PluginServices, String, String, ImageIcon, Object)}
649
     */
650
    @Override
651
    public void register(String name, Object resource) {
652
        logstack("register('" + name + "'), deprecated method.");
653
        try {
654
            register(null, null, name, null, (URL) resource);
655
        } catch (IllegalArgumentException e) {
656
            logger.info(e.getLocalizedMessage(), e);
657
        }
658
    }
659

    
660
    /**
661
     * @param iconName
662
     * @param loader
663
     * @return
664
     * @deprecated use get(String iconName) instead.
665
     */
666
    @Override
667
    public ImageIcon get(String iconName, ClassLoader loader) {
668
        logstack("get('" + iconName + "', loader), deprecated method.");
669
        return this.get(iconName);
670
    }
671

    
672
    @Override
673
    public String getGroupDescription(String group) {
674
        return this.groupsDescriptions.get(group);
675
    }
676

    
677
    @Override
678
    public void setGroupDescription(String group, String description) {
679
        this.groupsDescriptions.put(group, description);
680
    }
681

    
682
    @Override
683
    public String getSubgroupDescription(String group, String subgroup) {
684
        return this.subgroupsDescriptions.get(group + "|" + subgroup);
685
    }
686

    
687
    @Override
688
    public void setSubgroupDescription(String group, String subgroup, String description) {
689
        this.subgroupsDescriptions.put(group + "|" + subgroup, description);
690
    }
691
    
692
    public void addGroupImage(String group, URL resource) {
693
        List<URL> images = this.groupsImages.get(group);
694
        if( images == null ) {
695
            images = new ArrayList<>();
696
            this.groupsImages.put(group, images);
697
        }
698
        images.add(resource);
699
    }
700
    
701
    public List<SimpleImage> getGroupImages(String group) {
702
        List<URL> images = this.groupsImages.get(group);
703
        if( images == null ) {
704
            return Collections.EMPTY_LIST;
705
        }
706
        ToolsSwingManager manager = ToolsSwingLocator.getToolsSwingManager();
707
        List<SimpleImage> simpleImages = new ArrayList<>();
708
        for (URL image : images) {
709
            SimpleImage simpleImage = manager.createSimpleImage(image);
710
            simpleImages.add(simpleImage);
711
        }
712
        return simpleImages;
713
    } 
714
    
715
    public void addSubgroupImage(String group, String subgroup, URL resource) {
716
        String key = group + "|" + subgroup;
717
        List<URL> images = this.subgroupsImages.get(key);
718
        if( images == null ) {
719
            images = new ArrayList<>();
720
            this.subgroupsImages.put(key, images);
721
        }
722
        images.add(resource);
723
    }
724
    
725
    public List<SimpleImage> getSubgroupImages(String group, String subgroup) {
726
        String key = group + "|" + subgroup;
727
        List<URL> images = this.subgroupsImages.get(key);
728
        if( images == null ) {
729
            return Collections.EMPTY_LIST;
730
        }
731
        ToolsSwingManager manager = ToolsSwingLocator.getToolsSwingManager();
732
        List<SimpleImage> simpleImages = new ArrayList<>();
733
        for (URL image : images) {
734
            SimpleImage simpleImage = manager.createSimpleImage(image);
735
            simpleImages.add(simpleImage);
736
        }
737
        return simpleImages;
738
    } 
739

    
740
    @Override
741
    public boolean matchID(String id) {
742
        return StringUtils.equalsIgnoreCase(id, this.id);
743
    }
744
    
745
    
746
    
747
}