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.modules.form.palette;
043:
044: import java.beans.*;
045: import java.awt.Image;
046:
047: import org.openide.ErrorManager;
048: import org.openide.nodes.Node;
049:
050: import org.netbeans.modules.form.FormUtils;
051: import org.netbeans.modules.form.project.*;
052: import org.openide.filesystems.FileObject;
053:
054: /**
055: * PaletteItem holds important information about one component (item)
056: * in the palette.
057: *
058: * @author Tomas Pavek
059: */
060:
061: public final class PaletteItem implements Node.Cookie {
062: public static String TYPE_CHOOSE_BEAN = "chooseBean"; // NOI18N
063: private PaletteItemDataObject itemDataObject;
064:
065: // raw data (as read from the item file - to be resolved lazily)
066: ClassSource componentClassSource;
067: // Boolean isContainer_explicit;
068: String componentType_explicit;
069: Image icon;
070: private FileObject cpRepresentative;
071:
072: // resolved data (derived from the raw data)
073: private Class componentClass;
074: private Throwable lastError; // error occurred when loading component class
075: // private Boolean componentIsContainer;
076: private int componentType = -1;
077:
078: // type of component constants
079: private static final int LAYOUT = 1;
080: private static final int BORDER = 2;
081: private static final int VISUAL = 4; // bit flag
082: private static final int MENU = 8; // bit flag
083: private static final int TYPE_MASK = 15;
084:
085: // -------
086:
087: PaletteItem(PaletteItemDataObject dobj) {
088: itemDataObject = dobj;
089: }
090:
091: public PaletteItem(ClassSource componentClassSource,
092: Class componentClass) {
093: this .componentClassSource = componentClassSource;
094: this .componentClass = componentClass;
095: }
096:
097: public void setComponentClassSource(ClassSource cs) {
098: componentClass = null;
099: lastError = null;
100: componentType = -1;
101: componentClassSource = cs;
102: }
103:
104: void setComponentExplicitType(String type) {
105: componentType_explicit = type;
106: }
107:
108: /**
109: * Used by Choose Bean palette item where the user can fill in whatever
110: * class from the actual project classpath. Such a palette item will be
111: * used in the same project, so ClassSource is not really needed (it is
112: * normally used only for project output).
113: */
114: public void setClassFromCurrentProject(String className,
115: FileObject fileInProject) {
116: setComponentClassSource(new ClassSource(className));
117: cpRepresentative = fileInProject;
118: }
119:
120: // -------
121:
122: /** @return a node visually representing this palette item */
123: public Node getNode() {
124: return (itemDataObject == null) ? null : itemDataObject
125: .getNodeDelegate();
126: }
127:
128: /** @return a String identifying this palette item */
129: public String getId() {
130: return getComponentClassName();
131: }
132:
133: public String getComponentClassName() {
134: return componentClassSource.getClassName();
135: }
136:
137: public ClassSource getComponentClassSource() {
138: return componentClassSource;
139: }
140:
141: /** @return the class of the component represented by this pallete item.
142: * May return null - if class loading fails. */
143: public Class getComponentClass() {
144: if (componentClass == null && lastError == null)
145: componentClass = loadComponentClass();
146: return componentClass;
147: }
148:
149: /** @return the exception occurred when trying to resolve the component
150: * class of this pallette item */
151: public Throwable getError() {
152: return lastError;
153: }
154:
155: /** @return type of the component as String, e.g. "visual", "menu",
156: * "layout", border */
157: public String getExplicitComponentType() {
158: return componentType_explicit;
159: }
160:
161: /** @return whether the component of this palette item is a visual component
162: * (java.awt.Component subclass) */
163: public boolean isVisual() {
164: if (componentType == -1)
165: resolveComponentType();
166: return (componentType & VISUAL) != 0;
167: }
168:
169: /** @return whether the component of this palette item is a menu component */
170: public boolean isMenu() {
171: if (componentType == -1)
172: resolveComponentType();
173: return (componentType & MENU) != 0;
174: }
175:
176: /** @return whether the component of this palette item is a layout mamanger
177: * (java.awt.LayoutManager implementation) */
178: public boolean isLayout() {
179: if (componentType == -1)
180: resolveComponentType();
181: return (componentType & TYPE_MASK) == LAYOUT;
182: }
183:
184: /** @return whether the component of this palette item is a border
185: * (javax.swing.border.Border implementation) */
186: public boolean isBorder() {
187: if (componentType == -1)
188: resolveComponentType();
189: return (componentType & TYPE_MASK) == BORDER;
190: }
191:
192: // public boolean isContainer() {
193: // if (componentIsContainer == null) {
194: // if (isContainer_explicit != null)
195: // componentIsContainer = isContainer_explicit;
196: // else {
197: // Class compClass = getComponentClass();
198: // if (compClass != null
199: // && java.awt.Container.class.isAssignableFrom(compClass))
200: // {
201: // BeanDescriptor bd = getBeanDescriptor();
202: // componentIsContainer =
203: // bd != null && Boolean.FALSE.equals(bd.getValue("isContainer")) ? // NOI18N
204: // Boolean.FALSE : Boolean.TRUE;
205: // }
206: // else componentIsContainer = Boolean.FALSE;
207: // }
208: // }
209: // return componentIsContainer.booleanValue();
210: // }
211:
212: @Override
213: public String toString() {
214: return PaletteUtils.getItemComponentDescription(this );
215: }
216:
217: String getDisplayName() {
218: BeanDescriptor bd = getBeanDescriptor();
219: return bd != null ? bd.getDisplayName() : null;
220: }
221:
222: String getTooltip() {
223: BeanDescriptor bd = getBeanDescriptor();
224: return bd != null ? bd.getShortDescription() : null;
225: }
226:
227: public Image getIcon(int type) {
228: if (icon != null)
229: return icon;
230: BeanInfo bi = getBeanInfo();
231: return bi != null ? bi.getIcon(type) : null;
232: }
233:
234: public void setIcon(Image icon) {
235: this .icon = icon;
236: }
237:
238: void reset() {
239: componentClass = null;
240: lastError = null;
241: // componentIsContainer = null;
242: componentType = -1;
243:
244: itemDataObject.displayName = null;
245: itemDataObject.tooltip = null;
246: itemDataObject.icon16 = null;
247: itemDataObject.icon32 = null;
248: }
249:
250: // -------
251:
252: private Class loadComponentClass() {
253: try {
254: return FormUtils.loadSystemClass(getComponentClassName());
255: } catch (ClassNotFoundException cnfex) {
256: }
257:
258: try {
259: if (cpRepresentative != null) {
260: return ClassPathUtils.loadClass(
261: getComponentClassSource().getClassName(),
262: cpRepresentative);
263: } else {
264: return ClassPathUtils
265: .loadClass(getComponentClassSource());
266: }
267: } catch (Exception ex) {
268: ErrorManager.getDefault().notify(
269: ErrorManager.INFORMATIONAL, ex);
270: lastError = ex;
271: } catch (LinkageError ex) {
272: ErrorManager.getDefault().notify(
273: ErrorManager.INFORMATIONAL, ex);
274: lastError = ex;
275: }
276: return null;
277: }
278:
279: private BeanInfo getBeanInfo() {
280: Class compClass = getComponentClass();
281: if (compClass != null) {
282: try {
283: return FormUtils.getBeanInfo(compClass);
284: } catch (Exception ex) {
285: } // ignore failure
286: //catch (LinkageError ex) {}
287: catch (Error er) {
288: } // Issue 74002
289: }
290: return null;
291: }
292:
293: private BeanDescriptor getBeanDescriptor() {
294: Class compClass = getComponentClass();
295: if (compClass != null) {
296: try {
297: return FormUtils.getBeanInfo(compClass)
298: .getBeanDescriptor();
299: } catch (Exception ex) {
300: } // ignore failure
301: //catch (LinkageError ex) {}
302: catch (Error er) {
303: } // Issue 74002
304: }
305: return null;
306: }
307:
308: private void resolveComponentType() {
309: if (componentType_explicit == null) {
310: componentType = 0;
311:
312: Class compClass = getComponentClass();
313: if (compClass == null)
314: return;
315:
316: if (java.awt.LayoutManager.class
317: .isAssignableFrom(compClass)) {
318: // PENDING LayoutSupportDelegate - should have special entry in pallette item file?
319: componentType = LAYOUT;
320: return;
321: }
322:
323: if (javax.swing.border.Border.class
324: .isAssignableFrom(compClass)) {
325: componentType = BORDER;
326: return;
327: }
328:
329: if (java.awt.Component.class.isAssignableFrom(compClass))
330: componentType |= VISUAL;
331:
332: if (java.awt.MenuComponent.class
333: .isAssignableFrom(compClass)
334: || javax.swing.JMenuItem.class
335: .isAssignableFrom(compClass)
336: || javax.swing.JMenuBar.class
337: .isAssignableFrom(compClass)
338: || javax.swing.JPopupMenu.class
339: .isAssignableFrom(compClass))
340: componentType |= MENU;
341: } else if ("visual".equalsIgnoreCase(componentType_explicit)) // NOI18N
342: componentType = VISUAL;
343: else if ("layout".equalsIgnoreCase(componentType_explicit)) // NOI18N
344: componentType = LAYOUT;
345: else if ("border".equalsIgnoreCase(componentType_explicit)) // NOI18N
346: componentType = BORDER;
347: else if ("menu".equalsIgnoreCase(componentType_explicit)) // NOI18N
348: componentType = MENU | VISUAL;
349: else
350: componentType = 0;
351: }
352: }
|