This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 171516
Collapse All | Expand All

(-)a/projectapi/apichanges.xml (+17 lines)
Lines 107-112 Link Here
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
107
    <!-- ACTUAL CHANGES BEGIN HERE: -->
108
108
109
    <changes>
109
    <changes>
110
        <change id="ProjectIconAnnotator">
111
            <api name="general"/>
112
            <summary>Added <code>ProjectIconAnnotator</code></summary>
113
            <version major="1" minor="33"/>
114
            <date day="22" month="6" year="2010"/>
115
            <author login="jbecicka"/>
116
            <compatibility addition="yes" />
117
            <description>
118
                <p>
119
                    A mechanism for changing the project node icon.
120
                    You can use it for example to add a badge to the project's icon.
121
                </p>
122
            </description>
123
            <class package="org.netbeans.spi.project" name="ProjectIconAnnotator"/>
124
            <issue number="171516"/>
125
        </change>
126
110
        <change id="MoveOrRenameOperationImplementation">
127
        <change id="MoveOrRenameOperationImplementation">
111
            <api name="general"/>
128
            <api name="general"/>
112
            <summary>Added <code>MoveOrRenameOperationImplementation</code></summary>
129
            <summary>Added <code>MoveOrRenameOperationImplementation</code></summary>
(-)a/projectapi/manifest.mf (-1 / +1 lines)
Lines 1-7 Link Here
1
Manifest-Version: 1.0
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.projectapi/1
2
OpenIDE-Module: org.netbeans.modules.projectapi/1
3
OpenIDE-Module-Install: org/netbeans/modules/projectapi/Installer.class
3
OpenIDE-Module-Install: org/netbeans/modules/projectapi/Installer.class
4
OpenIDE-Module-Specification-Version: 1.32
4
OpenIDE-Module-Specification-Version: 1.33
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties
5
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/projectapi/Bundle.properties
6
OpenIDE-Module-Layer: org/netbeans/modules/projectapi/layer.xml
6
OpenIDE-Module-Layer: org/netbeans/modules/projectapi/layer.xml
7
7
(-)a/projectapi/src/org/netbeans/api/project/ProjectUtils.java (-4 / +108 lines)
Lines 44-50 Link Here
44
44
45
package org.netbeans.api.project;
45
package org.netbeans.api.project;
46
46
47
import java.beans.PropertyChangeEvent;
48
import javax.swing.event.ChangeEvent;
49
import org.netbeans.spi.project.ProjectIconAnnotator;
50
import java.awt.Image;
47
import java.beans.PropertyChangeListener;
51
import java.beans.PropertyChangeListener;
52
import java.beans.PropertyChangeSupport;
48
import java.io.IOException;
53
import java.io.IOException;
49
import java.util.HashMap;
54
import java.util.HashMap;
50
import java.util.Map;
55
import java.util.Map;
Lines 53-58 Link Here
53
import java.util.logging.Logger;
58
import java.util.logging.Logger;
54
import java.util.prefs.Preferences;
59
import java.util.prefs.Preferences;
55
import javax.swing.Icon;
60
import javax.swing.Icon;
61
import javax.swing.event.ChangeListener;
56
import org.netbeans.modules.projectapi.AuxiliaryConfigBasedPreferencesProvider;
62
import org.netbeans.modules.projectapi.AuxiliaryConfigBasedPreferencesProvider;
57
import org.netbeans.modules.projectapi.AuxiliaryConfigImpl;
63
import org.netbeans.modules.projectapi.AuxiliaryConfigImpl;
58
import org.netbeans.spi.project.AuxiliaryConfiguration;
64
import org.netbeans.spi.project.AuxiliaryConfiguration;
Lines 64-71 Link Here
64
import org.openide.filesystems.FileStateInvalidException;
70
import org.openide.filesystems.FileStateInvalidException;
65
import org.openide.filesystems.FileUtil;
71
import org.openide.filesystems.FileUtil;
66
import org.openide.util.ImageUtilities;
72
import org.openide.util.ImageUtilities;
73
import org.openide.util.Lookup;
74
import org.openide.util.Lookup.Result;
75
import org.openide.util.LookupEvent;
76
import org.openide.util.LookupListener;
67
import org.openide.util.Mutex;
77
import org.openide.util.Mutex;
68
import org.openide.util.Parameters;
78
import org.openide.util.Parameters;
79
import org.openide.util.WeakListeners;
80
import org.openide.util.WeakSet;
69
81
70
/**
82
/**
71
 * Utility methods to get information about {@link Project}s.
83
 * Utility methods to get information about {@link Project}s.
Lines 87-97 Link Here
87
     */
