Source Code Cross Referenced for ProjectCustomizer.java in  » IDE-Netbeans » project.ant » org » netbeans » spi » project » ui » support » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » project.ant » org.netbeans.spi.project.ui.support 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.spi.project.ui.support;
043:
044:        import java.awt.Dialog;
045:        import java.awt.Image;
046:        import java.awt.event.ActionListener;
047:        import java.io.IOException;
048:        import java.util.ArrayList;
049:        import java.util.Collections;
050:        import java.util.HashMap;
051:        import java.util.List;
052:        import java.util.Map;
053:        import java.util.logging.Level;
054:        import java.util.logging.Logger;
055:        import javax.swing.JComponent;
056:        import javax.swing.JPanel;
057:
058:        import org.netbeans.modules.project.uiapi.CategoryModel;
059:        import org.netbeans.modules.project.uiapi.CategoryView;
060:        import org.netbeans.modules.project.uiapi.CategoryChangeSupport;
061:        import org.netbeans.modules.project.uiapi.CustomizerDialog;
062:        import org.netbeans.modules.project.uiapi.CustomizerPane;
063:        import org.netbeans.modules.project.uiapi.Utilities;
064:        import org.netbeans.spi.project.ui.support.ProjectCustomizer.Category;
065:        import org.openide.cookies.InstanceCookie;
066:        import org.openide.filesystems.FileObject;
067:        import org.openide.filesystems.FileStateInvalidException;
068:        import org.openide.filesystems.Repository;
069:        import org.openide.loaders.DataFolder;
070:        import org.openide.loaders.DataObject;
071:        import org.openide.util.HelpCtx;
072:        import org.openide.util.Lookup;
073:
074:        /** Support for creating dialogs which can be used as project
075:         * customizers. The dialog may display multiple panels or categories.
076:         * @see org.netbeans.spi.project.ui.CustomizerProvider
077:         * @see ProjectCustomizer.Category
078:         *
079:         * @author Petr Hrebejk, Martin Krauskopf
080:         */
081:        public final class ProjectCustomizer {
082:
083:            /** Factory/Namespace class only. */
084:            private ProjectCustomizer() {
085:            }
086:
087:            /** Creates standard customizer dialog which can be used for implementation
088:             * of {@link org.netbeans.spi.project.ui.CustomizerProvider}. You don't need
089:             * to call <code>pack()</code> method on the dialog. The resulting dialog will
090:             * be non-modal. <br>
091:             * Call <code>show()</code> on the dialog to make it visible. The dialog 
092:             * will be closed automatically after click on "OK" or "Cancel" button.
093:             * 
094:             * @param categories array of descriptions of categories to be shown in the
095:             *        dialog. Note that categories have the <code>valid</code>
096:             *        property. If any of the given categories is not valid cusomizer's
097:             *        OK button will be disabled until all categories become valid
098:             *        again.
099:             * @param componentProvider creator of GUI components for categories in the
100:             *        customizer dialog.
101:             * @param preselectedCategory name of one of the supplied categories or null.
102:             *        Category with given name will be selected. If  <code>null</code>
103:             *        or if the category of given name does not exist the first category will
104:             *        be selected.
105:             * @param okOptionListener listener which will be notified when the user presses
106:             *        the OK button.
107:             * @param helpCtx Help context for the dialog, which will be used when the
108:             *        panels in the customizer do not specify their own help context.
109:             * @return standard project customizer dialog.
110:             */
111:            public static Dialog createCustomizerDialog(Category[] categories,
112:                    CategoryComponentProvider componentProvider,
113:                    String preselectedCategory,
114:                    ActionListener okOptionListener, HelpCtx helpCtx) {
115:                return createCustomizerDialog(categories, componentProvider,
116:                        preselectedCategory, okOptionListener, null, helpCtx);
117:            }
118:
119:            /** Creates standard customizer dialog which can be used for implementation
120:             * of {@link org.netbeans.spi.project.ui.CustomizerProvider}. Use this version if you need 
121:             * to run processing of the customizer data partially off AWT Event Queue. You don't need
122:             * to call <code>pack()</code> method on the dialog. The resulting dialog will
123:             * be non-modal. <br>
124:             * Call <code>show()</code> on the dialog to make it visible. If you want the dialog to be
125:             * closed after user presses the "OK" button you have to call hide() and dispose() on it.
126:             * (Usually in the <code>actionPerformed(...)</code> method of the listener
127:             * you provided as a parameter. In case of the click on the "Cancel" button
128:             * the dialog will be closed automatically.
129:             * @since org.netbeans.modules.projectuiapi/1 1.26
130:             * @param categories array of descriptions of categories to be shown in the
131:             *        dialog. Note that categories have the <code>valid</code>
132:             *        property. If any of the given categories is not valid cusomizer's
133:             *        OK button will be disabled until all categories become valid
134:             *        again.
135:             * @param componentProvider creator of GUI components for categories in the
136:             *        customizer dialog.
137:             * @param preselectedCategory name of one of the supplied categories or null.
138:             *        Category with given name will be selected. If  <code>null</code>
139:             *        or if the category of given name does not exist the first category will
140:             *        be selected.
141:             * @param okOptionListener listener which will be notified when the user presses
142:             *        the OK button.
143:             * @param storeListener listener which will be notified when the user presses OK button.
144:             *        Listener will be executed after okOptionListener outside of AWT EventQueue.
145:             *        Usually to be used to save modified files on disk.
146:             * @param helpCtx Help context for the dialog, which will be used when the
147:             *        panels in the customizer do not specify their own help context.
148:             * @return standard project customizer dialog.
149:             */
150:            public static Dialog createCustomizerDialog(Category[] categories,
151:                    CategoryComponentProvider componentProvider,
152:                    String preselectedCategory,
153:                    ActionListener okOptionListener,
154:                    ActionListener storeListener, HelpCtx helpCtx) {
155:                CustomizerPane innerPane = createCustomizerPane(categories,
156:                        componentProvider, preselectedCategory);
157:                Dialog dialog = CustomizerDialog.createDialog(okOptionListener,
158:                        storeListener, innerPane, helpCtx, categories,
159:                        componentProvider);
160:                return dialog;
161:            }
162:
163:            /**
164:             * Creates standard customizer dialog that can be used for implementation of
165:             * {@link org.netbeans.spi.project.ui.CustomizerProvider} based on content of a folder in Layers.
166:             * Use this method when you want to allow composition and 3rd party additions to your customizer UI.
167:             * You don't need to call <code>pack()</code> method on the dialog. The resulting dialog will
168:             * be non-modal. <br> 
169:             * Call <code>show()</code> on the dialog to make it visible. The dialog 
170:             * will be closed automatically after click on "OK" or "Cancel" button.
171:             * 
172:             * @since org.netbeans.modules.projectuiapi/1 1.15
173:             * @param folderPath the path in the System Filesystem that is used as root for panel composition.
174:             *        The content of the folder is assummed to be {@link org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider} instances
175:             * @param context the context for the panels, up to the project type what the context shall be, for example org.netbeans.api.project.Project instance
176:             * @param preselectedCategory name of one of the supplied categories or null.
177:             *        Category with given name will be selected. If  <code>null</code>
178:             *        or if the category of given name does not exist the first category will
179:             *        be selected.
180:             * @param okOptionListener listener which will be notified when the user presses
181:             *        the OK button.
182:             * @param helpCtx Help context for the dialog, which will be used when the
183:             *        panels in the customizer do not specify their own help context.
184:             * @return standard project customizer dialog.
185:             */
186:            public static Dialog createCustomizerDialog(String folderPath,
187:                    Lookup context, String preselectedCategory,
188:                    ActionListener okOptionListener, HelpCtx helpCtx) {
189:                return createCustomizerDialog(folderPath, context,
190:                        preselectedCategory, okOptionListener, null, helpCtx);
191:            }
192:
193:            /**
194:             * Creates standard customizer dialog that can be used for implementation of
195:             * {@link org.netbeans.spi.project.ui.CustomizerProvider} based on content of a folder in Layers.
196:             * Use this method when you want to allow composition and 3rd party additions to your customizer UI.
197:             * This version runs processing of the customizer data partially off AWT Event Queue.
198:             * You don't need to call <code>pack()</code> method on the dialog. The resulting dialog will
199:             * be non-modal. <br> 
200:             * Call <code>show()</code> on the dialog to make it visible. If you want the dialog to be
201:             * closed after user presses the "OK" button you have to call hide() and dispose() on it.
202:             * (Usually in the <code>actionPerformed(...)</code> method of the listener
203:             * you provided as a parameter. In case of the click on the "Cancel" button
204:             * the dialog will be closed automatically.
205:             * 
206:             * @since org.netbeans.modules.projectuiapi/1 1.26
207:             * @param folderPath the path in the System Filesystem that is used as root for panel composition.
208:             *        The content of the folder is assummed to be {@link org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider} instances
209:             * @param context the context for the panels, up to the project type what the context shall be, for example org.netbeans.api.project.Project instance
210:             * @param preselectedCategory name of one of the supplied categories or null.
211:             *        Category with given name will be selected. If  <code>null</code>
212:             *        or if the category of given name does not exist the first category will
213:             *        be selected.
214:             * @param okOptionListener listener which will be notified when the user presses
215:             *        the OK button.
216:             * @param storeListener listener which will be notified when the user presses OK button.
217:             *        Listener will be executed after okOptionListener outside of AWT EventQueue.
218:             *        Usually to be used to save modified files on disk
219:             * @param helpCtx Help context for the dialog, which will be used when the
220:             *        panels in the customizer do not specify their own help context.
221:             * @return standard project customizer dialog.
222:             */
223:            public static Dialog createCustomizerDialog(String folderPath,
224:                    Lookup context, String preselectedCategory,
225:                    ActionListener okOptionListener,
226:                    ActionListener storeListener, HelpCtx helpCtx) {
227:                FileObject root = Repository.getDefault()
228:                        .getDefaultFileSystem().findResource(folderPath);
229:                if (root == null) {
230:                    throw new IllegalArgumentException("The designated path "
231:                            + folderPath
232:                            + " doesn't exist. Cannot create customizer.");
233:                }
234:                DataFolder def = DataFolder.findFolder(root);
235:                assert def != null : "Cannot find DataFolder for " + folderPath;
236:                DelegateCategoryProvider prov = new DelegateCategoryProvider(
237:                        def, context);
238:                return createCustomizerDialog(prov.getSubCategories(), prov,
239:                        preselectedCategory, okOptionListener, storeListener,
240:                        helpCtx);
241:            }
242:
243:            /** Creates standard innerPane for customizer dialog.
244:             */
245:            private static CustomizerPane createCustomizerPane(
246:                    Category[] categories,
247:                    CategoryComponentProvider componentProvider,
248:                    String preselectedCategory) {
249:
250:                CategoryChangeSupport changeSupport = new CategoryChangeSupport();
251:                registerCategoryChangeSupport(changeSupport, categories);
252:
253:                CategoryModel categoryModel = new CategoryModel(categories);
254:                JPanel categoryView = new CategoryView(categoryModel);
255:                CustomizerPane customizerPane = new CustomizerPane(
256:                        categoryView, categoryModel, componentProvider);
257:
258:                if (preselectedCategory == null) {
259:                    preselectedCategory = categories[0].getName();
260:                }
261:
262:                Category c = categoryModel.getCategory(preselectedCategory);
263:                if (c != null) {
264:                    categoryModel.setCurrentCategory(c);
265:                }
266:
267:                return customizerPane;
268:            }
269:
270:            private static void registerCategoryChangeSupport(
271:                    final CategoryChangeSupport changeSupport,
272:                    final Category[] categories) {
273:                for (int i = 0; i < categories.length; i++) {
274:                    Utilities.putCategoryChangeSupport(categories[i],
275:                            changeSupport);
276:                    Category[] subCategories = categories[i].getSubcategories();
277:                    if (subCategories != null) {
278:                        registerCategoryChangeSupport(changeSupport,
279:                                subCategories);
280:                    }
281:                }
282:            }
283:
284:            /** Provides components for categories.
285:             */
286:            public static interface CategoryComponentProvider {
287:
288:                /** Creates component which has to be shown for given category.
289:                 * @param category The Category
290:                 * @return UI component for category customization
291:                 */
292:                JComponent create(Category category);
293:
294:            }
295:
296:            /**
297:             * Interface for creation of Customizer categories and their respective UI panels.
298:             * Implementations are to be registered in System FileSystem via module layers. Used by the
299:             * {@link org.netbeans.spi.project.ui.support.ProjectCustomizer#createCustomizerDialog(String,Lookup,String,ActionListener,HelpCtx)}
300:             * The panel/category created by the provider can get notified that the customizer got
301:             * closed by setting an <code>ActionListener</code> to 
302:             * {@link org.netbeans.spi.project.ui.support.ProjectCustomizer.Category#setOkButtonListener} .
303:             * UI Component can be defined for category folder that is represented as node with subnodes in the category
304:             * tree of project customizer. Name of the file that defines the instance class in layer for such category 
305:             * must be named "Self". Such CompositeCategory won't have the createCategory() method called, but will have the category created by
306:             * the infrastructure based on the folder content.
307:             * For details and usage see issue #91276.
308:             * @since org.netbeans.modules.projectuiapi/1 1.22
309:             */
310:            public static interface CompositeCategoryProvider {
311:
312:                /**
313:                 * create the Category instance for the given project customizer context.
314:                 * @param context Lookup instance passed from project The content is up to the project type, please consult documentation
315:                 * for the project type you want to integrate your panel into.
316:                 * @return A category instance, can be null, in which case no category and no panels are created for given context.
317:                 *   The instance is expected to have no subcategories.
318:                 */
319:                Category createCategory(Lookup context);
320:
321:                /**
322:                 * create the UI component for given category and context.
323:                 * The panel/category created by the provider can get notified that the customizer got
324:                 * closed by setting an <code>ActionListener</code> to 
325:                 * {@link org.netbeans.spi.project.ui.support.ProjectCustomizer.Category#setOkButtonListener}.
326:                 * @param category Category instance that was created in the createCategory method.
327:                 * @param context Lookup instance passed from project The content is up to the project type, please consult documentation
328:                 * for the project type you want to integrate your panel into.
329:                 */
330:                JComponent createComponent(Category category, Lookup context);
331:            }
332:
333:            /** Describes category of properties to be customized by given component
334:             */
335:            public static final class Category {
336:
337:                private String name;
338:                private String displayName;
339:                private Image icon;
340:                private Category[] subcategories;
341:                private boolean valid;
342:                private String errorMessage;
343:                private ActionListener okListener;
344:                private ActionListener storeListener;
345:
346:                /** Private constructor. See the factory method.
347:                 */
348:                private Category(String name, String displayName, Image icon,
349:                        Category[] subcategories) {
350:
351:                    this .name = name;
352:                    this .displayName = displayName;
353:                    this .icon = icon;
354:                    this .subcategories = subcategories;
355:                    this .valid = true; // default
356:                }
357:
358:                /** Factory method which creates new category description.
359:                 * @param name Programmatic name of the category
360:                 * @param displayName Name to be shown to the user
361:                 * @param icon Icon for given category. Will use default icon if null.
362:                 * @param subcategories Subcategories to be shown under given category.
363:                 *        Category won't be expandable if null or empty array.
364:                 * @return a new category description
365:                 */
366:                public static Category create(String name, String displayName,
367:                        Image icon, Category... subcategories) {
368:                    return new Category(name, displayName, icon, subcategories);
369:                }
370:
371:                // Public methods ------------------------------------------------------
372:
373:                /** Gets programmatic name of given category.
374:                 * @return Programmatic name of the category
375:                 */
376:                public String getName() {
377:                    return this .name;
378:                }
379:
380:                /** Gets display name of given category.
381:                 * @return Display name of the category
382:                 */
383:                public String getDisplayName() {
384:                    return this .displayName;
385:                }
386:
387:                /** Gets icon of given category.
388:                 * @return Icon name of the category or null
389:                 */
390:                public Image getIcon() {
391:                    return this .icon;
392:                }
393:
394:                /** Gets subcategories of given category.
395:                 * @return Subcategories of the category or null
396:                 */
397:                public Category[] getSubcategories() {
398:                    return this .subcategories;
399:                }
400:
401:                /**
402:                 * Returns an error message for this category.
403:                 * @return the error message (could be null)
404:                 */
405:                public String getErrorMessage() {
406:                    return errorMessage;
407:                }
408:
409:                /**
410:                 * Returns whether this category is valid or not. See {@link
411:                 * ProjectCustomizer#createCustomizerDialog} for more details.
412:                 * @return whether this category is valid or not (true by default)
413:                 */
414:                public boolean isValid() {
415:                    return valid;
416:                }
417:
418:                /**
419:                 * Set a validity of this category. See {@link
420:                 * ProjectCustomizer#createCustomizerDialog} for more details.
421:                 * @param valid set whether this category is valid or not
422:                 */
423:                public void setValid(boolean valid) {
424:                    if (this .valid != valid) {
425:                        this .valid = valid;
426:                        Utilities.getCategoryChangeSupport(this )
427:                                .firePropertyChange(
428:                                        CategoryChangeSupport.VALID_PROPERTY,
429:                                        !valid, valid);
430:                    }
431:                }
432:
433:                /**
434:                 * Set an errror message for this category which than may be shown in a
435:                 * project customizer.
436:                 *
437:                 * @param message message for this category. To <em>reset</em> a
438:                 *        message usually <code>null</code> or an empty string is
439:                 *        passed. (similar to behaviour of {@link
440:                 *        javax.swing.text.JTextComponent#setText(String)})
441:                 */
442:                public void setErrorMessage(String message) {
443:                    if (message == null) {
444:                        message = "";
445:                    }
446:                    if (!message.equals(this .errorMessage)) {
447:                        String oldMessage = this .errorMessage;
448:                        this .errorMessage = message;
449:                        Utilities
450:                                .getCategoryChangeSupport(this )
451:                                .firePropertyChange(
452:                                        CategoryChangeSupport.ERROR_MESSAGE_PROPERTY,
453:                                        oldMessage, message);
454:                    }
455:                }
456:
457:                /**
458:                 * Set the action listener that will get notified when the changes in the customizer 
459:                 * are to be applied.
460:                 * @param okButtonListener ActionListener to notify 
461:                 * @since org.netbeans.modules.projectuiapi/1 1.20
462:                 */
463:                public void setOkButtonListener(ActionListener okButtonListener) {
464:                    okListener = okButtonListener;
465:                }
466:
467:                /**
468:                 * Returns the action listener associated with this category that gets notified
469:                 * when OK button is pressed on the customizer.
470:                 * @return instance of ActionListener or null if not set.
471:                 * @since org.netbeans.modules.projectuiapi/1 1.20
472:                 */
473:                public ActionListener getOkButtonListener() {
474:                    return okListener;
475:                }
476:
477:                /**
478:                 * Set the action listener that will get notified when the changes in the customizer 
479:                 * are to be applied. Listener is executed after OkButtonListener outside of AWT EventQueue. 
480:                 * Usually to be used to save modified files on disk.
481:                 * @param listener ActionListener to notify 
482:                 * @since org.netbeans.modules.projectuiapi/1 1.25
483:                 */
484:                public void setStoreListener(ActionListener listener) {
485:                    storeListener = listener;
486:                }
487:
488:                /**
489:                 * Returns the action listener that is executed outside of AWT EQ and is associated 
490:                 * with this category that gets notified when OK button is pressed on the customizer.
491:                 * @return instance of ActionListener or null if not set.
492:                 * @since org.netbeans.modules.projectuiapi/1 1.25
493:                 */
494:                public ActionListener getStoreListener() {
495:                    return storeListener;
496:                }
497:
498:            }
499:
500:            /*private*/static class DelegateCategoryProvider implements 
501:                    CategoryComponentProvider, CompositeCategoryProvider,
502:                    Lookup.Provider {
503:
504:                private final Lookup context;
505:                private final Map<ProjectCustomizer.Category, CompositeCategoryProvider> category2provider;
506:                private final DataFolder folder;
507:                private final CompositeCategoryProvider selfProvider;
508:
509:                public DelegateCategoryProvider(DataFolder folder,
510:                        Lookup context) {
511:                    this (
512:                            folder,
513:                            context,
514:                            new HashMap<ProjectCustomizer.Category, CompositeCategoryProvider>());
515:                }
516:
517:                private DelegateCategoryProvider(
518:                        DataFolder folder,
519:                        Lookup context,
520:                        Map<ProjectCustomizer.Category, CompositeCategoryProvider> cat2Provider) {
521:                    this (folder, context, cat2Provider, null);
522:                }
523:
524:                private DelegateCategoryProvider(
525:                        DataFolder folder,
526:                        Lookup context,
527:                        Map<ProjectCustomizer.Category, CompositeCategoryProvider> cat2Provider,
528:                        CompositeCategoryProvider sProv) {
529:                    this .context = context;
530:                    this .folder = folder;
531:                    category2provider = cat2Provider;
532:                    selfProvider = sProv;
533:                }
534:
535:                public JComponent create(ProjectCustomizer.Category category) {
536:                    CompositeCategoryProvider prov = category2provider
537:                            .get(category);
538:                    assert prov != null : "Category doesn't have a provider associated.";
539:                    return prov.createComponent(category, context);
540:                }
541:
542:                public ProjectCustomizer.Category[] getSubCategories() {
543:                    try {
544:                        return readCategories(folder);
545:                    } catch (IOException exc) {
546:                        Logger.getAnonymousLogger().log(Level.WARNING,
547:                                "Cannot construct Project UI panels", exc);
548:                        return new ProjectCustomizer.Category[0];
549:                    } catch (ClassNotFoundException ex) {
550:                        Logger.getAnonymousLogger().log(Level.WARNING,
551:                                "Cannot construct Project UI panels", ex);
552:                        return new ProjectCustomizer.Category[0];
553:                    }
554:                }
555:
556:                /*private*/ProjectCustomizer.Category[] readCategories(
557:                        DataFolder folder) throws IOException,
558:                        ClassNotFoundException {
559:                    List<ProjectCustomizer.Category> toRet = new ArrayList<ProjectCustomizer.Category>();
560:                    for (DataObject dob : folder.getChildren()) {
561:                        if (dob instanceof  DataFolder) {
562:                            CompositeCategoryProvider sProvider = null;
563:                            DataObject subDobs[] = ((DataFolder) dob)
564:                                    .getChildren();
565:                            for (DataObject subDob : subDobs) {
566:                                if (subDob.getName().equals("Self")) { // NOI18N
567:                                    InstanceCookie cookie = subDob
568:                                            .getCookie(InstanceCookie.class);
569:                                    if (cookie != null
570:                                            && CompositeCategoryProvider.class
571:                                                    .isAssignableFrom(cookie
572:                                                            .instanceClass())) {
573:                                        sProvider = (CompositeCategoryProvider) cookie
574:                                                .instanceCreate();
575:                                    }
576:                                }
577:                            }
578:                            CompositeCategoryProvider prov = null;
579:                            if (sProvider != null) {
580:                                prov = new DelegateCategoryProvider(
581:                                        (DataFolder) dob, context,
582:                                        category2provider, sProvider);
583:                            } else {
584:                                prov = new DelegateCategoryProvider(
585:                                        (DataFolder) dob, context,
586:                                        category2provider);
587:                            }
588:                            ProjectCustomizer.Category cat = prov
589:                                    .createCategory(context);
590:                            toRet.add(cat);
591:                            category2provider.put(cat, prov);
592:                        }
593:                        if (!dob.getName().equals("Self")) { // NOI18N
594:                            InstanceCookie cook = dob
595:                                    .getCookie(InstanceCookie.class);
596:                            if (cook != null
597:                                    && CompositeCategoryProvider.class
598:                                            .isAssignableFrom(cook
599:                                                    .instanceClass())) {
600:                                CompositeCategoryProvider provider = (CompositeCategoryProvider) cook
601:                                        .instanceCreate();
602:                                ProjectCustomizer.Category cat = provider
603:                                        .createCategory(context);
604:                                if (cat != null) {
605:                                    toRet.add(cat);
606:                                    category2provider.put(cat, provider);
607:                                    includeSubcats(cat.getSubcategories(),
608:                                            provider);
609:                                }
610:                            }
611:                        }
612:                    }
613:                    return toRet.toArray(new ProjectCustomizer.Category[toRet
614:                            .size()]);
615:                }
616:
617:                private void includeSubcats(ProjectCustomizer.Category[] cats,
618:                        ProjectCustomizer.CompositeCategoryProvider provider) {
619:                    if (cats != null) {
620:                        for (ProjectCustomizer.Category cat : cats) {
621:                            category2provider.put(cat, provider);
622:                            includeSubcats(cat.getSubcategories(), provider);
623:                        }
624:                    }
625:                }
626:
627:                /**
628:                 * provides category for folder..
629:                 */
630:                public ProjectCustomizer.Category createCategory(Lookup context) {
631:                    FileObject fo = folder.getPrimaryFile();
632:                    String dn = fo.getNameExt();
633:                    try {
634:                        dn = fo.getFileSystem().getStatus().annotateName(
635:                                fo.getNameExt(), Collections.singleton(fo));
636:                    } catch (FileStateInvalidException ex) {
637:                        Logger.getAnonymousLogger().log(
638:                                Level.WARNING,
639:                                "Cannot retrieve display name for folder "
640:                                        + fo.getPath(), ex);
641:                    }
642:                    return ProjectCustomizer.Category.create(folder.getName(),
643:                            dn, null, getSubCategories());
644:                }
645:
646:                /**
647:                 * provides component for folder category
648:                 */
649:                public JComponent createComponent(
650:                        ProjectCustomizer.Category category, Lookup context) {
651:                    if (selfProvider != null) {
652:                        return selfProvider.createComponent(category, context);
653:                    }
654:                    return new JPanel();
655:                }
656:
657:                //#97998 related
658:                public Lookup getLookup() {
659:                    return context;
660:                }
661:            }
662:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.