Lines 16-21
Link Here
|
16 |
import java.awt.Dialog; |
16 |
import java.awt.Dialog; |
17 |
import java.awt.Image; |
17 |
import java.awt.Image; |
18 |
import java.awt.event.ActionListener; |
18 |
import java.awt.event.ActionListener; |
|
|
19 |
import java.io.IOException; |
20 |
import java.util.ArrayList; |
21 |
import java.util.Collections; |
22 |
import java.util.HashMap; |
23 |
import java.util.List; |
24 |
import java.util.logging.Level; |
25 |
import java.util.logging.Logger; |
19 |
import javax.swing.JComponent; |
26 |
import javax.swing.JComponent; |
20 |
import javax.swing.JPanel; |
27 |
import javax.swing.JPanel; |
21 |
|
28 |
|
Lines 26-32
Link Here
|
26 |
import org.netbeans.modules.project.uiapi.CustomizerPane; |
33 |
import org.netbeans.modules.project.uiapi.CustomizerPane; |
27 |
import org.netbeans.modules.project.uiapi.Utilities; |
34 |
import org.netbeans.modules.project.uiapi.Utilities; |
28 |
import org.netbeans.spi.project.ui.support.ProjectCustomizer.Category; |
35 |
import org.netbeans.spi.project.ui.support.ProjectCustomizer.Category; |
|
|
36 |
import org.openide.cookies.InstanceCookie; |
37 |
import org.openide.filesystems.FileObject; |
38 |
import org.openide.filesystems.FileStateInvalidException; |
39 |
import org.openide.filesystems.Repository; |
40 |
import org.openide.loaders.DataFolder; |
41 |
import org.openide.loaders.DataObject; |
29 |
import org.openide.util.HelpCtx; |
42 |
import org.openide.util.HelpCtx; |
|
|
43 |
import org.openide.util.Lookup; |
30 |
|
44 |
|
31 |
/** Support for creating dialogs which can be used as project |
45 |
/** Support for creating dialogs which can be used as project |
32 |
* customizers. The dialog may display multiple panels or categories. |
46 |
* customizers. The dialog may display multiple panels or categories. |
Lines 76-81
Link Here
|
76 |
Dialog dialog = CustomizerDialog.createDialog( okOptionListener, innerPane, helpCtx, categories ); |
90 |
Dialog dialog = CustomizerDialog.createDialog( okOptionListener, innerPane, helpCtx, categories ); |
77 |
return dialog; |
91 |
return dialog; |
78 |
} |
92 |
} |
|
|
93 |
|
94 |
/** |
95 |
* Creates standard customizer dialog that can be used for implementation of |
96 |
* {@link org.netbeans.spi.project.ui.CustomizerProvider} based on content of a folder in Layers. |
97 |
* Use this method when you want to allow composition and 3rd party additions to your customizer UI. |
98 |
* You don't need to call <code>pack()</code> method on the dialog. The resulting dialog will |
99 |
* be non-modal. <br> |
100 |
* Call <code>show()</code> on the dialog to make it visible. If you want the dialog to be |
101 |
* closed after user presses the "OK" button you have to call hide() and dispose() on it. |
102 |
* (Usually in the <code>actionPerformed(...)</code> method of the listener |
103 |
* you provided as a parameter. In case of the click on the "Cancel" button |
104 |
* the dialog will be closed automatically. |
105 |
* @param folderPath the path in the System Filesystem that is used as root for panel composition. |
106 |
* The content of the folder is assummed to be {@link org.netbeans.spi.project.ui.support.ProjectCustomizer.CompositeCategoryProvider} instances |
107 |
* @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 |
108 |
* @param preselectedCategory name of one of the supplied categories or null. |
109 |
* Category with given name will be selected. If <code>null</code> |
110 |
* or if the category of given name does not exist the first category will |
111 |
* be selected. |
112 |
* @param okOptionListener listener which will be notified when the user presses |
113 |
* the OK button. |
114 |
* @param helpCtx Help context for the dialog, which will be used when the |
115 |
* panels in the customizer do not specify their own help context. |
116 |
* @return standard project customizer dialog. |
117 |
*/ |
118 |
public static Dialog createCustomizerDialog( String folderPath, |
119 |
Lookup context, |
120 |
String preselectedCategory, |
121 |
ActionListener okOptionListener, |
122 |
HelpCtx helpCtx) { |
123 |
FileObject root = Repository.getDefault().getDefaultFileSystem().findResource(folderPath); |
124 |
if (root == null) { |
125 |
throw new IllegalArgumentException("The designated path " + folderPath + " doesn't exist. Cannot create customizer."); |
126 |
} |
127 |
DataFolder def = DataFolder.findFolder(root); |
128 |
assert def != null : "Cannot find DataFolder for " + folderPath; |
129 |
DelegateCategoryProvider prov = new DelegateCategoryProvider(def, context); |
130 |
return createCustomizerDialog(prov.getSubCategories(), |
131 |
prov, |
132 |
preselectedCategory, okOptionListener, helpCtx); |
133 |
|
134 |
} |
79 |
|
135 |
|
80 |
/** Creates standard innerPane for customizer dialog. |
136 |
/** Creates standard innerPane for customizer dialog. |
81 |
*/ |
137 |
*/ |
Lines 112-117
Link Here
|
112 |
} |
168 |
} |
113 |
} |
169 |
} |
114 |
} |
170 |
} |
|
|
171 |
|
115 |
|
172 |
|
116 |
/** Provides components for categories. |
173 |
/** Provides components for categories. |
117 |
*/ |
174 |
*/ |
Lines 124-129
Link Here
|
124 |
JComponent create( Category category ); |
181 |
JComponent create( Category category ); |
125 |
|
182 |
|
126 |
} |
183 |
} |
|
|
184 |
|
185 |
/** |
186 |
* Interface for creation of Customizer categories and their respective UI panels. |
187 |
* Implementations are to be registered in System FileSystem via module layers. Used by the |
188 |
* {@link org.netbeans.spi.project.ui.support.ProjectCustomizer#createCustomizerDialog(String,Lookup,String,ActionListener,HelpCtx)} |
189 |
*/ |
190 |
public static interface CompositeCategoryProvider { |
191 |
|
192 |
/** |
193 |
* create the Category instance for the given project customizer context. |
194 |
*/ |
195 |
Category createCategory( Lookup context ); |
196 |
|
197 |
/** |
198 |
* create the UI component for given category and context. |
199 |
*/ |
200 |
JComponent createComponent (Category category, Lookup context ); |
201 |
} |
127 |
|
202 |
|
128 |
/** Describes category of properties to be customized by given component |
203 |
/** Describes category of properties to be customized by given component |
129 |
*/ |
204 |
*/ |
Lines 246-250
Link Here
|
246 |
} |
321 |
} |
247 |
|
322 |
|
248 |
} |
323 |
} |
249 |
|
324 |
|
|
|
325 |
private static class DelegateCategoryProvider implements CategoryComponentProvider, CompositeCategoryProvider { |
326 |
private Lookup context; |
327 |
private HashMap category2provider; |
328 |
private DataFolder folder; |
329 |
public DelegateCategoryProvider(DataFolder folder, Lookup context) { |
330 |
this(folder, context, new HashMap()); |
331 |
} |
332 |
|
333 |
private DelegateCategoryProvider(DataFolder folder, Lookup context, HashMap cat2Provider) { |
334 |
this.context = context; |
335 |
this.folder = folder; |
336 |
category2provider = cat2Provider; |
337 |
} |
338 |
|
339 |
public JComponent create(ProjectCustomizer.Category category) { |
340 |
CompositeCategoryProvider prov = (CompositeCategoryProvider)category2provider.get(category); |
341 |
assert prov != null : "Category doesn't have a provider associated."; |
342 |
return prov.createComponent(category, context); |
343 |
} |
344 |
|
345 |
public ProjectCustomizer.Category[] getSubCategories() { |
346 |
try { |
347 |
return readCategories(folder); |
348 |
} catch (IOException exc) { |
349 |
Logger.getAnonymousLogger().log(Level.WARNING, "Cannot construct Project UI panels", exc); |
350 |
return new ProjectCustomizer.Category[0]; |
351 |
} catch (ClassNotFoundException ex) { |
352 |
Logger.getAnonymousLogger().log(Level.WARNING, "Cannot construct Project UI panels", ex); |
353 |
return new ProjectCustomizer.Category[0]; |
354 |
} |
355 |
} |
356 |
|
357 |
|
358 |
private ProjectCustomizer.Category[] readCategories(DataFolder folder) throws IOException, ClassNotFoundException { |
359 |
List toRet = new ArrayList(); |
360 |
DataObject[] dobjs = folder.getChildren(); |
361 |
for (int i = 0; i < dobjs.length; i++) { |
362 |
if (dobjs[i] instanceof DataFolder) { |
363 |
CompositeCategoryProvider prov = new DelegateCategoryProvider((DataFolder)dobjs[i], context, category2provider); |
364 |
ProjectCustomizer.Category cat = prov.createCategory(context); |
365 |
toRet.add(cat); |
366 |
category2provider.put(cat, prov); |
367 |
} |
368 |
InstanceCookie cook = (InstanceCookie)dobjs[i].getCookie(InstanceCookie.class); |
369 |
if (cook != null && CompositeCategoryProvider.class.isAssignableFrom(cook.instanceClass())) { |
370 |
CompositeCategoryProvider provider = (CompositeCategoryProvider)cook.instanceCreate(); |
371 |
ProjectCustomizer.Category cat = provider.createCategory(context); |
372 |
if (cat != null) { |
373 |
toRet.add(cat); |
374 |
category2provider.put(cat, provider); |
375 |
} |
376 |
} |
377 |
} |
378 |
return (ProjectCustomizer.Category[])toRet.toArray(new ProjectCustomizer.Category[toRet.size()]); |
379 |
} |
380 |
|
381 |
/** |
382 |
* provides category for folder.. |
383 |
*/ |
384 |
public ProjectCustomizer.Category createCategory(Lookup context) { |
385 |
FileObject fo = folder.getPrimaryFile(); |
386 |
String dn = fo.getNameExt(); |
387 |
try { |
388 |
dn = fo.getFileSystem().getStatus().annotateName(fo.getNameExt(), Collections.singleton(fo)); |
389 |
} catch (FileStateInvalidException ex) { |
390 |
Logger.getAnonymousLogger().log(Level.WARNING, "Cannot retrieve display name for folder " + fo.getPath(), ex); |
391 |
} |
392 |
return ProjectCustomizer.Category.create(folder.getName(), dn, null, getSubCategories()); |
393 |
} |
394 |
|
395 |
/** |
396 |
* provides component for folder category |
397 |
*/ |
398 |
public JComponent createComponent(ProjectCustomizer.Category category, Lookup context) { |
399 |
return new JPanel(); |
400 |
} |
401 |
} |
250 |
} |
402 |
} |