99
     */
88
    public static ProjectInformation getInformation(Project p) {
100
    public static ProjectInformation getInformation(Project p) {
89
        ProjectInformation pi = p.getLookup().lookup(ProjectInformation.class);
101
        ProjectInformation pi = p.getLookup().lookup(ProjectInformation.class);
90
        if (pi != null) {
102
        if (pi == null) {
91
            return pi;
103
            pi = new BasicInformation(p);
92
        } else {
93
            return new BasicInformation(p);
94
        }
104
        }
105
        ProjectInformation retVal = new AnnotateIconProxyProjectInformation(p, pi);
106
        return retVal;
95
    }
107
    }
96
    
108
    
97
    /**
109
    /**
Lines 253-258 Link Here
253
        }
265
        }
254
        
266
        
255
    }
267
    }
268
269
    private static final class AnnotateIconProxyProjectInformation implements ProjectInformation {
270
271
        private final ProjectInformation pinfo;
272
        private Icon icon;
273
        private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
274
        private final Set<ProjectIconAnnotator> pias = new WeakSet<ProjectIconAnnotator>();
275
        private final PropertyChangeListener listener = new PropertyChangeListener(){
276
277
            @Override
278
            public void propertyChange(PropertyChangeEvent evt) {
279
                if (pinfo.PROP_ICON.equals(evt.getPropertyName())) {
280
                    updateIcon(pinfo, getProject());
281
                }
282
                pcs.firePropertyChange(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
283
            }
284
        };
285
286
        private final ChangeListener clistener = new ChangeListener() {
287
288
            @Override
289
            public void stateChanged(ChangeEvent e) {
290
                updateIcon(pinfo, getProject());
291
                pcs.firePropertyChange(pinfo.PROP_ICON, null, getIcon());
292
            }
293
        };
294
295
        public AnnotateIconProxyProjectInformation(Project p, ProjectInformation pi) {
296
            this.pinfo = pi;
297
            this.pinfo.addPropertyChangeListener(WeakListeners.propertyChange(listener, pinfo));
298
            final Result<ProjectIconAnnotator> lookupResult = Lookup.getDefault().lookupResult(ProjectIconAnnotator.class);
299
            lookupResult.addLookupListener(new LookupListener() {
300
                @Override
301
                public void resultChanged(LookupEvent ev) {
302
                    updateIcon(pinfo, getProject());
303
                    initIconAnnotations(lookupResult);
304
                    pcs.firePropertyChange(pinfo.PROP_ICON, null, getIcon());
305
                }
306
            });
307
            initIconAnnotations(lookupResult);
308
            updateIcon(pi, p);
309
        }
310
311
        private void initIconAnnotations(Result<ProjectIconAnnotator> lookupResult) {
312
            for (ProjectIconAnnotator pa : lookupResult.allInstances()) {
313
                if (!pias.contains(pa)) {
314
                    pa.addChangeListener(WeakListeners.change(clistener, pa));
315
                    pias.add(pa);
316
                }
317
            }
318
        }
319
320
        private void updateIcon(ProjectInformation pi, Project p) {
321
            Image _icon = ImageUtilities.icon2Image(pi.getIcon());
322
            for (ProjectIconAnnotator pa : Lookup.getDefault().lookupAll(ProjectIconAnnotator.class)) {
323
                _icon = pa.annotateIcon(p, _icon, false);
324
            }
325
            icon = ImageUtilities.image2Icon(_icon);
326
        }
327
328
        @Override
329
        public String getName() {
330
            return pinfo.getName();
331
        }
332
333
        @Override
334
        public String getDisplayName() {
335
            return pinfo.getDisplayName();
336
        }
337
338
        @Override
339
        public Icon getIcon() {
340
            return icon;
341
        }
342
343
        @Override
344
        public Project getProject() {
345
            return pinfo.getProject();
346
        }
347
348
        @Override
349
        public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
350
            pcs.addPropertyChangeListener(listener);
351
        }
352
353
        @Override
354
        public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
355
            pcs.removePropertyChangeListener(listener);
356
        }
357
358
    }
359
256
    
360
    
257
    /**
361
    /**
258
     * Find a way of storing extra configuration in a project.
362
     * Find a way of storing extra configuration in a project.
(-)a/projectapi/src/org/netbeans/spi/project/ProjectIconAnnotator.java (+120 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.spi.project;
46
47
import java.awt.Image;
48
import javax.swing.event.ChangeListener;
49
import org.netbeans.api.project.Project;
50
51
/**
52
 * <p>The interface provides a mechanism for changing the project node icon.
53
 * You can use it for example to add a badge to the project's icon. Class implementing this
54
 * interface should be registered using {@link org.openide.util.lookup.ServiceProvider}.</p>
55
 * <pre>
56
 * &#64;ServiceProvider(service=ProjectIconAnnotator.class)
57
 * public class SampleProjectIconAnnotator implements ProjectIconAnnotator {
58
 *
59
 *   private static final Image badgeOpened = ImageUtilities.loadImage("org/samplepath/opened-badge.png");
60
 *   private static final Image badgeClosed = ImageUtilities.loadImage("org/samplepath/closed-badge.png");
61
 *   private static final String tooltip = "Sample tooltip."
62
 *   private ChangeSupport pcs = new ChangeSupport(this);
63
 *
64
 *   Image annotateIcon(Project p, Image original, boolean openedNode) {
65
 *       original = ImageUtilities.addToolTipToImage(original, tooltip);
66
 *       if (openedNode) {
67
 *           original = ImageUtilities.mergeImages(original, badgeOpened, 16, 0);
68
 *       } else {
69
 *           original = ImageUtilities.mergeImages(original, badgeClosed, 16, 0);
70
 *       }
71
 *       return original;
72
 *   }
73
 *
74
 *    @Override
75
 *    public void addChangeListener(ChangeListener listener) {
76
 *        pcs.addChangeListener(listener);
77
 *    }
78
 *
79
 *    @Override
80
 *    public void removeChangeListener(ChangeListener listener) {
81
 *        pcs.removeChangeListener(listener);
82
 *    }
83
 *
84
 *    public void updateMyBadges() {
85
 *        pcs.fireChange();
86
 *    }
87
 *
88
 * }
89
 * </pre>
90
 * @author petrdvorak
91
 * @since 1.33
92
 */
