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;
043:
044: import java.awt.Component;
045: import java.awt.Window;
046: import java.awt.event.WindowAdapter;
047: import java.awt.event.WindowEvent;
048: import javax.swing.Action;
049:
050: import org.openide.nodes.*;
051: import org.openide.cookies.*;
052: import org.openide.actions.*;
053: import org.openide.util.actions.SystemAction;
054: import org.openide.loaders.DataObject;
055:
056: /**
057: * A common superclass for nodes used in Form Editor.
058: *
059: * @author Tomas Pavek
060: */
061:
062: public class FormNode extends AbstractNode implements FormCookie {
063:
064: private FormModel formModel;
065:
066: protected Action[] actions;
067:
068: protected FormNode(Children children, FormModel formModel) {
069: super (children);
070: this .formModel = formModel;
071: getCookieSet().add(this );
072: }
073:
074: // FormCookie implementation
075: public final FormModel getFormModel() {
076: return formModel;
077: }
078:
079: // FormCookie implementation
080: public final Node getOriginalNode() {
081: return this ;
082: }
083:
084: @Override
085: public <T extends Node.Cookie> T getCookie(Class<T> type) {
086: T cookie = super .getCookie(type);
087: if (cookie == null
088: && (DataObject.class.isAssignableFrom(type)
089: || SaveCookie.class.isAssignableFrom(type)
090: || CloseCookie.class.isAssignableFrom(type) || PrintCookie.class
091: .isAssignableFrom(type))) {
092: FormDataObject fdo = FormEditor
093: .getFormDataObject(formModel);
094: if (fdo != null)
095: cookie = fdo.getCookie(type);
096: }
097: return cookie;
098: }
099:
100: // because delegating cookies to FormDataObject we have a bit complicated
101: // way of updating cookies on node - need fire a change on nodes explicitly
102: void updateCookies() {
103: super .fireCookieChange();
104: }
105:
106: @Override
107: public javax.swing.Action[] getActions(boolean context) {
108: if (actions == null) {
109: actions = new Action[] { SystemAction
110: .get(PropertiesAction.class) };
111: }
112: return actions;
113: }
114:
115: @Override
116: public Component getCustomizer() {
117: Component customizer = createCustomizer();
118: if (customizer instanceof Window) {
119: // register the customizer window (probably a dialog) to be closed
120: // automatically when the form is closed
121: FormEditor formEditor = FormEditor.getFormEditor(formModel);
122: if (formEditor != null) {
123: Window customizerWindow = (Window) customizer;
124: formEditor.registerFloatingWindow(customizerWindow);
125: // attach a listener to unregister the window when it is closed
126: customizerWindow.addWindowListener(new WindowAdapter() {
127: @Override
128: public void windowClosing(WindowEvent e) {
129: if (e.getSource() instanceof Window) {
130: Window window = (Window) e.getSource();
131: FormEditor formEditor = FormEditor
132: .getFormEditor(formModel);
133: if (formEditor != null)
134: formEditor
135: .unregisterFloatingWindow(window);
136: window.removeWindowListener(this );
137: }
138: }
139: });
140: }
141: }
142: return customizer;
143: }
144:
145: // to be implemented in FormNode descendants (instead of getCustomizer)
146: protected Component createCustomizer() {
147: return null;
148: }
149:
150: /** Provides access for firing property changes
151: *
152: * @param name property name
153: * @param oldValue old value of the property
154: * @param newValue new value of the property
155: */
156: public void firePropertyChangeHelper(String name, Object oldValue,
157: Object newValue) {
158: super .firePropertyChange(name, oldValue, newValue);
159: }
160:
161: // ----------
162: // automatic children updates
163:
164: void updateChildren() {
165: Children children = getChildren();
166: if (children instanceof FormNodeChildren)
167: ((FormNodeChildren) children).updateKeys();
168: }
169:
170: // Special children class - to be implemented in FormNode descendants (if
171: // they know their set of children nodes and can update them).
172: protected abstract static class FormNodeChildren extends
173: Children.Keys<Object> {
174: protected void updateKeys() {
175: }
176: }
177:
178: // ----------
179: // Persistence hacks - for the case the node is selected in some
180: // (standalone) properties window when IDE exits. We don't restore the
181: // original node after IDE restarts (would require to load the form), but
182: // provide a fake node which destroys itself immediately - closing the
183: // properties window. [Would be nice to find some better solution...]
184:
185: @Override
186: public Node.Handle getHandle() {
187: return new Handle();
188: }
189:
190: static class Handle implements Node.Handle {
191: static final long serialVersionUID = 1;
192:
193: public Node getNode() throws java.io.IOException {
194: return new ClosingNode();
195: }
196: }
197:
198: static class ClosingNode extends AbstractNode implements Runnable {
199: ClosingNode() {
200: super (Children.LEAF);
201: }
202:
203: @Override
204: public String getName() {
205: java.awt.EventQueue.invokeLater(this );
206: return super .getName();
207: }
208:
209: @Override
210: public Node.PropertySet[] getPropertySets() {
211: java.awt.EventQueue.invokeLater(this );
212: return super .getPropertySets();
213: }
214:
215: public void run() {
216: this.fireNodeDestroyed();
217: }
218: }
219: }
|