0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.modules.form;
0043:
0044: import com.sun.source.tree.AnnotationTree;
0045: import com.sun.source.tree.ClassTree;
0046: import com.sun.source.tree.CompilationUnitTree;
0047: import com.sun.source.tree.MethodTree;
0048: import com.sun.source.tree.ModifiersTree;
0049: import com.sun.source.tree.Tree;
0050: import com.sun.source.util.SourcePositions;
0051: import java.awt.Cursor;
0052: import java.awt.EventQueue;
0053: import java.beans.*;
0054: import java.io.IOException;
0055: import java.util.*;
0056: import java.util.logging.Level;
0057: import java.util.logging.Logger;
0058: import java.util.prefs.PreferenceChangeEvent;
0059: import java.util.prefs.PreferenceChangeListener;
0060: import javax.swing.*;
0061: import javax.swing.text.Document;
0062: import org.netbeans.api.project.libraries.Library;
0063: import org.netbeans.api.project.libraries.LibraryManager;
0064: import org.netbeans.editor.EditorUI;
0065: import org.netbeans.editor.ext.ExtCaret;
0066: import javax.swing.text.BadLocationException;
0067: import org.netbeans.api.editor.guards.SimpleSection;
0068: import org.netbeans.api.java.classpath.ClassPath;
0069: import org.netbeans.api.java.source.CancellableTask;
0070: import org.netbeans.api.java.source.JavaSource;
0071: import org.netbeans.api.java.source.WorkingCopy;
0072: import org.netbeans.modules.form.actions.EditContainerAction;
0073: import org.netbeans.modules.form.actions.EditFormAction;
0074: import org.netbeans.modules.form.assistant.AssistantModel;
0075: import org.netbeans.modules.form.palette.PaletteUtils;
0076: import org.netbeans.spi.palette.PaletteController;
0077:
0078: import org.openide.*;
0079: import org.openide.awt.UndoRedo;
0080: import org.openide.awt.StatusDisplayer;
0081: import org.openide.filesystems.FileObject;
0082: import org.openide.loaders.DataObject;
0083: import org.openide.nodes.Node;
0084: import org.openide.util.Mutex;
0085: import org.openide.windows.*;
0086: import org.openide.util.actions.SystemAction;
0087:
0088: import org.netbeans.modules.form.project.ClassSource;
0089: import org.netbeans.modules.form.project.ClassPathUtils;
0090:
0091: /**
0092: * Form editor.
0093: *
0094: * @author Jan Stola
0095: */
0096: public class FormEditor {
0097: static final int LOADING = 1;
0098: static final int SAVING = 2;
0099:
0100: /** The FormModel instance holding the form itself */
0101: private FormModel formModel;
0102:
0103: /** The root node of form hierarchy presented in Component Inspector */
0104: private FormRootNode formRootNode;
0105:
0106: /** The designer component - the last active designer of the form
0107: * (there can be more clones). May happen to be null if the active designer
0108: * was closed and no other designer of given form was activated since then. */
0109: private FormDesigner formDesigner;
0110:
0111: /** The code generator for the form */
0112: private CodeGenerator codeGenerator;
0113:
0114: /** The FormJavaSource for the form */
0115: private FormJavaSource formJavaSource;
0116:
0117: /** ResourceSupport instance for the form */
0118: private ResourceSupport resourceSupport;
0119:
0120: /** Instance of binding support for the form.*/
0121: private BindingDesignSupport bindingSupport;
0122:
0123: /** List of exceptions occurred during the last persistence operation */
0124: private List<Throwable> persistenceErrors;
0125:
0126: /** Persistence manager responsible for saving the form */
0127: private PersistenceManager persistenceManager;
0128:
0129: /** An indicator whether the form has been loaded (from the .form file) */
0130: private boolean formLoaded = false;
0131:
0132: /** Table of opened FormModel instances (FormModel to FormEditor map) */
0133: private static Map<FormModel, FormEditor> openForms = new Hashtable<FormModel, FormEditor>();
0134:
0135: /* Maps form model to assistant model. */
0136: private static Map<FormModel, AssistantModel> formModelToAssistant = new WeakHashMap<FormModel, AssistantModel>();
0137:
0138: /** List of floating windows - must be closed when the form is closed. */
0139: private List<java.awt.Window> floatingWindows;
0140:
0141: /** The DataObject of the form */
0142: private FormDataObject formDataObject;
0143: private PropertyChangeListener dataObjectListener;
0144: private static PreferenceChangeListener settingsListener;
0145: private PropertyChangeListener paletteListener;
0146:
0147: // listeners
0148: private FormModelListener formListener;
0149:
0150: /** List of actions that are tried when a component is double-clicked. */
0151: private List<Action> defaultActions;
0152:
0153: /** Indicates that a task has been posted to ask the user about format
0154: * upgrade - not to show the confirmation dialog multiple times.
0155: */
0156: private boolean upgradeCheckPosted;
0157:
0158: // -----
0159:
0160: FormEditor(FormDataObject formDataObject) {
0161: this .formDataObject = formDataObject;
0162: }
0163:
0164: /** @return root node representing the form (in pair with the class node) */
0165: public final FormNode getFormRootNode() {
0166: return formRootNode;
0167: }
0168:
0169: public final FormNode getOthersContainerNode() {
0170: FormNode othersNode = formRootNode.getOthersNode();
0171: return othersNode != null ? othersNode : formRootNode;
0172: }
0173:
0174: /** @return the FormModel of this form, null if the form is not loaded */
0175: public final FormModel getFormModel() {
0176: return formModel;
0177: }
0178:
0179: public final FormDataObject getFormDataObject() {
0180: return formDataObject;
0181: }
0182:
0183: private final FormJavaSource getFormJavaSource() {
0184: return formJavaSource;
0185: }
0186:
0187: CodeGenerator getCodeGenerator() {
0188: if (!formLoaded)
0189: return null;
0190: if (codeGenerator == null)
0191: codeGenerator = new JavaCodeGenerator();
0192: return codeGenerator;
0193: }
0194:
0195: ResourceSupport getResourceSupport() {
0196: if (resourceSupport == null && formModel != null) {
0197: resourceSupport = new ResourceSupport(formModel);
0198: resourceSupport.init();
0199: }
0200: return resourceSupport;
0201: }
0202:
0203: BindingDesignSupport getBindingSupport() {
0204: if (bindingSupport == null && formModel != null) {
0205: bindingSupport = new BindingDesignSupport(formModel);
0206: }
0207: return bindingSupport;
0208: }
0209:
0210: boolean isFormLoaded() {
0211: return formLoaded;
0212: }
0213:
0214: /** This methods loads the form, reports errors, creates the FormDesigner */
0215: void loadFormDesigner() {
0216: JFrame mainWin = (JFrame) WindowManager.getDefault()
0217: .getMainWindow();
0218:
0219: // set status text "Opening Form: ..."
0220: StatusDisplayer.getDefault().setStatusText(
0221: FormUtils.getFormattedBundleString("FMT_OpeningForm", // NOI18N
0222: new Object[] { formDataObject.getFormFile()
0223: .getName() }));
0224: javax.swing.RepaintManager.currentManager(mainWin)
0225: .paintDirtyRegions();
0226:
0227: // set wait cursor [is not very reliable, but...]
0228: mainWin.getGlassPane().setCursor(
0229: Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
0230: mainWin.getGlassPane().setVisible(true);
0231:
0232: preCreationUpdate();
0233:
0234: // load form data and report errors
0235: try {
0236: loadFormData();
0237: } catch (PersistenceException ex) { // a fatal loading error happened
0238: logPersistenceError(ex, 0);
0239: if (!formLoaded) { // loading failed - don't keep empty designer opened
0240: java.awt.EventQueue.invokeLater(new Runnable() {
0241: public void run() {
0242: getFormDataObject().getFormEditorSupport()
0243: .selectJavaEditor();
0244: }
0245: });
0246: }
0247: }
0248:
0249: // clear status text
0250: StatusDisplayer.getDefault().setStatusText(""); // NOI18N
0251:
0252: // clear wait cursor
0253: mainWin.getGlassPane().setVisible(false);
0254: mainWin.getGlassPane().setCursor(null);
0255:
0256: // report errors during loading
0257: reportErrors(LOADING);
0258:
0259: // may do additional setup for just created form
0260: postCreationUpdate();
0261: }
0262:
0263: boolean loadForm() {
0264: if (formLoaded)
0265: return true;
0266:
0267: if (java.awt.EventQueue.isDispatchThread()) {
0268: try {
0269: loadFormData();
0270: } catch (PersistenceException ex) {
0271: logPersistenceError(ex, 0);
0272: }
0273: } else { // loading must be done in AWT event dispatch thread
0274: try {
0275: java.awt.EventQueue.invokeAndWait(new Runnable() {
0276: public void run() {
0277: try {
0278: loadFormData();
0279: } catch (PersistenceException ex) {
0280: logPersistenceError(ex, 0);
0281: }
0282: }
0283: });
0284: } catch (Exception ex) {
0285: ex.printStackTrace();
0286: }
0287: }
0288:
0289: return formLoaded;
0290: }
0291:
0292: /** This method performs the form data loading. All open/load methods go
0293: * through this one.
0294: */
0295: private void loadFormData() throws PersistenceException {
0296: if (formLoaded)
0297: return; // form already loaded
0298:
0299: resetPersistenceErrorLog(); // clear log of errors
0300:
0301: // first find PersistenceManager for loading the form
0302: persistenceManager = recognizeForm(formDataObject);
0303:
0304: // create and register new FormModel instance
0305: formModel = new FormModel();
0306: formModel.setName(formDataObject.getName());
0307: formModel.setReadOnly(formDataObject.isReadOnly());
0308: formJavaSource = new FormJavaSource(formDataObject);
0309: formModel.getCodeStructure().setFormJavaSource(formJavaSource);
0310:
0311: openForms.put(formModel, this );
0312:
0313: // Force initialization of Auto Set Component Name.
0314: // It cannot be initialized in constructor of FormModel,
0315: // because it may call getResourceSupport() which
0316: // requires formModel/FormEditor pair to be in openForms.
0317: formModel.getSettings().getAutoSetComponentName();
0318:
0319: // load the form data (FormModel) and report errors
0320: synchronized (persistenceManager) {
0321: try {
0322: FormLAF.executeWithLookAndFeel(formModel,
0323: new Mutex.ExceptionAction() {
0324: public Object run() throws Exception {
0325: persistenceManager.loadForm(
0326: formDataObject, formModel,
0327: persistenceErrors);
0328: return null;
0329: }
0330: });
0331: } catch (PersistenceException ex) { // some fatal error occurred
0332: persistenceManager = null;
0333: openForms.remove(formModel);
0334: formModel = null;
0335: throw ex;
0336: } catch (Exception ex) { // should not happen, but for sure...
0337: ex.printStackTrace();
0338: persistenceManager = null;
0339: openForms.remove(formModel);
0340: formModel = null;
0341: return;
0342: }
0343: }
0344:
0345: // form is successfully loaded...
0346: formLoaded = true;
0347:
0348: getCodeGenerator().initialize(formModel);
0349: getResourceSupport(); // make sure ResourceSupport is created and initialized
0350:
0351: getBindingSupport();
0352: formModel.fireFormLoaded();
0353: if (formModel.wasCorrected()) // model repaired or upgraded
0354: formModel.fireFormChanged(false);
0355:
0356: // create form nodes hierarchy and add it to SourceChildren
0357: formRootNode = new FormRootNode(formModel);
0358: formRootNode.getChildren().getNodes();
0359: formDataObject.getNodeDelegate().getChildren().add(
0360: new Node[] { formRootNode });
0361:
0362: attachFormListener();
0363: attachDataObjectListener();
0364: attachSettingsListener();
0365: attachPaletteListener();
0366: }
0367:
0368: /** Public method for saving form data to file. Does not save the
0369: * source code (document), does not report errors and does not throw
0370: * any exceptions.
0371: * @return whether there was not any fatal error during saving (true means
0372: * everything was ok); returns true even if nothing was saved
0373: * because form was not loaded or read-only, etc.
0374: */
0375: public boolean saveForm() {
0376: try {
0377: saveFormData();
0378: return true;
0379: } catch (PersistenceException ex) {
0380: logPersistenceError(ex, 0);
0381: return false;
0382: }
0383: }
0384:
0385: void saveFormData() throws PersistenceException {
0386: if (formLoaded && !formDataObject.formFileReadOnly()
0387: && !formModel.isReadOnly()) {
0388: formModel.fireFormToBeSaved();
0389:
0390: resetPersistenceErrorLog();
0391:
0392: synchronized (persistenceManager) {
0393: persistenceManager.saveForm(formDataObject, formModel,
0394: persistenceErrors);
0395: }
0396: }
0397: }
0398:
0399: private void resetPersistenceErrorLog() {
0400: if (persistenceErrors != null)
0401: persistenceErrors.clear();
0402: else
0403: persistenceErrors = new ArrayList<Throwable>();
0404: }
0405:
0406: private void logPersistenceError(Throwable t, int index) {
0407: if (persistenceErrors == null)
0408: persistenceErrors = new ArrayList<Throwable>();
0409:
0410: if (index < 0)
0411: persistenceErrors.add(t);
0412: else
0413: persistenceErrors.add(index, t);
0414: }
0415:
0416: /** Finds PersistenceManager that can load and save the form.
0417: */
0418: private PersistenceManager recognizeForm(FormDataObject formDO)
0419: throws PersistenceException {
0420: Iterator<PersistenceManager> it = PersistenceManager
0421: .getManagers();
0422: if (!it.hasNext()) { // there's no PersistenceManager available
0423: PersistenceException ex = new PersistenceException(
0424: "No persistence manager registered"); // NOI18N
0425: ErrorManager
0426: .getDefault()
0427: .annotate(
0428: ex,
0429: ErrorManager.ERROR,
0430: null,
0431: FormUtils
0432: .getBundleString("MSG_ERR_NoPersistenceManager"), // NOI18N
0433: null, null);
0434: throw ex;
0435: }
0436:
0437: do {
0438: PersistenceManager pm = it.next();
0439: synchronized (pm) {
0440: try {
0441: if (pm.canLoadForm(formDO)) {
0442: resetPersistenceErrorLog();
0443: return pm;
0444: }
0445: } catch (PersistenceException ex) {
0446: logPersistenceError(ex);
0447: // [continue on exception?]
0448: }
0449: }
0450: } while (it.hasNext());
0451:
0452: // no PersistenceManager is able to load the form
0453: PersistenceException ex;
0454: if (!anyPersistenceError()) {
0455: // no error occurred, the format is just unknown
0456: ex = new PersistenceException(
0457: "Form file format not recognized"); // NOI18N
0458: ErrorManager
0459: .getDefault()
0460: .annotate(
0461: ex,
0462: ErrorManager.ERROR,
0463: null,
0464: FormUtils
0465: .getBundleString("MSG_ERR_NotRecognizedForm"), // NOI18N
0466: null, null);
0467: } else { // some errors occurred when recognizing the form file format
0468: Throwable annotateT = null;
0469: int n = persistenceErrors.size();
0470: if (n == 1) { // just one exception occurred
0471: ex = (PersistenceException) persistenceErrors.get(0);
0472: Throwable t = ex.getOriginalException();
0473: annotateT = t != null ? t : ex;
0474: n = 0;
0475: } else { // there were more exceptions
0476: ex = new PersistenceException(
0477: "Form file cannot be loaded"); // NOI18N
0478: annotateT = ex;
0479: }
0480: ErrorManager.getDefault().annotate(annotateT,
0481: FormUtils.getBundleString("MSG_ERR_LoadingErrors") // NOI18N
0482: );
0483: for (int i = 0; i < n; i++) {
0484: PersistenceException pe = (PersistenceException) persistenceErrors
0485: .get(i);
0486: Throwable t = pe.getOriginalException();
0487: ErrorManager.getDefault().annotate(ex,
0488: (t != null ? t : pe));
0489: }
0490: // all the exceptions were attached to the main exception to
0491: // be thrown, so the log can be cleared
0492: resetPersistenceErrorLog();
0493: }
0494: throw ex;
0495: }
0496:
0497: private void logPersistenceError(Throwable t) {
0498: logPersistenceError(t, -1);
0499: }
0500:
0501: private boolean anyPersistenceError() {
0502: return persistenceErrors != null
0503: && !persistenceErrors.isEmpty();
0504: }
0505:
0506: /** Reports errors occurred during loading or saving the form.
0507: *
0508: * @param operation operation being performed.
0509: */
0510: public void reportErrors(int operation) {
0511: if (!anyPersistenceError())
0512: return; // no errors or warnings logged
0513:
0514: final ErrorManager errorManager = ErrorManager.getDefault();
0515:
0516: boolean checkLoadingErrors = operation == LOADING && formLoaded;
0517: boolean anyNonFatalLoadingError = false; // was there a real error?
0518:
0519: for (Iterator it = persistenceErrors.iterator(); it.hasNext();) {
0520: Throwable t = (Throwable) it.next();
0521: if (t instanceof PersistenceException) {
0522: Throwable th = ((PersistenceException) t)
0523: .getOriginalException();
0524: if (th != null)
0525: t = th;
0526: }
0527:
0528: if (checkLoadingErrors && !anyNonFatalLoadingError) {
0529: // was there a real loading error (not just warnings) causing
0530: // some data not loaded?
0531: ErrorManager.Annotation[] annotations = errorManager
0532: .findAnnotations(t);
0533: int severity = 0;
0534: if ((annotations != null) && (annotations.length != 0)) {
0535: for (int i = 0; i < annotations.length; i++) {
0536: int s = annotations[i].getSeverity();
0537: if (s == ErrorManager.UNKNOWN)
0538: s = ErrorManager.EXCEPTION;
0539: if (s > severity)
0540: severity = s;
0541: }
0542: } else
0543: severity = ErrorManager.EXCEPTION;
0544:
0545: if (severity > ErrorManager.WARNING)
0546: anyNonFatalLoadingError = true;
0547: }
0548: errorManager.notify(ErrorManager.INFORMATIONAL, t);
0549: errorManager.notify(ErrorManager.USER, t);
0550: }
0551:
0552: if (checkLoadingErrors && anyNonFatalLoadingError) {
0553: // the form was loaded with some non-fatal errors - some data
0554: // was not loaded - show a warning about possible data loss
0555: java.awt.EventQueue.invokeLater(new Runnable() {
0556: public void run() {
0557: // for some reason this would be displayed before the
0558: // ErrorManager if not invoked later
0559:
0560: JButton viewOnly = new JButton(FormUtils
0561: .getBundleString("CTL_ViewOnly")); // NOI18N
0562: JButton allowEditing = new JButton(FormUtils
0563: .getBundleString("CTL_AllowEditing")); // NOI18N
0564:
0565: Object ret = DialogDisplayer
0566: .getDefault()
0567: .notify(
0568: new NotifyDescriptor(
0569: FormUtils
0570: .getBundleString("MSG_FormLoadedWithErrors"), // NOI18N
0571: FormUtils
0572: .getBundleString("CTL_FormLoadedWithErrors"), // NOI18N
0573: NotifyDescriptor.DEFAULT_OPTION,
0574: NotifyDescriptor.WARNING_MESSAGE,
0575: new Object[] {
0576: viewOnly,
0577: allowEditing,
0578: NotifyDescriptor.CANCEL_OPTION },
0579: viewOnly));
0580:
0581: if (ret == viewOnly) {
0582: setFormReadOnly();
0583: } else if (ret == allowEditing) {
0584: destroyInvalidComponents();
0585: } else { // close form, switch to source editor
0586: getFormDesigner().reset(FormEditor.this ); // might be reused
0587: closeForm();
0588: getFormDataObject().getFormEditorSupport()
0589: .selectJavaEditor();
0590: }
0591: }
0592: });
0593: }
0594:
0595: resetPersistenceErrorLog();
0596: }
0597:
0598: /**
0599: * Destroys all components from {@link #formModel} taged as invalid
0600: */
0601: private void destroyInvalidComponents() {
0602: Collection<RADComponent> allComps = formModel
0603: .getAllComponents();
0604: List<RADComponent> invalidComponents = new ArrayList<RADComponent>(
0605: allComps.size());
0606: // collect all invalid components
0607: for (RADComponent comp : allComps) {
0608: if (!comp.isValid()) {
0609: invalidComponents.add(comp);
0610: }
0611: }
0612: // destroy all invalid components
0613: for (RADComponent comp : invalidComponents) {
0614: try {
0615: comp.getNodeReference().destroy();
0616: } catch (java.io.IOException ex) { // should not happen
0617: ex.printStackTrace();
0618: }
0619: }
0620: }
0621:
0622: /**
0623: * Sets the FormEditor in Read-Only mode
0624: */
0625: private void setFormReadOnly() {
0626: formModel.setReadOnly(true);
0627: getFormDesigner().getHandleLayer().setViewOnly(true);
0628: detachFormListener();
0629: getFormDataObject().getFormEditorSupport()
0630: .updateMVTCDisplayName();
0631: }
0632:
0633: boolean needPostCreationUpdate() {
0634: return Boolean.TRUE.equals(formDataObject.getPrimaryFile()
0635: .getAttribute("justCreatedByNewWizard")); // NOI18N
0636: // see o.n.m.f.w.TemplateWizardIterator.instantiate()
0637: }
0638:
0639: private void preCreationUpdate() {
0640: FileObject fob = formDataObject.getPrimaryFile();
0641: Object libName = fob.getAttribute("requiredLibrary"); // NOI18N
0642: if (libName != null) {
0643: Object className = fob.getAttribute("requiredClass"); // NOI18N
0644: if ((className == null)
0645: || !ClassPathUtils.isOnClassPath(fob, className
0646: .toString())) {
0647: try {
0648: Library lib = LibraryManager.getDefault()
0649: .getLibrary((String) libName);
0650: ClassPathUtils.updateProject(fob, new ClassSource(
0651: (className == null) ? null : className
0652: .toString(),
0653: new ClassSource.LibraryEntry(lib)));
0654: } catch (IOException ioex) {
0655: Logger.getLogger(FormEditor.class.getName()).log(
0656: Level.INFO, ioex.getLocalizedMessage(),
0657: ioex);
0658: }
0659: }
0660: }
0661: }
0662:
0663: /**
0664: * Form just created by the user via the New wizard may need some additional
0665: * setup that can't be ensured by the static template. For example the type
0666: * of layout code generation needs to be honored, or properties
0667: * internationalized or converted to resources.
0668: */
0669: private void postCreationUpdate() {
0670: if (formLoaded && formModel != null && !formModel.isReadOnly()
0671: && needPostCreationUpdate()) // just created via New wizard
0672: { // detect settings, update the form, regenerate code, save
0673: // make sure no upgrade warning is shown
0674: formModel.setMaxVersionLevel(FormModel.LATEST_VERSION);
0675: // switch to resources if needed
0676: FormLAF.executeWithLookAndFeel(formModel, new Runnable() {
0677: public void run() {
0678: getResourceSupport().prepareNewForm();
0679: }
0680: });
0681: // make sure layout code generation type is detected
0682: formModel.getSettings().getLayoutCodeTarget();
0683: // hack: regenerate code immediately
0684: // - needs to be forced since there might be no change fired
0685: // - don't wait for the next round, we want to save now
0686: formModel.fireFormChanged(true);
0687: // remove SuppressWarnings annotation if necessary
0688: checkSuppressWarningsAnnotation();
0689: // save the form if changed
0690: FormEditorSupport fes = formDataObject
0691: .getFormEditorSupport();
0692: try {
0693: if (fes.isModified()) {
0694: saveFormData();
0695: fes.saveSourceOnly();
0696: }
0697: formDataObject.getPrimaryFile().setAttribute(
0698: "justCreatedByNewWizard", null); // NOI18N
0699: formDataObject.getPrimaryFile().setAttribute(
0700: "nonEditableTemplate", null); // NOI18N
0701: } catch (Exception ex) { // no problem should happen for just created form
0702: ErrorManager.getDefault().notify(
0703: ErrorManager.INFORMATIONAL, ex);
0704: }
0705: }
0706: }
0707:
0708: /** @return the last activated FormDesigner for this form */
0709: FormDesigner getFormDesigner() {
0710: if (!formLoaded)
0711: return null;
0712:
0713: return formDesigner;
0714: }
0715:
0716: /** Called by FormDesigner when activated. */
0717: void setFormDesigner(FormDesigner designer) {
0718: formDesigner = designer;
0719: }
0720:
0721: /** Closes the form. Used when closing the form editor or reloading
0722: * the form. */
0723: void closeForm() {
0724: if (formLoaded) {
0725: formModel.fireFormToBeClosed();
0726:
0727: openForms.remove(formModel);
0728: formModelToAssistant.remove(formModel);
0729: formLoaded = false;
0730:
0731: // remove nodes hierarchy
0732: if (formDataObject.isValid()) {
0733: // Avoiding deadlock (issue 51796)
0734: java.awt.EventQueue.invokeLater(new Runnable() {
0735: public void run() {
0736: if (formDataObject.isValid()) {
0737: formDataObject
0738: .getNodeDelegate()
0739: .getChildren()
0740: .remove(new Node[] { formRootNode });
0741: }
0742: formRootNode = null;
0743: }
0744: });
0745: }
0746:
0747: // remove listeners
0748: detachFormListener();
0749: detachDataObjectListener();
0750: detachPaletteListener();
0751:
0752: // focus the next form in inspector
0753: FormEditor next;
0754: if (openForms.isEmpty()) {
0755: next = null;
0756: detachSettingsListener();
0757: } else { // still any opened forms - focus some
0758: next = openForms.values().iterator().next();
0759: }
0760: if (ComponentInspector.exists()) {
0761: ComponentInspector.getInstance().focusForm(next);
0762: }
0763:
0764: // close the floating windows
0765: if (floatingWindows != null) {
0766: if (floatingWindows.size() > 0) {
0767: List<java.awt.Window> tempList = new LinkedList<java.awt.Window>(
0768: floatingWindows);
0769: Iterator it = tempList.iterator();
0770: while (it.hasNext()) {
0771: java.awt.Window window = (java.awt.Window) it
0772: .next();
0773: if (window.isVisible())
0774: window.setVisible(false);
0775: }
0776: }
0777: floatingWindows = null;
0778: }
0779:
0780: // reset references
0781: formDesigner = null;
0782: persistenceManager = null;
0783: persistenceErrors = null;
0784: formModel = null;
0785: codeGenerator = null;
0786: formJavaSource = null;
0787: resourceSupport = null;
0788: bindingSupport = null;
0789: }
0790: }
0791:
0792: private void attachFormListener() {
0793: if (formListener != null || formDataObject.isReadOnly()
0794: || formModel.isReadOnly())
0795: return;
0796:
0797: // this listener ensures necessary updates of nodes according to
0798: // changes in containers in form
0799: formListener = new FormModelListener() {
0800: public void formChanged(FormModelEvent[] events) {
0801: if (events == null)
0802: return;
0803:
0804: boolean modifying = false;
0805: Set<ComponentContainer> changedContainers = events.length > 0 ? new HashSet<ComponentContainer>()
0806: : null;
0807: Set<RADComponent> compsToSelect = null;
0808: FormNode nodeToSelect = null;
0809:
0810: for (int i = 0; i < events.length; i++) {
0811: FormModelEvent ev = events[i];
0812:
0813: if (ev.isModifying())
0814: modifying = true;
0815:
0816: int type = ev.getChangeType();
0817: if (type == FormModelEvent.CONTAINER_LAYOUT_EXCHANGED
0818: || type == FormModelEvent.CONTAINER_LAYOUT_CHANGED
0819: || type == FormModelEvent.COMPONENT_ADDED
0820: || type == FormModelEvent.COMPONENT_REMOVED
0821: || type == FormModelEvent.COMPONENTS_REORDERED) {
0822: ComponentContainer cont = ev.getContainer();
0823: if (changedContainers == null
0824: || !changedContainers.contains(cont)) {
0825: updateNodeChildren(cont);
0826: if (changedContainers != null)
0827: changedContainers.add(cont);
0828: }
0829:
0830: if (type == FormModelEvent.COMPONENT_REMOVED) {
0831: FormNode select;
0832: if (cont instanceof RADComponent) {
0833: select = ((RADComponent) cont)
0834: .getNodeReference();
0835: } else {
0836: select = getOthersContainerNode();
0837: }
0838:
0839: if (!(nodeToSelect instanceof RADComponentNode)) {
0840: if (nodeToSelect != formRootNode)
0841: nodeToSelect = select;
0842: } else if (nodeToSelect != select)
0843: nodeToSelect = formRootNode;
0844: } else if (type == FormModelEvent.CONTAINER_LAYOUT_EXCHANGED) {
0845: nodeToSelect = ((RADVisualContainer) cont)
0846: .getLayoutNodeReference();
0847: } else if (type == FormModelEvent.COMPONENT_ADDED
0848: && ev.getComponent().isInModel()) {
0849: if (compsToSelect == null)
0850: compsToSelect = new HashSet<RADComponent>();
0851:
0852: compsToSelect.add(ev.getComponent());
0853: compsToSelect.remove(ev.getContainer());
0854: }
0855: }
0856: }
0857:
0858: FormDesigner designer = getFormDesigner();
0859: if (designer != null) {
0860: if (compsToSelect != null) {
0861: designer.clearSelectionImpl();
0862: for (Iterator it = compsToSelect.iterator(); it
0863: .hasNext();) {
0864: designer
0865: .addComponentToSelectionImpl((RADComponent) it
0866: .next());
0867: }
0868: designer.updateComponentInspector();
0869: // RADComponent[] comps =
0870: // new RADComponent[compsToSelect.size()];
0871: // compsToSelect.toArray(comps);
0872: // designer.setSelectedComponents(comps);
0873: } else if (nodeToSelect != null)
0874: designer.setSelectedNode(nodeToSelect);
0875: }
0876:
0877: if (modifying) { // mark the form document modified explicitly
0878: getFormDataObject().getFormEditorSupport()
0879: .markFormModified();
0880: checkFormVersionUpgrade();
0881: }
0882: }
0883: };
0884:
0885: formModel.addFormModelListener(formListener);
0886: }
0887:
0888: private void detachFormListener() {
0889: if (formListener != null) {
0890: formModel.removeFormModelListener(formListener);
0891: formListener = null;
0892: }
0893: }
0894:
0895: /** Updates (sub)nodes of a container (in Component Inspector) after
0896: * a change has been made (like component added or removed). */
0897: void updateNodeChildren(ComponentContainer metacont) {
0898: FormNode node = null;
0899:
0900: if (metacont == null
0901: || metacont == formModel.getModelContainer()) {
0902: node = (formRootNode != null ? getOthersContainerNode()
0903: : null);
0904: } else if (metacont instanceof RADComponent) {
0905: node = ((RADComponent) metacont).getNodeReference();
0906: }
0907:
0908: if (node != null) {
0909: node.updateChildren();
0910: }
0911: }
0912:
0913: /**
0914: * After a round of changes check whether they did not require to upgrade
0915: * the form version. If the required version is higher than the version of
0916: * the IDE in which the form was created, ask the user for confirmation - to
0917: * let them know the form will not open in the older IDE anymore. If the
0918: * user refuses the upgrade, undo is performed (for that all the fired
0919: * changes must be already processed).
0920: */
0921: private void checkFormVersionUpgrade() {
0922: FormModel.FormVersion currentVersion = formModel
0923: .getCurrentVersionLevel();
0924: FormModel.FormVersion maxVersion = formModel
0925: .getMaxVersionLevel();
0926: if (currentVersion.ordinal() > maxVersion.ordinal()) {
0927: if (EventQueue.isDispatchThread()) {
0928: processVersionUpgrade(true);
0929: } else { // not a result of a user action, or some forgotten upgrade...
0930: confirmVersionUpgrade();
0931: }
0932: }
0933: }
0934:
0935: private void processVersionUpgrade(boolean processingEvents) {
0936: if (!processingEvents && formModel.hasPendingEvents()) {
0937: processingEvents = true;
0938: }
0939: if (processingEvents) { // post a task for later, if not already posted
0940: if (!upgradeCheckPosted) {
0941: upgradeCheckPosted = true;
0942: EventQueue.invokeLater(new Runnable() {
0943: public void run() {
0944: upgradeCheckPosted = false;
0945: if (formModel != null) {
0946: processVersionUpgrade(false);
0947: }
0948: }
0949: });
0950: }
0951: } else { // all events processed
0952: String upgradeOption = FormUtils
0953: .getBundleString("CTL_UpgradeOption"); // NOI18N
0954: String undoOption = FormUtils
0955: .getBundleString("CTL_CancelOption"); // NOI18N
0956: NotifyDescriptor d = new NotifyDescriptor(
0957: FormUtils.getBundleString("MSG_UpgradeQuestion"), // NOI18N
0958: FormUtils.getBundleString("TITLE_FormatUpgrade"), // NOI18N
0959: NotifyDescriptor.DEFAULT_OPTION,
0960: NotifyDescriptor.QUESTION_MESSAGE, new String[] {
0961: upgradeOption, undoOption }, upgradeOption);
0962: if (DialogDisplayer.getDefault().notify(d) == upgradeOption) {
0963: confirmVersionUpgrade();
0964: } else { // upgrade refused
0965: revertVersionUpgrade();
0966: }
0967: }
0968: }
0969:
0970: private void confirmVersionUpgrade() {
0971: if (formModel != null) {
0972: formModel.setMaxVersionLevel(FormModel.LATEST_VERSION);
0973: }
0974: }
0975:
0976: private void revertVersionUpgrade() {
0977: if (formModel != null) {
0978: formModel.getUndoRedoManager().undo();
0979: formModel.revertVersionLevel();
0980: }
0981: }
0982:
0983: private void attachDataObjectListener() {
0984: if (dataObjectListener != null)
0985: return;
0986:
0987: dataObjectListener = new PropertyChangeListener() {
0988: public void propertyChange(PropertyChangeEvent ev) {
0989: if (DataObject.PROP_NAME.equals(ev.getPropertyName())) {
0990: // FormDataObject's name has changed
0991: String name = formDataObject.getName();
0992: formModel.setName(name);
0993: formRootNode.updateName(name);
0994: // multiview updated by FormEditorSupport
0995: // code regenerated by FormRefactoringUpdate
0996: } else if (DataObject.PROP_COOKIE.equals(ev
0997: .getPropertyName())) {
0998: java.awt.EventQueue.invokeLater(new Runnable() {
0999: public void run() {
1000: Node[] nodes = ComponentInspector
1001: .getInstance().getExplorerManager()
1002: .getSelectedNodes();
1003: for (int i = 0; i < nodes.length; i++)
1004: ((FormNode) nodes[i]).updateCookies();
1005: }
1006: });
1007: }
1008: }
1009: };
1010:
1011: formDataObject.addPropertyChangeListener(dataObjectListener);
1012: }
1013:
1014: private void detachDataObjectListener() {
1015: if (dataObjectListener != null) {
1016: formDataObject
1017: .removePropertyChangeListener(dataObjectListener);
1018: dataObjectListener = null;
1019: }
1020: }
1021:
1022: private static void attachSettingsListener() {
1023: if (settingsListener != null)
1024: return;
1025:
1026: settingsListener = new PreferenceChangeListener() {
1027: public void preferenceChange(PreferenceChangeEvent evt) {
1028: Iterator iter = openForms.keySet().iterator();
1029: while (iter.hasNext()) {
1030: FormModel formModel = (FormModel) iter.next();
1031: String propName = evt.getKey();
1032:
1033: if (FormLoaderSettings.PROP_USE_INDENT_ENGINE
1034: .equals(propName)) {
1035: formModel.fireSyntheticPropertyChanged(null,
1036: propName, null, evt.getNewValue());
1037: } else if (FormLoaderSettings.PROP_SELECTION_BORDER_SIZE
1038: .equals(propName)
1039: || FormLoaderSettings.PROP_SELECTION_BORDER_COLOR
1040: .equals(propName)
1041: || FormLoaderSettings.PROP_CONNECTION_BORDER_COLOR
1042: .equals(propName)
1043: || FormLoaderSettings.PROP_FORMDESIGNER_BACKGROUND_COLOR
1044: .equals(propName)
1045: || FormLoaderSettings.PROP_FORMDESIGNER_BORDER_COLOR
1046: .equals(propName)) {
1047: FormDesigner designer = getFormDesigner(formModel);
1048: if (designer != null) {
1049: designer.updateVisualSettings();
1050: }
1051: } else if (FormLoaderSettings.PROP_PALETTE_IN_TOOLBAR
1052: .equals(propName)) {
1053: FormDesigner designer = getFormDesigner(formModel);
1054: if (designer != null) {
1055: designer
1056: .getFormToolBar()
1057: .showPaletteButton(
1058: FormLoaderSettings
1059: .getInstance()
1060: .isPaletteInToolBar());
1061: }
1062: }
1063: }
1064: }
1065: };
1066:
1067: FormLoaderSettings.getPreferences()
1068: .addPreferenceChangeListener(settingsListener);
1069: }
1070:
1071: private static void detachSettingsListener() {
1072: if (settingsListener != null) {
1073: FormLoaderSettings.getPreferences()
1074: .removePreferenceChangeListener(settingsListener);
1075: settingsListener = null;
1076: }
1077: }
1078:
1079: private void attachPaletteListener() {
1080: if (paletteListener != null)
1081: return;
1082:
1083: paletteListener = new PropertyChangeListener() {
1084: public void propertyChange(PropertyChangeEvent evt) {
1085: if (PaletteController.PROP_SELECTED_ITEM.equals(evt
1086: .getPropertyName())) {
1087: FormModel formModel = getFormModel();
1088: if (isFormLoaded() && formModel != null
1089: && !formModel.isReadOnly()) {
1090: FormDesigner designer = getFormDesigner(formModel);
1091: if (designer != null) {
1092: // PENDING should be done for all cloned designers
1093: if (evt.getNewValue() == null) {
1094: if (designer.getDesignerMode() == FormDesigner.MODE_ADD)
1095: designer
1096: .setDesignerMode(FormDesigner.MODE_SELECT);
1097: } else {
1098: if (designer.getDesignerMode() == FormDesigner.MODE_ADD) {
1099: // Change in the selected palette item means unselection
1100: // of the old item and selection of the new one
1101: designer
1102: .setDesignerMode(FormDesigner.MODE_SELECT);
1103: }
1104: designer
1105: .setDesignerMode(FormDesigner.MODE_ADD);
1106: }
1107: // TODO activate current designer?
1108: }
1109: }
1110: }
1111: }
1112: };
1113:
1114: PaletteUtils.addPaletteListener(paletteListener, formDataObject
1115: .getPrimaryFile());
1116: }
1117:
1118: private void detachPaletteListener() {
1119: if (paletteListener != null) {
1120: PaletteUtils.removePaletteListener(paletteListener,
1121: formDataObject.getPrimaryFile());
1122: paletteListener = null;
1123: }
1124: }
1125:
1126: void reinstallListener() {
1127: if (formListener != null) {
1128: formModel.removeFormModelListener(formListener);
1129: formModel.addFormModelListener(formListener);
1130: }
1131: }
1132:
1133: /**
1134: * Returns code editor pane for the specified form.
1135: *
1136: * @param formModel form model.
1137: * @return JEditorPane set up with the actuall forms java source*/
1138: public static JEditorPane createCodeEditorPane(FormModel formModel) {
1139: FormDataObject dobj = getFormDataObject(formModel);
1140: JavaCodeGenerator codeGen = (JavaCodeGenerator) FormEditor
1141: .getCodeGenerator(formModel);
1142: codeGen.regenerateCode();
1143:
1144: JEditorPane codePane = new JEditorPane();
1145: SimpleSection sec = dobj.getFormEditorSupport()
1146: .getInitComponentSection();
1147: int pos = sec.getText().indexOf('{') + 2
1148: + sec.getStartPosition().getOffset();
1149: FormUtils.setupEditorPane(codePane, dobj.getPrimaryFile(), pos);
1150: return codePane;
1151: }
1152:
1153: public static synchronized AssistantModel getAssistantModel(
1154: FormModel formModel) {
1155: assert (formModel != null);
1156: AssistantModel assistant = formModelToAssistant.get(formModel);
1157: if (assistant == null) {
1158: assistant = new AssistantModel();
1159: formModelToAssistant.put(formModel, assistant);
1160: }
1161: return assistant;
1162: }
1163:
1164: /**
1165: * @param formModel form model.
1166: * @return FormDesigner for given form */
1167: public static FormDesigner getFormDesigner(FormModel formModel) {
1168: FormEditor formEditor = openForms.get(formModel);
1169: return formEditor != null ? formEditor.getFormDesigner() : null;
1170: }
1171:
1172: /**
1173: * Returns code generator for the specified form.
1174: *
1175: * @param formModel form model.
1176: * @return CodeGenerator for given form */
1177: public static CodeGenerator getCodeGenerator(FormModel formModel) {
1178: FormEditor formEditor = openForms.get(formModel);
1179: return formEditor != null ? formEditor.getCodeGenerator()
1180: : null;
1181: }
1182:
1183: /**
1184: * Returns form data object for the specified form.
1185: *
1186: * @param formModel form model.
1187: * @return FormDataObject of given form */
1188: public static FormDataObject getFormDataObject(FormModel formModel) {
1189: FormEditor formEditor = openForms.get(formModel);
1190: return formEditor != null ? formEditor.getFormDataObject()
1191: : null;
1192: }
1193:
1194: /**
1195: * Returns <code>FormJavaSource</code> for the specified form.
1196: *
1197: * @param formModel form model.
1198: * @return FormJavaSource of given form */
1199: public static FormJavaSource getFormJavaSource(FormModel formModel) {
1200: FormEditor formEditor = openForms.get(formModel);
1201: return formEditor != null ? formEditor.getFormJavaSource()
1202: : null;
1203: }
1204:
1205: /**
1206: * Returns <code>ResourceSupport</code> for the specified form.
1207: *
1208: * @param formModel form model.
1209: * @return ResourceSupport of given form */
1210: static ResourceSupport getResourceSupport(FormModel formModel) {
1211: FormEditor formEditor = openForms.get(formModel);
1212: return formEditor != null ? formEditor.getResourceSupport()
1213: : null;
1214: }
1215:
1216: /**
1217: * Returns <code>BindingDesignSupport</code> for the specified form.
1218: *
1219: * @param formModel form model.
1220: * @return BindingDesignSupport of given form */
1221: static BindingDesignSupport getBindingSupport(FormModel formModel) {
1222: FormEditor formEditor = openForms.get(formModel);
1223: return formEditor != null ? formEditor.getBindingSupport()
1224: : null;
1225: }
1226:
1227: /**
1228: * Returns form editor for the specified form.
1229: *
1230: * @param formModel form model.
1231: * @return FormEditor instance for given form */
1232: public static FormEditor getFormEditor(FormModel formModel) {
1233: return openForms.get(formModel);
1234: }
1235:
1236: UndoRedo.Manager getFormUndoRedoManager() {
1237: return formModel != null ? formModel.getUndoRedoManager()
1238: : null;
1239: }
1240:
1241: public void registerFloatingWindow(java.awt.Window window) {
1242: if (floatingWindows == null)
1243: floatingWindows = new ArrayList<java.awt.Window>();
1244: else
1245: floatingWindows.remove(window);
1246: floatingWindows.add(window);
1247: }
1248:
1249: public void unregisterFloatingWindow(java.awt.Window window) {
1250: if (floatingWindows != null)
1251: floatingWindows.remove(window);
1252: }
1253:
1254: public void registerDefaultComponentAction(Action action) {
1255: if (defaultActions == null) {
1256: createDefaultComponentActionsList();
1257: } else {
1258: defaultActions.remove(action);
1259: }
1260: defaultActions.add(0, action);
1261: }
1262:
1263: public void unregisterDefaultComponentAction(Action action) {
1264: if (defaultActions != null) {
1265: defaultActions.remove(action);
1266: }
1267: }
1268:
1269: private void createDefaultComponentActionsList() {
1270: defaultActions = new LinkedList<Action>();
1271: defaultActions.add(SystemAction.get(EditContainerAction.class));
1272: defaultActions.add(SystemAction.get(EditFormAction.class));
1273: defaultActions.add(SystemAction.get(DefaultRADAction.class));
1274: }
1275:
1276: Collection<Action> getDefaultComponentActions() {
1277: if (defaultActions == null) {
1278: createDefaultComponentActionsList();
1279: }
1280: return Collections.unmodifiableList(defaultActions);
1281: }
1282:
1283: /**
1284: * Updates project classpath with the layout extensions library.
1285: *
1286: * @param formModel form model.
1287: * @return <code>true</code> if the project was updated.
1288: */
1289: public static boolean updateProjectForNaturalLayout(
1290: FormModel formModel) {
1291: FormEditor formEditor = getFormEditor(formModel);
1292: if (formEditor != null
1293: && formModel.getSettings().getLayoutCodeTarget() != JavaCodeGenerator.LAYOUT_CODE_JDK6
1294: && !ClassPathUtils
1295: .isOnClassPath(formEditor.getFormDataObject()
1296: .getFormFile(),
1297: org.jdesktop.layout.GroupLayout.class
1298: .getName())) {
1299: try {
1300: Library lib = LibraryManager.getDefault().getLibrary(
1301: "swing-layout"); // NOI18N
1302: if (lib == null) {
1303: return false;
1304: }
1305: ClassSource cs = new ClassSource("", // class name is not needed // NOI18N
1306: new ClassSource.LibraryEntry(lib));
1307: return Boolean.TRUE == ClassPathUtils.updateProject(
1308: formEditor.getFormDataObject().getFormFile(),
1309: cs);
1310: } catch (IOException ex) {
1311: ErrorManager.getDefault().notify(
1312: ErrorManager.INFORMATIONAL, ex);
1313: } catch (RuntimeException ex) { // e.g. UnsupportedOperationException
1314: ErrorManager.getDefault().notify(
1315: ErrorManager.INFORMATIONAL, ex);
1316: }
1317: }
1318: return false;
1319: }
1320:
1321: /**
1322: * Updates project classpath with the beans binding library.
1323: *
1324: * @param formModel form model.
1325: * @return <code>true</code> if the project was updated.
1326: */
1327: public static boolean updateProjectForBeansBinding(
1328: FormModel formModel) {
1329: FormEditor formEditor = getFormEditor(formModel);
1330: if (formEditor != null
1331: && !ClassPathUtils.isOnClassPath(formEditor
1332: .getFormDataObject().getFormFile(),
1333: org.jdesktop.beansbinding.Binding.class
1334: .getName())) {
1335: try {
1336: Library lib = LibraryManager.getDefault().getLibrary(
1337: "beans-binding"); // NOI18N
1338: if (lib == null) {
1339: return false;
1340: }
1341: ClassSource cs = new ClassSource("", // class name is not needed // NOI18N
1342: new ClassSource.LibraryEntry(lib));
1343: return Boolean.TRUE == ClassPathUtils.updateProject(
1344: formEditor.getFormDataObject().getFormFile(),
1345: cs);
1346: } catch (IOException ex) {
1347: ErrorManager.getDefault().notify(
1348: ErrorManager.INFORMATIONAL, ex);
1349: }
1350: }
1351: return false;
1352: }
1353:
1354: public static boolean isNonVisualTrayEnabled() {
1355: return Boolean.getBoolean("netbeans.form.non_visual_tray"); // NOI18N
1356: }
1357:
1358: private void checkSuppressWarningsAnnotation() {
1359: FileObject fo = getFormDataObject().getPrimaryFile();
1360: ClassPath cp = ClassPath.getClassPath(fo, ClassPath.BOOT);
1361: if (cp.findResource("java/lang/SuppressWarnings.class") == null) { // NOI18N
1362: // The project's bootclasspath doesn't contain SuppressWarnings class.
1363: // So, remove this annotation from initComponents() method.
1364: final String foName = fo.getName();
1365: JavaSource js = JavaSource.forFileObject(fo);
1366: final int[] positions = new int[] { -1, -1 };
1367: try {
1368: js.runModificationTask(
1369: new CancellableTask<WorkingCopy>() {
1370: public void cancel() {
1371: }
1372:
1373: public void run(WorkingCopy wcopy)
1374: throws Exception {
1375: wcopy
1376: .toPhase(JavaSource.Phase.RESOLVED);
1377:
1378: ClassTree clazz = null;
1379: CompilationUnitTree cu = wcopy
1380: .getCompilationUnit();
1381: for (Tree tree : cu.getTypeDecls()) {
1382: if (tree.getKind() == Tree.Kind.CLASS) {
1383: ClassTree cand = (ClassTree) tree;
1384: if (foName.equals(cand
1385: .getSimpleName()
1386: .toString())) {
1387: clazz = cand;
1388: }
1389: }
1390: }
1391: if (clazz == null)
1392: return;
1393:
1394: for (Tree tree : clazz.getMembers()) {
1395: if (tree.getKind() == Tree.Kind.METHOD) {
1396: MethodTree method = (MethodTree) tree;
1397: if ("initComponents"
1398: .equals(method
1399: .getName()
1400: .toString()) // NOI18N
1401: && (method
1402: .getParameters()
1403: .size() == 0)) {
1404: ModifiersTree modifiers = method
1405: .getModifiers();
1406: for (AnnotationTree annotation : modifiers
1407: .getAnnotations()) {
1408: if (annotation
1409: .getAnnotationType()
1410: .toString()
1411: .contains(
1412: "SuppressWarnings")) { // NOI18N
1413: SourcePositions sp = wcopy
1414: .getTrees()
1415: .getSourcePositions();
1416: positions[0] = (int) sp
1417: .getStartPosition(
1418: cu,
1419: annotation);
1420: positions[1] = (int) sp
1421: .getEndPosition(
1422: cu,
1423: annotation);
1424: // We cannot use the following code because
1425: // part of the modifier is in guarded block
1426: //ModifiersTree newModifiers = wcopy.getTreeMaker().removeModifiersAnnotation(method.getModifiers(), annotation);
1427: //wcopy.rewrite(modifiers, newModifiers);
1428: }
1429: }
1430: }
1431: }
1432: }
1433:
1434: }
1435: }).commit();
1436: } catch (IOException ioex) {
1437: Logger.getLogger(FormEditor.class.getName()).log(
1438: Level.INFO, ioex.getLocalizedMessage(), ioex);
1439: }
1440: if (positions[0] != -1) {
1441: try {
1442: getFormDataObject().getFormEditorSupport()
1443: .getDocument().remove(positions[0],
1444: positions[1] - positions[0]);
1445: } catch (BadLocationException blex) {
1446: Logger.getLogger(FormEditor.class.getName()).log(
1447: Level.INFO, blex.getLocalizedMessage(),
1448: blex);
1449: }
1450: }
1451: }
1452: }
1453:
1454: }
|