93
public interface ProjectIconAnnotator {
94
95
    /**
96
     * Returns image representing annotated project icon. Return {@code original} if you do not
97
     * intend to change the original icon.
98
     * @param p Project whose icon is to be annotated
99
     * @param original Image with the original icon
100
     * @param openedNode Flag indicating if the node that uses the icon is in opened state or not
101
     * @return Annotated project icon
102
     */
103
    public Image annotateIcon(Project p, Image original, boolean openedNode);
104
105
    /**
106
     * Add a listener to property changes.
107
     * Only {@link #PROP_ICON} may be fired.
108
     * old and new values are undefined
109
     * @param listener a listener to add
110
     */
111
    public void addChangeListener(ChangeListener listener);
112
113
114
    /**
115
     * Remove a listener to property changes.
116
     * @param listener a listener to remove
117
     */
118
    public void removeChangeListener(ChangeListener listener);
119
120
}
(-)a/projectapi/test/unit/src/org/netbeans/api/project/ProjectIconAnnotatorTest.java (+150 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.api.project;
46
47
import java.beans.PropertyChangeEvent;
48
import java.beans.PropertyChangeListener;
49
import java.io.IOException;
50
import org.netbeans.spi.project.ProjectIconAnnotator;
51
import java.awt.Image;
52
import javax.swing.Icon;
53
import javax.swing.event.ChangeListener;
54
import org.netbeans.junit.NbTestCase;
55
import org.openide.filesystems.FileObject;
56
import org.openide.util.ChangeSupport;
57
import org.openide.util.ImageUtilities;
58
import org.openide.util.test.MockLookup;
59
60
/**
61
 *
62
 * @author petrdvorak
63
 */
64
public class ProjectIconAnnotatorTest extends NbTestCase {
65
66
    public ProjectIconAnnotatorTest(String name) {
67
        super(name);
68
    }
69
70
    final static Image icon1 = ImageUtilities.loadImage("org/netbeans/api/project/resources/icon-1.png");
71
72
    private FileObject scratch;
73
    private FileObject goodproject;
74
    private ProjectManager pm;
75
    private ProjectIconAnnotatorImpl pia;
76
    private String testEventName;
77
78
    @Override
79
    protected void setUp() throws Exception {
80
        super.setUp();
81
        scratch = TestUtil.makeScratchDir(this);
82
        goodproject = scratch.createFolder("good");
83
        goodproject.createFolder("testproject");
84
        MockLookup.setInstances(TestUtil.testProjectFactory(), pia = new ProjectIconAnnotatorImpl());
85
        pm = ProjectManager.getDefault();
86
        pm.reset();
87
88
    }
89
90
    @Override
91
    protected void tearDown() throws Exception {
92
        scratch = null;
93
        goodproject = null;
94
        pm = null;
95
        testEventName = null;
96
        pia = null;
97
        super.tearDown();
98
    }
99
100
101
    /**
102
     * Test of annotateIcon method, of class ProjectIconAnnotator.
103
     */
104
    public void testAnnotateIcon() throws IOException {
105
        Project p = pm.findProject(goodproject);
106
        ProjectInformation pi = ProjectUtils.getInformation(p);
107
        Icon img = pi.getIcon();
108
        assertEquals("Annotated image height should be 8", img.getIconHeight(), 8);
109
        assertEquals("Annotated image width should be 8", img.getIconWidth(), 8);
110
        pi.addPropertyChangeListener(new PropertyChangeListener() {
111
112
            @Override
113
            public void propertyChange(PropertyChangeEvent evt) {
114
                testEventName=evt.getPropertyName();
115
            }
116
        });
117
118
        pia.updateBadges();
119
        assertEquals("Event not fired properly", pi.PROP_ICON, testEventName);
120
    }
121
122
    public static final class ProjectIconAnnotatorImpl implements ProjectIconAnnotator {
123
124
125
        private ChangeSupport pcs = new ChangeSupport(this);
126
127
        public ProjectIconAnnotatorImpl() {
128
        }
129
130
        @Override
131
        public Image annotateIcon(Project p, Image original, boolean openedNode) {
132
            return icon1;
133
        }
134
135
        @Override
136
        public void addChangeListener(ChangeListener listener) {
137
            pcs.addChangeListener(listener);
138
        }
139
140
        @Override
141
        public void removeChangeListener(ChangeListener listener) {
142
            pcs.removeChangeListener(listener);
143
        }
144
145
        public void updateBadges() {
146
            pcs.fireChange();
147
        }
148
    }
149
150
}
(-)a/projectui/nbproject/project.xml (-1 / +1 lines)
Lines 91-97 Link Here
91
                    <compile-dependency/>
91
                    <compile-dependency/>
92
                    <run-dependency>
92
                    <run-dependency>
93
                        <release-version>1</release-version>
93
                        <release-version>1</release-version>
94
                        <specification-version>1.17</specification-version>
94
                        <specification-version>1.33</specification-version>
95
                    </run-dependency>
95
                    </run-dependency>
96
                </dependency>
96
                </dependency>
97
                <dependency>
97
                <dependency>
(-)a/projectui/src/org/netbeans/modules/project/ui/ProjectsRootNode.java (+13 lines)
Lines 72-77 Link Here
72
import javax.swing.event.ChangeListener;
72
import javax.swing.event.ChangeListener;
73
import org.netbeans.api.project.FileOwnerQuery;
73
import org.netbeans.api.project.FileOwnerQuery;
74
import org.netbeans.api.project.Project;
74
import org.netbeans.api.project.Project;
75
import org.netbeans.spi.project.ProjectIconAnnotator;
75
import org.netbeans.api.project.ProjectManager;
76
import org.netbeans.api.project.ProjectManager;
76
import org.netbeans.api.project.ProjectUtils;
77
import org.netbeans.api.project.ProjectUtils;
77
import org.netbeans.api.project.SourceGroup;
78
import org.netbeans.api.project.SourceGroup;
Lines 772-777 Link Here
772
                } catch (FileStateInvalidException e) {
773
                } catch (FileStateInvalidException e) {
773
                    LOG.log(Level.INFO, null, e);
774
                    LOG.log(Level.INFO, null, e);
774
                }
