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: package org.netbeans.modules.vmd.api.model.presenters;
042:
043: import org.netbeans.modules.vmd.api.model.*;
044: import org.openide.util.Utilities;
045:
046: import java.awt.*;
047:
048: /**
049: * The info presenter is used for resolving display name, icon and editable name.
050: * The values are resolved by Resolver and cached by the presenter.
051: * When a document/component is changed according to the specified DesignEventFilter, the cache is cleared.
052: *
053: * @author David Kaspar
054: */
055: public final class InfoPresenter extends DynamicPresenter {
056:
057: /**
058: * The name type.
059: */
060: public enum NameType {
061: PRIMARY, SECONDARY, TERTIARY
062: }
063:
064: /**
065: * The icon type.
066: */
067: public enum IconType {
068: COLOR_16x16, COLOR_32x32, COLOR_48x48, COLOR_64x64
069: }
070:
071: /**
072: * Creates an info presenter for a specified resolver.
073: * @param resolver the resolver of the info presenter
074: * @return the info presenter
075: */
076: public static InfoPresenter create(Resolver resolver) {
077: return new InfoPresenter(resolver);
078: }
079:
080: private Resolver resolver;
081:
082: private String cachedPrimary;
083: private String cachedSecondary;
084: private String cachedTertiary;
085:
086: private Image cached16;
087: private Image cached32;
088: private Image cached48;
089: private Image cached64;
090:
091: private InfoPresenter(Resolver resolver) {
092: this .resolver = resolver;
093: }
094:
095: protected void notifyAttached(DesignComponent component) {
096: }
097:
098: protected void notifyDetached(DesignComponent component) {
099: }
100:
101: protected DesignEventFilter getEventFilter() {
102: return resolver.getEventFilter(getComponent());
103: }
104:
105: protected void designChanged(DesignEvent event) {
106: cachedPrimary = cachedSecondary = cachedTertiary = null;
107: cached16 = cached32 = cached48 = cached64 = null;
108: firePresenterChanged();
109: }
110:
111: protected void presenterChanged(PresenterEvent event) {
112: }
113:
114: /**
115: * Returns a display name for a specific component and name type.
116: * @param nameType the name type
117: * @return the display name
118: */
119: public String getDisplayName(NameType nameType) {
120: switch (nameType) {
121: case PRIMARY:
122: if (cachedPrimary == null)
123: cachedPrimary = resolver.getDisplayName(getComponent(),
124: nameType);
125: return cachedPrimary;
126: case SECONDARY:
127: if (cachedSecondary == null)
128: cachedSecondary = resolver.getDisplayName(
129: getComponent(), nameType);
130: return cachedSecondary;
131: case TERTIARY:
132: if (cachedTertiary == null)
133: cachedTertiary = resolver.getDisplayName(
134: getComponent(), nameType);
135: return cachedTertiary;
136: default:
137: throw new IllegalStateException();
138: }
139: }
140:
141: /**
142: * Returns whether a name is editable.
143: * @return true, if editable
144: */
145: public boolean isEditable() {
146: return resolver.isEditable(getComponent());
147: }
148:
149: /**
150: * Returns an initial name usually used in an in-place editor.
151: * @return the initial name; if null, then the in-place editor is not allowed
152: */
153: public String getEditableName() {
154: return resolver.getEditableName(getComponent());
155: }
156:
157: /**
158: * Sets a new name usually entered by an in-place editor.
159: * @param enteredName the edited name
160: */
161: public void setEditableName(String enteredName) {
162: resolver.setEditableName(getComponent(), enteredName);
163: }
164:
165: /**
166: * Returns an icon.
167: * @param iconType the icon type
168: * @return the icon
169: */
170: public Image getIcon(IconType iconType) {
171: switch (iconType) {
172: case COLOR_16x16:
173: if (cached16 == null)
174: cached16 = resolver.getIcon(getComponent(), iconType);
175: return cached16;
176: case COLOR_32x32:
177: if (cached32 == null)
178: cached32 = resolver.getIcon(getComponent(), iconType);
179: return cached32;
180: case COLOR_48x48:
181: if (cached48 == null)
182: cached48 = resolver.getIcon(getComponent(), iconType);
183: return cached48;
184: case COLOR_64x64:
185: if (cached64 == null)
186: cached64 = resolver.getIcon(getComponent(), iconType);
187: return cached64;
188: default:
189: throw new IllegalStateException();
190: }
191: }
192:
193: public static InfoPresenter createStatic(final String displayName,
194: final String typeName, String iconResource) {
195: return createStatic(displayName, typeName, null, iconResource);
196: }
197:
198: public static InfoPresenter createStatic(final String displayName,
199: final String typeName, final String toolTip,
200: String iconResource) {
201: return createStatic(displayName, typeName, toolTip, Utilities
202: .loadImage(iconResource));
203: }
204:
205: public static InfoPresenter createStatic(final String displayName,
206: final String typeName, final String toolTip,
207: final Image icon) {
208: return new InfoPresenter(new Resolver() {
209: public DesignEventFilter getEventFilter(
210: DesignComponent component) {
211: return null;
212: }
213:
214: public String getDisplayName(DesignComponent component,
215: NameType nameType) {
216: switch (nameType) {
217: case PRIMARY:
218: return displayName;
219: case SECONDARY:
220: return typeName;
221: case TERTIARY:
222: return toolTip;
223: default:
224: throw Debug.illegalState();
225: }
226: }
227:
228: public boolean isEditable(DesignComponent component) {
229: return false;
230: }
231:
232: public String getEditableName(DesignComponent component) {
233: throw new IllegalStateException();
234: }
235:
236: public void setEditableName(DesignComponent component,
237: String enteredName) {
238: throw new IllegalStateException();
239: }
240:
241: public Image getIcon(DesignComponent component,
242: IconType iconType) {
243: return IconType.COLOR_16x16.equals(iconType) ? icon
244: : null;
245: }
246: });
247: }
248:
249: public static String getHtmlDisplayName(DesignComponent component) {
250: InfoPresenter presenter = component
251: .getPresenter(InfoPresenter.class);
252: if (presenter == null) {
253: Debug.warning("Missing InfoPresenter for: ", component); // NOI18N
254: return null;
255: }
256: String primary = presenter
257: .getDisplayName(InfoPresenter.NameType.PRIMARY);
258: String secondary = presenter
259: .getDisplayName(InfoPresenter.NameType.SECONDARY);
260: return secondary != null ? primary
261: + " <font color=\"#808080\">[" + secondary + "]"
262: : primary; // NOI18N
263: }
264:
265: public static String getDisplayName(DesignComponent component) {
266: InfoPresenter presenter = component
267: .getPresenter(InfoPresenter.class);
268: if (presenter == null) {
269: Debug.warning("Missing InfoPresenter for: ", component); // NOI18N
270: return null;
271: }
272: String primary = presenter
273: .getDisplayName(InfoPresenter.NameType.PRIMARY);
274: String secondary = presenter
275: .getDisplayName(InfoPresenter.NameType.SECONDARY);
276: return secondary != null ? primary + " [" + secondary + "]"
277: : primary; // NOI18N
278: }
279:
280: public static String getToolTip(DesignComponent component) {
281: InfoPresenter presenter = component
282: .getPresenter(InfoPresenter.class);
283: if (presenter == null) {
284: Debug.warning("Missing InfoPresenter for: ", component); // NOI18N
285: return null;
286: }
287: return getToolTip(presenter);
288: }
289:
290: public static String getToolTip(InfoPresenter presenter) {
291: String text = presenter.getDisplayName(NameType.TERTIARY);
292: if (text != null)
293: return text;
294: return presenter.getDisplayName(NameType.SECONDARY);
295: }
296:
297: public interface Resolver {
298:
299: /**
300: * Returns an event filter for a component.
301: * @param component the component
302: * @return the event filter used by a info presenter where the resolver is attached
303: */
304: DesignEventFilter getEventFilter(DesignComponent component);
305:
306: /**
307: * Returns a display name for a specific component and name type.
308: * @param component the component
309: * @param nameType the name type
310: * @return the display name
311: */
312: String getDisplayName(DesignComponent component,
313: InfoPresenter.NameType nameType);
314:
315: /**
316: * Returns whether a name is editable.
317: * @return true, if editable
318: */
319: boolean isEditable(DesignComponent component);
320:
321: /**
322: * Returns an initial name usually used in an in-place editor.
323: * @param component the component
324: * @return the initial name; if null, then the in-place editor is not allowed
325: */
326: String getEditableName(DesignComponent component);
327:
328: /**
329: * Sets a new name usually entered by an in-place editor.
330: * @param component the component
331: * @param enteredName the edited name
332: */
333: void setEditableName(DesignComponent component,
334: String enteredName);
335:
336: /**
337: * Returns an icon.
338: * @param component the component
339: * @param iconType the icon type
340: * @return the icon
341: */
342: Image getIcon(DesignComponent component, IconType iconType);
343:
344: }
345:
346: }
|