775
                }
776
                Project p = getLookup().lookup(Project.class);
777
                if (p != null) {
778
                    for (ProjectIconAnnotator pa : Lookup.getDefault().lookupAll(ProjectIconAnnotator.class)) {
779
                        img = pa.annotateIcon(p, img, false);
780
            }
781
                }
775
            }
782
            }
776
783
777
            return img;
784
            return img;
Lines 787-792 Link Here
787
                } catch (FileStateInvalidException e) {
794
                } catch (FileStateInvalidException e) {
788
                    LOG.log(Level.INFO, null, e);
795
                    LOG.log(Level.INFO, null, e);
789
                }
796
                }
797
                Project p = getLookup().lookup(Project.class);
798
                if (p != null) {
799
                    for (ProjectIconAnnotator pa : Lookup.getDefault().lookupAll(ProjectIconAnnotator.class)) {
800
                        img = pa.annotateIcon(p, img, true);
801
                    }
802
                }
790
            }
803
            }
791
804
792
            return img;
805
            return img;
(-)a/projectui/test/unit/src/org/netbeans/modules/project/ui/ProjectRootNodeIconTest.java (+174 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.project.ui;
46
47
import java.awt.Graphics;
48
import java.awt.Image;
49
import java.awt.image.ImageObserver;
50
import java.awt.image.ImageProducer;
51
import java.beans.BeanInfo;
52
import java.io.IOException;
53
import java.util.Arrays;
54
import java.util.Collection;
55
import java.util.HashSet;
56
import java.util.Set;
57
import java.util.TreeSet;
58
import javax.swing.event.ChangeListener;
59
import org.netbeans.api.project.Project;
60
import org.netbeans.spi.project.ProjectIconAnnotator;
61
import org.netbeans.junit.MockServices;
62
import org.netbeans.junit.NbTestCase;
63
import org.netbeans.modules.project.ui.actions.TestSupport.TestProject;
64
import org.openide.filesystems.FileObject;
65
import org.openide.filesystems.FileStatusEvent;
66
import org.openide.filesystems.FileSystem;
67
import org.openide.filesystems.FileSystem.HtmlStatus;
68
import org.openide.filesystems.FileUtil;
69
import org.openide.filesystems.MultiFileSystem;
70
import org.openide.nodes.AbstractNode;
71
import org.openide.nodes.Children;
72
import org.openide.util.ImageUtilities;
73
import org.openide.util.Lookup;
74
import org.openide.util.lookup.Lookups;
75
76
/**
77
 *
78
 * @author petrdvorak
79
 */
80
public class ProjectRootNodeIconTest extends NbTestCase {
81
82
    public ProjectRootNodeIconTest(String name) {
83
        super(name);
84
    }
85
86
    final static Image icon1 = ImageUtilities.loadImage("org/netbeans/modules/project/ui/resources/icon-1.png");
87
    final static Image icon2 = ImageUtilities.loadImage("org/netbeans/modules/project/ui/resources/icon-2.png");
88
    final static Image icon3 = ImageUtilities.loadImage("org/netbeans/modules/project/ui/resources/icon-3.png");
89
90
    public void testIconAnnotated() throws IOException, Exception {
91
        class BadgedImage extends Image {
92
            final Image original;
93
            BadgedImage(Image original) {this.original = original;}
94
            public @Override int getWidth(ImageObserver observer) {return original.getWidth(observer);}
95
            public @Override int getHeight(ImageObserver observer) {return original.getHeight(observer);}
96
            public @Override ImageProducer getSource() {return original.getSource();}
97
            public @Override Graphics getGraphics() {return original.getGraphics();}
98
            public @Override Object getProperty(String name, ImageObserver observer) {return original.getProperty(name, observer);}
99
            public @Override void flush() {original.flush();}
100
        }
101
        class TestFS extends MultiFileSystem {
102
            String nameBadge = "";
103
            String htmlBadge = "";
104
            boolean badging;
105
            Set<? extends FileObject> badgedFiles;
106
            TestFS() throws Exception {
107
                super(new FileSystem[] {FileUtil.createMemoryFileSystem()});
108
            }
109
            public @Override Status getStatus() {
110
                return new HtmlStatus() {
111
                    public String annotateName(String name, Set<? extends FileObject> files) {
112
                        badgedFiles = files;
113
                        return name + nameBadge;
114
                    }
115
                    public String annotateNameHtml(String name, Set<? extends FileObject> files) {
116
                        badgedFiles = files;
117
                        return name + htmlBadge;
118
                    }
119
                    public Image annotateIcon(Image icon, int iconType, Set<? extends FileObject> files) {
120
                        badgedFiles = files;
121
                        return badging ? new BadgedImage(icon) : icon;
122
                    }
123
                };
124
            }
125
            void fireChange(boolean icon, boolean name, FileObject... files) {
126
                fireFileStatusChanged(new FileStatusEvent(this, new HashSet<FileObject>(Arrays.asList(files)), icon, name));
127
            }
128
        }
129
        TestFS fs = new TestFS();
130
        FileObject root = fs.getRoot();
131
        Project prj = new TestProject(root, null);
132
        assertNotNull(prj);
133
        MockServices.setServices(ProjectIconAnnotatorImpl.class);
134
        Collection<? extends ProjectIconAnnotator> lookupAll = Lookup.getDefault().lookupAll(ProjectIconAnnotator.class);
135
        System.setProperty("test.nodelay", "true");
136
        ProjectsRootNode.BadgingNode node = new ProjectsRootNode.BadgingNode(null, new ProjectsRootNode.ProjectChildren.Pair(prj),
137
                new AbstractNode(Children.LEAF, Lookups.singleton(prj)) {
138
                    public @Override String getDisplayName() {return "Prj";}
139
                    public @Override String getHtmlDisplayName() {return "Prj";}
140
                }, false, true);
141
        Set<FileObject> fos = new TreeSet<FileObject>();
142
        fos.add(prj.getProjectDirectory());
143
        node.setFiles(fos);
144
        Image img = node.getIcon(BeanInfo.ICON_COLOR_16x16);
145
        assertTrue("Icon is not the same as 'icon3'", img.equals(icon3));
146
        assertFalse("Icon is the same as 'icon2'", img.equals(icon2));
147
        img = node.getOpenedIcon(BeanInfo.ICON_COLOR_16x16);
148
        assertTrue("Icon is not the same as 'icon2'", img.equals(icon2));
149
        assertFalse("Icon is the same as 'icon3'", img.equals(icon3));
150
    }
151
152
    public static final class ProjectIconAnnotatorImpl implements ProjectIconAnnotator {
153
154
        public ProjectIconAnnotatorImpl() {
155
        }
156
157
        public Image annotateIcon(Project p, Image original, boolean openedNode) {
158
            if (openedNode)
159
                return icon2;
160
            else
161
                return icon3;
162
        }
163
164
        @Override
165
        public void addChangeListener(ChangeListener listener) {
166
        }
167
168
        @Override
169
        public void removeChangeListener(ChangeListener listener) {
170
        }
171
172
    }
173
174
}

Return to bug 171516