Source Code Cross Referenced for FormEditorSupport.java in  » IDE-Netbeans » form » org » netbeans » modules » form » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » form » org.netbeans.modules.form 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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-2007 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 java.awt.EventQueue;
0045:        import java.beans.PropertyChangeEvent;
0046:        import java.beans.PropertyChangeListener;
0047:        import java.io.IOException;
0048:        import java.io.InputStream;
0049:        import java.io.ObjectInput;
0050:        import java.io.ObjectOutput;
0051:        import java.io.OutputStream;
0052:        import java.io.Reader;
0053:        import java.io.Serializable;
0054:        import java.io.Writer;
0055:        import java.lang.reflect.InvocationTargetException;
0056:        import java.nio.charset.Charset;
0057:        import java.text.MessageFormat;
0058:        import java.util.Collections;
0059:        import java.util.Enumeration;
0060:        import java.util.HashMap;
0061:        import java.util.HashSet;
0062:        import java.util.Iterator;
0063:        import java.util.Map;
0064:        import java.util.Set;
0065:        import java.util.logging.Level;
0066:        import java.util.logging.Logger;
0067:        import javax.swing.JComponent;
0068:        import javax.swing.JEditorPane;
0069:        import javax.swing.JPanel;
0070:        import javax.swing.text.BadLocationException;
0071:        import javax.swing.text.Document;
0072:        import javax.swing.text.EditorKit;
0073:        import javax.swing.text.Position;
0074:        import javax.swing.text.StyledDocument;
0075:        import org.netbeans.api.editor.guards.GuardedSectionManager;
0076:        import org.netbeans.api.editor.guards.SimpleSection;
0077:        import org.netbeans.api.queries.FileEncodingQuery;
0078:        import org.netbeans.core.api.multiview.MultiViewHandler;
0079:        import org.netbeans.core.api.multiview.MultiViews;
0080:        import org.netbeans.core.spi.multiview.CloseOperationHandler;
0081:        import org.netbeans.core.spi.multiview.CloseOperationState;
0082:        import org.netbeans.core.spi.multiview.MultiViewDescription;
0083:        import org.netbeans.core.spi.multiview.MultiViewElement;
0084:        import org.netbeans.core.spi.multiview.MultiViewElementCallback;
0085:        import org.netbeans.core.spi.multiview.MultiViewFactory;
0086:        import org.netbeans.core.spi.multiview.SourceViewMarker;
0087:        import org.netbeans.spi.editor.guards.GuardedEditorSupport;
0088:        import org.netbeans.spi.editor.guards.GuardedSectionsFactory;
0089:        import org.netbeans.spi.editor.guards.GuardedSectionsProvider;
0090:        import org.openide.DialogDisplayer;
0091:        import org.openide.ErrorManager;
0092:        import org.openide.NotifyDescriptor;
0093:        import org.openide.awt.UndoRedo;
0094:        import org.openide.cookies.CloseCookie;
0095:        import org.openide.cookies.EditorCookie;
0096:        import org.openide.cookies.PrintCookie;
0097:        import org.openide.cookies.SaveCookie;
0098:        import org.openide.filesystems.FileLock;
0099:        import org.openide.filesystems.FileObject;
0100:        import org.openide.filesystems.FileStateInvalidException;
0101:        import org.openide.filesystems.FileStatusEvent;
0102:        import org.openide.filesystems.FileStatusListener;
0103:        import org.openide.filesystems.FileSystem;
0104:        import org.openide.filesystems.FileUtil;
0105:        import org.openide.loaders.DataObject;
0106:        import org.openide.loaders.MultiDataObject;
0107:        import org.openide.nodes.CookieSet;
0108:        import org.openide.nodes.Node;
0109:        import org.openide.text.CloneableEditor;
0110:        import org.openide.text.CloneableEditorSupport;
0111:        import org.openide.text.DataEditorSupport;
0112:        import org.openide.text.NbDocument;
0113:        import org.openide.text.PositionRef;
0114:        import org.openide.util.UserQuestionException;
0115:        import org.openide.util.Utilities;
0116:        import org.openide.windows.CloneableOpenSupport;
0117:        import org.openide.windows.CloneableTopComponent;
0118:        import org.openide.windows.Mode;
0119:        import org.openide.windows.TopComponent;
0120:        import org.openide.windows.TopComponentGroup;
0121:        import org.openide.windows.WindowManager;
0122:
0123:        /**
0124:         *
0125:         * @author Ian Formanek, Tomas Pavek
0126:         */
0127:
0128:        public class FormEditorSupport extends DataEditorSupport implements 
0129:                EditorCookie.Observable, CloseCookie, PrintCookie {
0130:
0131:            /** ID of the form designer (in the multiview) */
0132:            private static final String MV_FORM_ID = "form"; //NOI18N
0133:            /** ID of the java editor (in the multiview) */
0134:            private static final String MV_JAVA_ID = "java"; // NOI18N
0135:
0136:            private static final int JAVA_ELEMENT_INDEX = 0;
0137:            private static final int FORM_ELEMENT_INDEX = 1;
0138:            private int elementToOpen; // default element index when multiview TC is created
0139:
0140:            private static final String SECTION_INIT_COMPONENTS = "initComponents"; // NOI18N
0141:            private static final String SECTION_VARIABLES = "variables"; // NOI18N
0142:
0143:            /** Icon for the form editor multiview window */
0144:            private static final String iconURL = "org/netbeans/modules/form/resources/form.gif"; // NOI18N
0145:
0146:            /** The DataObject of the form */
0147:            private FormDataObject formDataObject;
0148:
0149:            /** The embracing multiview TopComponent (holds the form designer and
0150:             * java editor) - we remeber the last active TopComponent (not all clones) */
0151:            private CloneableTopComponent multiviewTC;
0152:
0153:            // listeners
0154:            private static PropertyChangeListener topcompsListener;
0155:
0156:            private UndoRedo.Manager editorUndoManager;
0157:
0158:            private FormEditor formEditor;
0159:
0160:            /** Set of opened FormEditorSupport instances (java or form opened) */
0161:            private static Set<FormEditorSupport> opened = Collections
0162:                    .synchronizedSet(new HashSet<FormEditorSupport>());
0163:
0164:            private static Map<FileSystem, FileStatusListener> fsToStatusListener = new HashMap<FileSystem, FileStatusListener>();
0165:
0166:            // --------------
0167:            // constructor
0168:
0169:            public FormEditorSupport(MultiDataObject.Entry javaEntry,
0170:                    FormDataObject formDataObject, CookieSet cookies) {
0171:                super (formDataObject, new Environment(formDataObject));
0172:                setMIMEType("text/x-java"); // NOI18N
0173:                this .formDataObject = formDataObject;
0174:                this .cookies = cookies;
0175:            }
0176:
0177:            // ----------
0178:            // opening & saving interface methods
0179:
0180:            /** Main entry method. Called by OpenCookie implementation - opens the form.
0181:             * 
0182:             * @param forceFormElement determines whether we should force switch to form element.
0183:             * @see OpenCookie#open
0184:             */
0185:            public void openFormEditor(boolean forceFormElement) {
0186:                boolean alreadyOpened = opened.contains(this );
0187:                boolean switchToForm = forceFormElement || !alreadyOpened;
0188:                if (switchToForm) {
0189:                    elementToOpen = FORM_ELEMENT_INDEX;
0190:                }
0191:                multiviewTC = openCloneableTopComponent();
0192:                multiviewTC.requestActive();
0193:
0194:                if (switchToForm) {
0195:                    MultiViewHandler handler = MultiViews
0196:                            .findMultiViewHandler(multiviewTC);
0197:                    handler
0198:                            .requestActive(handler.getPerspectives()[FORM_ELEMENT_INDEX]);
0199:                }
0200:            }
0201:
0202:            private void addStatusListener(FileSystem fs) {
0203:                FileStatusListener fsl = fsToStatusListener.get(fs);
0204:                if (fsl == null) {
0205:                    fsl = new FileStatusListener() {
0206:                        public void annotationChanged(FileStatusEvent ev) {
0207:                            Iterator<FormEditorSupport> iter = opened
0208:                                    .iterator();
0209:                            while (iter.hasNext()) {
0210:                                FormEditorSupport fes = iter.next();
0211:                                if (ev.hasChanged(fes.getFormDataObject()
0212:                                        .getPrimaryFile())
0213:                                        || ev.hasChanged(fes
0214:                                                .getFormDataObject()
0215:                                                .getFormFile())) {
0216:                                    fes.updateMVTCDisplayName();
0217:                                }
0218:                            }
0219:                        }
0220:                    };
0221:                    fs.addFileStatusListener(fsl);
0222:                    fsToStatusListener.put(fs, fsl);
0223:                } // else do nothing - the listener is already added
0224:            }
0225:
0226:            private static void detachStatusListeners() {
0227:                Iterator iter = fsToStatusListener.entrySet().iterator();
0228:                while (iter.hasNext()) {
0229:                    Map.Entry entry = (Map.Entry) iter.next();
0230:                    FileSystem fs = (FileSystem) entry.getKey();
0231:                    FileStatusListener fsl = (FileStatusListener) entry
0232:                            .getValue();
0233:                    fs.removeFileStatusListener(fsl);
0234:                }
0235:                fsToStatusListener.clear();
0236:            }
0237:
0238:            void selectJavaEditor() {
0239:                MultiViewHandler handler = MultiViews
0240:                        .findMultiViewHandler(multiviewTC);
0241:                if (handler != null) {
0242:                    handler
0243:                            .requestActive(handler.getPerspectives()[JAVA_ELEMENT_INDEX]);
0244:                }
0245:            }
0246:
0247:            /** Overriden from JavaEditor - opens editor and ensures it is selected
0248:             * in the multiview.
0249:             */
0250:            @Override
0251:            public void open() {
0252:                if (EventQueue.isDispatchThread()) {
0253:                    openInAWT();
0254:                } else {
0255:                    EventQueue.invokeLater(new Runnable() {
0256:                        public void run() {
0257:                            openInAWT();
0258:                        }
0259:                    });
0260:                }
0261:            }
0262:
0263:            private void openInAWT() {
0264:                if (!formDataObject.isValid()) {
0265:                    return;
0266:                }
0267:                if (Boolean.TRUE.equals(formDataObject.getPrimaryFile()
0268:                        .getAttribute("nonEditableTemplate"))) { // NOI18N
0269:                    String pattern = FormUtils
0270:                            .getBundleString("MSG_NonEditableTemplate"); // NOI18N
0271:                    String message = MessageFormat.format(pattern,
0272:                            new Object[] { formDataObject.getNodeDelegate()
0273:                                    .getName() });
0274:                    DialogDisplayer.getDefault().notify(
0275:                            new NotifyDescriptor.Message(message));
0276:                    return;
0277:                }
0278:                elementToOpen = JAVA_ELEMENT_INDEX;
0279:                super .open();
0280:
0281:                // This method must be executed in AWT thread because
0282:                // otherwise multiview is opened in AWT using invokeLater
0283:                // and we don't have multiviewTC correctly set
0284:                MultiViewHandler handler = MultiViews
0285:                        .findMultiViewHandler(multiviewTC);
0286:                handler
0287:                        .requestActive(handler.getPerspectives()[JAVA_ELEMENT_INDEX]);
0288:            }
0289:
0290:            /** Overriden from JavaEditor - opens editor at given position and ensures
0291:             * it is selected in the multiview.
0292:             * 
0293:             * @param pos position
0294:             */
0295:            public void openAt(PositionRef pos) {
0296:                elementToOpen = JAVA_ELEMENT_INDEX;
0297:                openCloneableTopComponent();
0298:
0299:                MultiViewHandler handler = MultiViews
0300:                        .findMultiViewHandler(multiviewTC);
0301:                handler
0302:                        .requestActive(handler.getPerspectives()[JAVA_ELEMENT_INDEX]);
0303:
0304:                openAt(pos, -1).getComponent().requestActive();
0305:            }
0306:
0307:            public void openAt(Position pos) {
0308:                openAt(createPositionRef(pos.getOffset(), Position.Bias.Forward));
0309:            }
0310:
0311:            /** Public method for loading form data from file. Does not open the
0312:             * source editor and designer, does not report errors and does not throw
0313:             * any exceptions. Runs in AWT event dispatch thread, returns after the
0314:             * form is loaded (even if not called from AWT thread).
0315:             * @return whether the form is loaded (true also if it already was)
0316:             */
0317:            public boolean loadForm() {
0318:                // Ensure initialization of the formEditor
0319:                getFormEditor(true);
0320:                return formEditor.loadForm();
0321:            }
0322:
0323:            /** @return true if the form is opened, false otherwise */
0324:            public boolean isOpened() {
0325:                return (formEditor != null) && formEditor.isFormLoaded();
0326:            }
0327:
0328:            private boolean saving; // workaround for bug 75225
0329:
0330:            /** Save the document in this thread and start reparsing it.
0331:             * @exception IOException on I/O error
0332:             */
0333:            @Override
0334:            public void saveDocument() throws IOException {
0335:                IOException ioEx = null;
0336:                try {
0337:                    if (formEditor != null) {
0338:                        formEditor.saveFormData();
0339:                    }
0340:                    saving = true; // workaround for bug 75225
0341:                    super .saveDocument();
0342:                } catch (PersistenceException ex) {
0343:                    Throwable t = ex.getOriginalException();
0344:                    if (t instanceof  IOException)
0345:                        ioEx = (IOException) t;
0346:                    else {
0347:                        ioEx = new IOException("Cannot save the form"); // NOI18N
0348:                        ErrorManager.getDefault().annotate(ioEx,
0349:                                t != null ? t : ex);
0350:                    }
0351:                } finally {
0352:                    saving = false; // workaround for bug 75225
0353:                }
0354:                if (formEditor != null) {
0355:                    formEditor.reportErrors(FormEditor.SAVING);
0356:                }
0357:
0358:                if (ioEx != null)
0359:                    throw ioEx;
0360:            }
0361:
0362:            void saveSourceOnly() throws IOException {
0363:                try {
0364:                    saving = true; // workaround for bug 75225
0365:                    super .saveDocument();
0366:                } finally {
0367:                    saving = false; // workaround for bug 75225
0368:                }
0369:            }
0370:
0371:            // ------------
0372:            // other interface methods
0373:
0374:            /** @return data object representing the form */
0375:            public final FormDataObject getFormDataObject() {
0376:                return formDataObject;
0377:            }
0378:
0379:            // PENDING remove when form_new_layout is merged to trunk
0380:            public static FormDataObject getFormDataObject(FormModel formModel) {
0381:                return FormEditor.getFormDataObject(formModel);
0382:            }
0383:
0384:            public FormModel getFormModel() {
0385:                FormEditor fe = getFormEditor();
0386:                return (fe == null) ? null : fe.getFormModel();
0387:            }
0388:
0389:            // END of PENDING
0390:
0391:            public FormEditor getFormEditor() {
0392:                return getFormEditor(false);
0393:            }
0394:
0395:            FormEditor getFormEditor(boolean initialize) {
0396:                if ((formEditor == null) && initialize) {
0397:                    formEditor = new FormEditor(formDataObject);
0398:                }
0399:                return formEditor;
0400:            }
0401:
0402:            /** Marks the form as modified if it's not yet. Used if changes made
0403:             * in form data don't affect the java source file (generated code). */
0404:            void markFormModified() {
0405:                if (formEditor != null && formEditor.isFormLoaded()
0406:                        && !formDataObject.isModified()) {
0407:                    notifyModified();
0408:                }
0409:            }
0410:
0411:            @Override
0412:            protected UndoRedo.Manager createUndoRedoManager() {
0413:                editorUndoManager = super .createUndoRedoManager();
0414:                return editorUndoManager;
0415:            }
0416:
0417:            void discardEditorUndoableEdits() {
0418:                if (editorUndoManager != null)
0419:                    editorUndoManager.discardAllEdits();
0420:            }
0421:
0422:            // ------------
0423:            // static getters
0424:
0425:            JEditorPane getEditorPane() {
0426:                return multiviewTC != null ? ((CloneableEditorSupport.Pane) multiviewTC)
0427:                        .getEditorPane()
0428:                        : null;
0429:            }
0430:
0431:            // -----------
0432:            // closing/reloading
0433:
0434:            public void reloadForm() {
0435:                if (canClose())
0436:                    reloadDocument();
0437:            }
0438:
0439:            @Override
0440:            protected org.openide.util.Task reloadDocument() {
0441:                if (multiviewTC == null)
0442:                    return super .reloadDocument();
0443:
0444:                org.openide.util.Task docLoadTask = super .reloadDocument();
0445:
0446:                if (saving) // workaround for bug 75225
0447:                    return docLoadTask;
0448:
0449:                // after reloading is done, open the form editor again
0450:                java.awt.EventQueue.invokeLater(new Runnable() {
0451:                    public void run() {
0452:                        FormDesigner formDesigner = getFormEditor(true)
0453:                                .getFormDesigner();
0454:                        if (formDesigner == null) {
0455:                            formDesigner = (FormDesigner) multiviewTC
0456:                                    .getClientProperty("formDesigner"); // NOI18N
0457:                        }
0458:                        if (formDesigner == null) {
0459:                            // if formDesigner is null then it haven't been activated yet...
0460:                            return;
0461:                        }
0462:
0463:                        // close
0464:                        getFormEditor().closeForm();
0465:                        formEditor = null;
0466:
0467:                        formDesigner.reset(getFormEditor(true));
0468:                        getFormEditor().setFormDesigner(formDesigner);
0469:
0470:                        if (formDesigner.isShowing()) {
0471:                            // load the form only if its open
0472:                            loadForm();
0473:                            FormEditor formEditor = getFormEditor();
0474:                            formEditor.reportErrors(FormEditor.LOADING);
0475:                            if (!formEditor.isFormLoaded()) { // there was a loading error
0476:                                formDesigner.removeAll();
0477:                            } else {
0478:                                formDesigner.initialize();
0479:                            }
0480:                            ComponentInspector.getInstance().focusForm(
0481:                                    formEditor);
0482:                            formDesigner.revalidate();
0483:                            formDesigner.repaint();
0484:                        }
0485:                    }
0486:                });
0487:
0488:                return docLoadTask;
0489:            }
0490:
0491:            public FormEditor reloadFormEditor() {
0492:                if (formEditor == null || !formEditor.isFormLoaded()) {
0493:                    return null;
0494:                }
0495:                FormDesigner formDesigner = formEditor.getFormDesigner();
0496:                if (formDesigner == null) {
0497:                    formDesigner = (FormDesigner) multiviewTC
0498:                            .getClientProperty("formDesigner"); // NOI18N
0499:                }
0500:                formEditor.closeForm();
0501:                formEditor = null;
0502:                formEditor = getFormEditor(true); // new FormEditor instance
0503:                if (formDesigner != null) {
0504:                    formDesigner.reset(formEditor);
0505:                    formEditor.setFormDesigner(formDesigner);
0506:                }
0507:                loadForm();
0508:                formEditor.reportErrors(FormEditor.LOADING);
0509:                if (formEditor.isFormLoaded() && formDesigner != null
0510:                        && formDesigner.isShowing()) {
0511:                    formDesigner.initialize();
0512:                }
0513:                return formEditor;
0514:            }
0515:
0516:            public void closeFormEditor() {
0517:                if (isOpened()) {
0518:                    final FormDesigner formDesigner = formEditor
0519:                            .getFormDesigner();
0520:                    formEditor.closeForm();
0521:                    Runnable run = new Runnable() {
0522:                        public void run() {
0523:                            if (formDesigner != null) {
0524:                                formDesigner.reset(formEditor); // might be reused
0525:                            }
0526:                            selectJavaEditor();
0527:                        }
0528:                    };
0529:                    if (EventQueue.isDispatchThread()) {
0530:                        run.run();
0531:                    } else {
0532:                        try {
0533:                            java.awt.EventQueue.invokeAndWait(run);
0534:                        } catch (Exception ex) {
0535:                            ErrorManager.getDefault().notify(
0536:                                    ErrorManager.INFORMATIONAL, ex);
0537:                        }
0538:                    }
0539:                }
0540:            }
0541:
0542:            @Override
0543:            protected void notifyClosed() {
0544:                opened.remove(this );
0545:                if (opened.isEmpty()) {
0546:                    detachTopComponentsListener();
0547:                    detachStatusListeners();
0548:                }
0549:
0550:                super .notifyClosed(); // close java editor
0551:                if (formEditor != null) {
0552:                    formEditor.closeForm();
0553:                    formEditor = null;
0554:                    multiviewTC = null;
0555:                }
0556:                elementToOpen = JAVA_ELEMENT_INDEX;
0557:            }
0558:
0559:            private void multiViewClosed(CloneableTopComponent mvtc) {
0560:                Enumeration en = mvtc.getReference().getComponents();
0561:                boolean isLast = !en.hasMoreElements();
0562:                if (multiviewTC == mvtc) {
0563:                    multiviewTC = null;
0564:                    FormDesigner formDesigner = null;
0565:                    // Find another multiviewTC, possibly with loaded formDesigner
0566:                    while (en.hasMoreElements()) {
0567:                        multiviewTC = (CloneableTopComponent) en.nextElement();
0568:                        FormDesigner designer = (FormDesigner) multiviewTC
0569:                                .getClientProperty("formDesigner"); // NOI18N
0570:                        if (designer != null) {
0571:                            formDesigner = designer;
0572:                            break;
0573:                        }
0574:                    }
0575:                    if (!isLast && (formDesigner == null)) {
0576:                        // Only Java elements are opened in the remaining clones
0577:                        if (formEditor != null) {
0578:                            formEditor.closeForm();
0579:                            formEditor = null;
0580:                        }
0581:                    }
0582:                }
0583:
0584:                if (isLast) // last view of this form closed
0585:                    notifyClosed();
0586:            }
0587:
0588:            @Override
0589:            protected boolean notifyModified() {
0590:                boolean alreadyModified = isModified();
0591:                boolean retVal = super .notifyModified();
0592:
0593:                if (retVal) { // java source modification
0594:                    addSaveCookie();
0595:                }
0596:
0597:                if (!alreadyModified) {
0598:                    FileObject formFile = formDataObject.getFormFile();
0599:                    if (!formFile.canWrite()) { // Issue 74092
0600:                        FileLock lock = null;
0601:                        try {
0602:                            lock = formFile.lock();
0603:                        } catch (UserQuestionException uqex) {
0604:                            NotifyDescriptor nd = new NotifyDescriptor.Confirmation(
0605:                                    uqex.getLocalizedMessage(),
0606:                                    FormUtils
0607:                                            .getBundleString("TITLE_UserQuestion"), // NOI18N
0608:                                    NotifyDescriptor.YES_NO_OPTION);
0609:                            DialogDisplayer.getDefault().notify(nd);
0610:                            if (NotifyDescriptor.YES_OPTION.equals(nd
0611:                                    .getValue())) {
0612:                                try {
0613:                                    uqex.confirmed();
0614:                                    EventQueue.invokeLater(new Runnable() {
0615:                                        public void run() {
0616:                                            reloadForm();
0617:                                        }
0618:                                    });
0619:                                } catch (IOException ioex) {
0620:                                    ErrorManager.getDefault().notify(
0621:                                            ErrorManager.INFORMATIONAL, ioex);
0622:                                }
0623:                            }
0624:                        } catch (IOException ex) {
0625:                            ErrorManager.getDefault().notify(
0626:                                    ErrorManager.INFORMATIONAL, ex);
0627:                        } finally {
0628:                            if (lock != null) {
0629:                                lock.releaseLock();
0630:                            }
0631:                        }
0632:                    }
0633:                    updateMVTCDisplayName();
0634:                }
0635:                return retVal;
0636:            }
0637:
0638:            @Override
0639:            protected void notifyUnmodified() {
0640:                super .notifyUnmodified();
0641:                // java source modification
0642:                removeSaveCookie();
0643:                updateMVTCDisplayName();
0644:            }
0645:
0646:            private static void attachTopComponentsListener() {
0647:                if (topcompsListener != null)
0648:                    return;
0649:
0650:                topcompsListener = new PropertyChangeListener() {
0651:                    public void propertyChange(PropertyChangeEvent ev) {
0652:                        if (TopComponent.Registry.PROP_ACTIVATED.equals(ev
0653:                                .getPropertyName())) { // activated TopComponent has changed
0654:                            TopComponent active = TopComponent.getRegistry()
0655:                                    .getActivated();
0656:                            if (getSelectedElementType(active) != -1) { // it is our multiview
0657:                                FormEditorSupport fes = getFormEditor(active);
0658:                                if (fes != null) {
0659:                                    fes.multiviewTC = (CloneableTopComponent) active;
0660:                                    FormDesigner designer = (FormDesigner) active
0661:                                            .getClientProperty("formDesigner"); // NOI18N
0662:                                    if (designer != null)
0663:                                        fes.getFormEditor().setFormDesigner(
0664:                                                designer);
0665:                                }
0666:                            }
0667:                            checkFormGroupVisibility();
0668:                        } else if (TopComponent.Registry.PROP_OPENED.equals(ev
0669:                                .getPropertyName())) { // set of opened TopComponents has changed - hasn't some
0670:                            // of our views been closed?
0671:                            CloneableTopComponent closedTC = null;
0672:                            Set oldSet = (Set) ev.getOldValue();
0673:                            Set newSet = (Set) ev.getNewValue();
0674:                            if (newSet.size() < oldSet.size()) {
0675:                                Iterator it = oldSet.iterator();
0676:                                while (it.hasNext()) {
0677:                                    Object o = it.next();
0678:                                    if (!newSet.contains(o)) {
0679:                                        if (o instanceof  CloneableTopComponent)
0680:                                            closedTC = (CloneableTopComponent) o;
0681:                                        break;
0682:                                    }
0683:                                }
0684:                            }
0685:                            if (getSelectedElementType(closedTC) != -1) { // it is our multiview
0686:                                FormEditorSupport fes = getFormEditor(closedTC);
0687:                                if (fes != null)
0688:                                    fes.multiViewClosed(closedTC);
0689:                            }
0690:                            TopComponent active = TopComponent.getRegistry()
0691:                                    .getActivated();
0692:                            if (active != null
0693:                                    && getSelectedElementType(active) != -1) { // it is our multiview
0694:                                FormEditorSupport fes = getFormEditor(active);
0695:                                if (fes != null) {
0696:                                    fes.updateMVTCDisplayName();
0697:                                }
0698:                            }
0699:                        }
0700:                    }
0701:                };
0702:
0703:                TopComponent.getRegistry().addPropertyChangeListener(
0704:                        topcompsListener);
0705:            }
0706:
0707:            private static void detachTopComponentsListener() {
0708:                if (topcompsListener != null) {
0709:                    TopComponent.getRegistry().removePropertyChangeListener(
0710:                            topcompsListener);
0711:                    topcompsListener = null;
0712:
0713:                    TopComponentGroup group = WindowManager.getDefault()
0714:                            .findTopComponentGroup("form"); // NOI18N
0715:                    if (group != null)
0716:                        group.close();
0717:                }
0718:            }
0719:
0720:            // -------
0721:            // window system & multiview
0722:
0723:            @Override
0724:            protected CloneableEditorSupport.Pane createPane() {
0725:                if (!formDataObject.isValid()) {
0726:                    return super .createPane(); // Issue 110249
0727:                }
0728:                MultiViewDescription[] descs = new MultiViewDescription[] {
0729:                        new JavaDesc(formDataObject),
0730:                        new FormDesc(formDataObject) };
0731:
0732:                CloneableTopComponent mvtc = MultiViewFactory
0733:                        .createCloneableMultiView(descs, descs[elementToOpen],
0734:                                new CloseHandler(formDataObject));
0735:
0736:                // #45665 - dock into editor mode if possible..
0737:                Mode editorMode = WindowManager.getDefault().findMode(
0738:                        CloneableEditorSupport.EDITOR_MODE);
0739:                if (editorMode != null) {
0740:                    editorMode.dockInto(mvtc);
0741:                }
0742:                try {
0743:                    addStatusListener(formDataObject.getPrimaryFile()
0744:                            .getFileSystem());
0745:                } catch (FileStateInvalidException fsiex) {
0746:                    fsiex.printStackTrace();
0747:                }
0748:                return (CloneableEditorSupport.Pane) mvtc;
0749:            }
0750:
0751:            private static String getMVTCToolTipText(
0752:                    FormDataObject formDataObject) {
0753:                String name = FileUtil.getFileDisplayName(formDataObject
0754:                        .getFormFile());
0755:                if (name.endsWith(".form")) { // NOI18N
0756:                    name = name.substring(0, name.length() - 5);
0757:                }
0758:                return name;
0759:            }
0760:
0761:            /**
0762:             * Returns display name of the multiview top component.
0763:             * The first item of the array is normal display name,
0764:             * the second item of the array is HTML display name.
0765:             *
0766:             * @param formDataObject form data object representing the multiview tc.
0767:             * @return display names of the MVTC. The second item can be <code>null</code>.
0768:             */
0769:            private static String[] getMVTCDisplayName(
0770:                    FormDataObject formDataObject) {
0771:
0772:                boolean readonly = !formDataObject.getPrimaryFile().canWrite();
0773:
0774:                TopComponent active = TopComponent.getRegistry().getActivated();
0775:                FormEditorSupport fes = formDataObject.getFormEditor();
0776:                FormModel fm = null;
0777:                if (fes != null) {
0778:                    fm = fes.getFormModel();
0779:                }
0780:                if (active != null
0781:                        && getSelectedElementType(active) == FORM_ELEMENT_INDEX) {
0782:                    if (fm != null) {
0783:                        readonly = readonly || fm.isReadOnly();
0784:                    }
0785:                }
0786:
0787:                int version;
0788:                if (formDataObject.isModified()) {
0789:                    version = readonly ? 2 : 1;
0790:                } else {
0791:                    version = readonly ? 0 : 3;
0792:                }
0793:
0794:                Node node = formDataObject.getNodeDelegate();
0795:                String htmlTitle = node.getHtmlDisplayName();
0796:                String title = node.getDisplayName();
0797:                if (fm != null) {
0798:                    FormDesigner fd = FormEditor.getFormDesigner(formDataObject
0799:                            .getFormEditor().getFormModel());
0800:                    if (fd != null && fd.getFormModel() != null) {
0801:                        if (fd.isShowing() && !fd.isTopRADComponent()
0802:                                && fd.getTopDesignComponent() != null) {
0803:                            title = FormUtils.getFormattedBundleString(
0804:                                    "FMT_FormTitleWithContainerName", // NOI18N
0805:                                    new Object[] {
0806:                                            title,
0807:                                            fd.getTopDesignComponent()
0808:                                                    .getName() });
0809:                        }
0810:                    }
0811:                }
0812:                if (htmlTitle != null) {
0813:                    if (!htmlTitle.trim().startsWith("<html>")) { // NOI18N
0814:                        htmlTitle = "<html>" + htmlTitle; // NOI18N
0815:                    }
0816:                }
0817:                return new String[] {
0818:                        FormUtils.getFormattedBundleString("FMT_FormMVTCTitle",
0819:                                new Object[] { new Integer(version), title }), // NOI18N
0820:                        (htmlTitle == null) ? null : FormUtils
0821:                                .getFormattedBundleString("FMT_FormMVTCTitle",
0822:                                        new Object[] { new Integer(version),
0823:                                                htmlTitle }) // NOI18N
0824:                };
0825:            }
0826:
0827:            /** Updates title (display name) of all multiviews for given form. Replans
0828:             * to event queue thread if necessary. */
0829:            void updateMVTCDisplayName() {
0830:                if (java.awt.EventQueue.isDispatchThread()) {
0831:                    updateMVTCDisplayNameInAWT();
0832:                } else {
0833:                    java.awt.EventQueue.invokeLater(new Runnable() {
0834:                        public void run() {
0835:                            updateMVTCDisplayNameInAWT();
0836:                        }
0837:                    });
0838:                }
0839:            }
0840:
0841:            private void updateMVTCDisplayNameInAWT() {
0842:                if ((multiviewTC == null) || (!formDataObject.isValid())) // Issue 67544
0843:                    return;
0844:
0845:                String[] titles = getMVTCDisplayName(formDataObject);
0846:                Enumeration en = multiviewTC.getReference().getComponents();
0847:                while (en.hasMoreElements()) {
0848:                    TopComponent tc = (TopComponent) en.nextElement();
0849:                    tc.setDisplayName(titles[0]);
0850:                    tc.setHtmlDisplayName(titles[1]);
0851:                }
0852:            }
0853:
0854:            /** Updates tooltip of all multiviews for given form. Replans to even queue
0855:             * thread if necessary. */
0856:            void updateMVTCToolTipText() {
0857:                if (java.awt.EventQueue.isDispatchThread()) {
0858:                    if (multiviewTC == null)
0859:                        return;
0860:
0861:                    String tooltip = getMVTCToolTipText(formDataObject);
0862:                    Enumeration en = multiviewTC.getReference().getComponents();
0863:                    while (en.hasMoreElements()) {
0864:                        TopComponent tc = (TopComponent) en.nextElement();
0865:                        tc.setToolTipText(tooltip);
0866:                    }
0867:                } else {
0868:                    java.awt.EventQueue.invokeLater(new Runnable() {
0869:                        public void run() {
0870:                            if (multiviewTC == null)
0871:                                return;
0872:
0873:                            String tooltip = getMVTCToolTipText(formDataObject);
0874:                            Enumeration en = multiviewTC.getReference()
0875:                                    .getComponents();
0876:                            while (en.hasMoreElements()) {
0877:                                TopComponent tc = (TopComponent) en
0878:                                        .nextElement();
0879:                                tc.setToolTipText(tooltip);
0880:                            }
0881:                        }
0882:                    });
0883:                }
0884:            }
0885:
0886:            static boolean isLastView(TopComponent tc) {
0887:                if (!(tc instanceof  CloneableTopComponent))
0888:                    return false;
0889:
0890:                boolean oneOrLess = true;
0891:                Enumeration en = ((CloneableTopComponent) tc).getReference()
0892:                        .getComponents();
0893:                if (en.hasMoreElements()) {
0894:                    en.nextElement();
0895:                    if (en.hasMoreElements())
0896:                        oneOrLess = false;
0897:                }
0898:                return oneOrLess;
0899:            }
0900:
0901:            /** This is called by the multiview elements whenever they are created
0902:             * (and given a observer knowing their multiview TopComponent). It is
0903:             * important during deserialization and clonig the multiview - i.e. during
0904:             * the operations we have no control over. But anytime a multiview is
0905:             * created, this method gets called.
0906:             */
0907:            void setTopComponent(TopComponent topComp) {
0908:                multiviewTC = (CloneableTopComponent) topComp;
0909:                String[] titles = getMVTCDisplayName(formDataObject);
0910:                multiviewTC.setDisplayName(titles[0]);
0911:                multiviewTC.setHtmlDisplayName(titles[1]);
0912:                multiviewTC.setToolTipText(getMVTCToolTipText(formDataObject));
0913:                opened.add(this );
0914:                attachTopComponentsListener();
0915:            }
0916:
0917:            public static FormEditorSupport getFormEditor(TopComponent tc) {
0918:                Object dobj = tc.getLookup().lookup(DataObject.class);
0919:                return dobj instanceof  FormDataObject ? ((FormDataObject) dobj)
0920:                        .getFormEditorSupport() : null;
0921:            }
0922:
0923:            private static Boolean groupVisible = null;
0924:
0925:            static void checkFormGroupVisibility() {
0926:                // when active TopComponent changes, check if we should open or close
0927:                // the form editor group of windows (Inspector, Palette, Properties)
0928:                WindowManager wm = WindowManager.getDefault();
0929:                final TopComponentGroup group = wm
0930:                        .findTopComponentGroup("form"); // NOI18N
0931:                if (group == null)
0932:                    return; // group not found (should not happen)
0933:
0934:                boolean designerSelected = false;
0935:                Iterator it = wm.getModes().iterator();
0936:                while (it.hasNext()) {
0937:                    Mode mode = (Mode) it.next();
0938:                    TopComponent selected = mode.getSelectedTopComponent();
0939:                    if (getSelectedElementType(selected) == FORM_ELEMENT_INDEX) {
0940:                        designerSelected = true;
0941:                        break;
0942:                    }
0943:                }
0944:
0945:                if (designerSelected && !Boolean.TRUE.equals(groupVisible)) {
0946:                    // Bug 116008: calling group.open() first time may cause hiding the
0947:                    // FormDesigner (some winsys multiview initialization mess), calling
0948:                    // this method again and hiding the group. By setting the groupVisible
0949:                    // to false we make the re-entrant call effectively do nothing.
0950:                    groupVisible = Boolean.FALSE;
0951:                    group.open();
0952:                    groupVisible = Boolean.TRUE;
0953:                    final TopComponentGroup paletteGroup = wm
0954:                            .findTopComponentGroup("commonpalette"); // NOI18N
0955:                    if (null != paletteGroup) {
0956:                        paletteGroup.open();
0957:                    }
0958:                    ComponentInspector inspector = ComponentInspector
0959:                            .getInstance();
0960:                    if (!Boolean.TRUE.equals(inspector
0961:                            .getClientProperty("isSliding"))) { // NOI18N
0962:                        inspector.requestVisible();
0963:                    }
0964:                } else if (!designerSelected
0965:                        && !Boolean.FALSE.equals(groupVisible)) {
0966:                    group.close();
0967:                    groupVisible = Boolean.FALSE;
0968:                }
0969:            }
0970:
0971:            /** @return 0 if java editor in form editor multiview is selected
0972:             *          1 if form designer in form editor multiview is selected
0973:             *         -1 if the given TopComponent is not form editor multiview
0974:             */
0975:            static int getSelectedElementType(TopComponent tc) {
0976:                if (tc != null) {
0977:                    MultiViewHandler handler = MultiViews
0978:                            .findMultiViewHandler(tc);
0979:                    if (handler != null) {
0980:                        String prefId = handler.getSelectedPerspective()
0981:                                .preferredID();
0982:                        if (MV_JAVA_ID.equals(prefId))
0983:                            return JAVA_ELEMENT_INDEX; // 0
0984:                        if (MV_FORM_ID.equals(prefId))
0985:                            return FORM_ELEMENT_INDEX; // 1
0986:                    }
0987:                }
0988:                return -1;
0989:            }
0990:
0991:            public SimpleSection getVariablesSection() {
0992:                return getGuardedSectionManager().findSimpleSection(
0993:                        SECTION_VARIABLES);
0994:            }
0995:
0996:            public SimpleSection getInitComponentSection() {
0997:                return getGuardedSectionManager().findSimpleSection(
0998:                        SECTION_INIT_COMPONENTS);
0999:            }
1000:
1001:            public GuardedSectionManager getGuardedSectionManager() {
1002:                try {
1003:                    StyledDocument doc = openDocument();
1004:                    return GuardedSectionManager.getInstance(doc);
1005:                } catch (IOException ex) {
1006:                    throw (IllegalStateException) new IllegalStateException(
1007:                            "cannot open document").initCause(ex); // NOI18N
1008:                }
1009:            }
1010:
1011:            private final class FormGEditor implements  GuardedEditorSupport {
1012:
1013:                StyledDocument doc = null;
1014:
1015:                public StyledDocument getDocument() {
1016:                    return FormGEditor.this .doc;
1017:                }
1018:            }
1019:
1020:            private FormGEditor guardedEditor;
1021:            private GuardedSectionsProvider guardedProvider;
1022:
1023:            @Override
1024:            protected void loadFromStreamToKit(StyledDocument doc,
1025:                    InputStream stream, EditorKit kit) throws IOException,
1026:                    BadLocationException {
1027:                if (guardedEditor == null) {
1028:                    guardedEditor = new FormGEditor();
1029:                    GuardedSectionsFactory gFactory = GuardedSectionsFactory
1030:                            .find(((DataEditorSupport.Env) env).getMimeType());
1031:                    if (gFactory != null) {
1032:                        guardedProvider = gFactory.create(guardedEditor);
1033:                    }
1034:                }
1035:
1036:                if (guardedProvider != null) {
1037:                    guardedEditor.doc = doc;
1038:                    Charset c = FileEncodingQuery.getEncoding(this 
1039:                            .getDataObject().getPrimaryFile());
1040:                    Reader reader = guardedProvider.createGuardedReader(stream,
1041:                            c);
1042:                    try {
1043:                        kit.read(reader, doc, 0);
1044:                    } finally {
1045:                        reader.close();
1046:                    }
1047:                } else {
1048:                    super .loadFromStreamToKit(doc, stream, kit);
1049:                }
1050:            }
1051:
1052:            @Override
1053:            protected void saveFromKitToStream(StyledDocument doc,
1054:                    EditorKit kit, OutputStream stream) throws IOException,
1055:                    BadLocationException {
1056:                if (guardedProvider != null) {
1057:                    Charset c = FileEncodingQuery.getEncoding(this 
1058:                            .getDataObject().getPrimaryFile());
1059:                    Writer writer = guardedProvider.createGuardedWriter(stream,
1060:                            c);
1061:                    try {
1062:                        kit.write(writer, doc, 0, doc.getLength());
1063:                    } finally {
1064:                        writer.close();
1065:                    }
1066:                } else {
1067:                    super .saveFromKitToStream(doc, kit, stream);
1068:                }
1069:            }
1070:
1071:            // --------
1072:
1073:            /** A descriptor for the FormDesigner element of multiview. Allows lazy
1074:             * creation of the FormDesigner (and thus form loading). */
1075:            private static class FormDesc implements  MultiViewDescription,
1076:                    Serializable {
1077:
1078:                private static final long serialVersionUID = -3126744316624172415L;
1079:
1080:                private DataObject dataObject;
1081:
1082:                private FormDesc() {
1083:                }
1084:
1085:                public FormDesc(DataObject formDO) {
1086:                    dataObject = formDO;
1087:                }
1088:
1089:                private FormEditorSupport getFormEditor() {
1090:                    return dataObject != null
1091:                            && dataObject instanceof  FormDataObject ? ((FormDataObject) dataObject)
1092:                            .getFormEditorSupport()
1093:                            : null;
1094:                }
1095:
1096:                public MultiViewElement createElement() {
1097:                    FormEditorSupport formEditor = getFormEditor();
1098:                    return new FormDesigner((formEditor == null) ? null
1099:                            : formEditor.getFormEditor(true));
1100:                }
1101:
1102:                public String getDisplayName() {
1103:                    return FormUtils.getBundleString("CTL_DesignTabCaption"); // NOI18N
1104:                }
1105:
1106:                public org.openide.util.HelpCtx getHelpCtx() {
1107:                    return org.openide.util.HelpCtx.DEFAULT_HELP;
1108:                }
1109:
1110:                public java.awt.Image getIcon() {
1111:                    return Utilities.loadImage(iconURL);
1112:                }
1113:
1114:                public int getPersistenceType() {
1115:                    return TopComponent.PERSISTENCE_NEVER;
1116:                }
1117:
1118:                public String preferredID() {
1119:                    return MV_FORM_ID;
1120:                }
1121:
1122:                public void writeExternal(ObjectOutput out) throws IOException {
1123:                    out.writeObject(dataObject);
1124:                }
1125:
1126:                public void readExternal(ObjectInput in) throws IOException,
1127:                        ClassNotFoundException {
1128:                    Object firstObject = in.readObject();
1129:                    if (firstObject instanceof  FormDataObject)
1130:                        dataObject = (DataObject) firstObject;
1131:                }
1132:            }
1133:
1134:            // -------
1135:
1136:            /** A descriptor for the java editor as an element in multiview. */
1137:            private static class JavaDesc implements  MultiViewDescription,
1138:                    SourceViewMarker, Serializable {
1139:
1140:                private static final long serialVersionUID = -3126744316624172415L;
1141:
1142:                private DataObject dataObject;
1143:
1144:                private JavaDesc() {
1145:                }
1146:
1147:                public JavaDesc(DataObject formDO) {
1148:                    dataObject = formDO;
1149:                }
1150:
1151:                private FormEditorSupport getJavaEditor() {
1152:                    return dataObject != null
1153:                            && dataObject instanceof  FormDataObject ? ((FormDataObject) dataObject)
1154:                            .getFormEditorSupport()
1155:                            : null;
1156:                }
1157:
1158:                public MultiViewElement createElement() {
1159:                    FormEditorSupport javaEditor = getJavaEditor();
1160:                    if (javaEditor != null) {
1161:                        javaEditor.prepareDocument();
1162:                        JavaEditorTopComponent editor = new JavaEditorTopComponent(
1163:                                dataObject.getCookie(FormEditorSupport.class));
1164:                        Node[] nodes = editor.getActivatedNodes();
1165:                        if ((nodes == null) || (nodes.length == 0)) {
1166:                            editor.setActivatedNodes(new Node[] { dataObject
1167:                                    .getNodeDelegate() });
1168:                        }
1169:                        return (MultiViewElement) editor;
1170:                    }
1171:                    return MultiViewFactory.BLANK_ELEMENT;
1172:                }
1173:
1174:                public String getDisplayName() {
1175:                    return FormUtils.getBundleString("CTL_SourceTabCaption"); // NOI18N
1176:                }
1177:
1178:                public org.openide.util.HelpCtx getHelpCtx() {
1179:                    return org.openide.util.HelpCtx.DEFAULT_HELP;
1180:                }
1181:
1182:                public java.awt.Image getIcon() {
1183:                    return Utilities.loadImage(iconURL);
1184:                }
1185:
1186:                public int getPersistenceType() {
1187:                    return TopComponent.PERSISTENCE_ONLY_OPENED;
1188:                }
1189:
1190:                public String preferredID() {
1191:                    return MV_JAVA_ID;
1192:                }
1193:
1194:                public void writeExternal(ObjectOutput out) throws IOException {
1195:                    out.writeObject(dataObject);
1196:                }
1197:
1198:                public void readExternal(ObjectInput in) throws IOException,
1199:                        ClassNotFoundException {
1200:                    Object firstObject = in.readObject();
1201:                    if (firstObject instanceof  FormDataObject)
1202:                        dataObject = (DataObject) firstObject;
1203:                }
1204:            }
1205:
1206:            // --------
1207:
1208:            private static class JavaEditorTopComponent extends CloneableEditor
1209:                    implements  MultiViewElement {
1210:                private static final long serialVersionUID = -3126744316624172415L;
1211:
1212:                private transient JComponent toolbar;
1213:
1214:                private transient MultiViewElementCallback multiViewObserver;
1215:
1216:                JavaEditorTopComponent() {
1217:                    super ();
1218:                }
1219:
1220:                JavaEditorTopComponent(DataEditorSupport s) {
1221:                    super (s);
1222:                }
1223:
1224:                public JComponent getToolbarRepresentation() {
1225:                    if (toolbar == null) {
1226:                        JEditorPane pane = getEditorPane();
1227:                        if (pane != null) {
1228:                            Document doc = pane.getDocument();
1229:                            if (doc instanceof  NbDocument.CustomToolbar) {
1230:                                toolbar = ((NbDocument.CustomToolbar) doc)
1231:                                        .createToolbar(pane);
1232:                            }
1233:                        }
1234:                        if (toolbar == null) {
1235:                            // attempt to create own toolbar??
1236:                            toolbar = new JPanel();
1237:                        }
1238:                    }
1239:                    return toolbar;
1240:                }
1241:
1242:                public JComponent getVisualRepresentation() {
1243:                    return this ;
1244:                }
1245:
1246:                @Override
1247:                public void componentDeactivated() {
1248:                    super .componentDeactivated();
1249:                }
1250:
1251:                @Override
1252:                public void componentActivated() {
1253:                    super .componentActivated();
1254:                }
1255:
1256:                public void setMultiViewCallback(
1257:                        MultiViewElementCallback callback) {
1258:                    multiViewObserver = callback;
1259:
1260:                    // needed for deserialization...
1261:                    if (((DataEditorSupport) cloneableEditorSupport())
1262:                            .getDataObject() instanceof  FormDataObject) { // [obj is from EditorSupport.Editor]
1263:                        // this is used (or misused?) to obtain the deserialized
1264:                        // multiview topcomponent and set it to FormEditorSupport
1265:                        ((FormDataObject) ((DataEditorSupport) cloneableEditorSupport())
1266:                                .getDataObject()).getFormEditorSupport()
1267:                                .setTopComponent(callback.getTopComponent());
1268:                    }
1269:                }
1270:
1271:                @Override
1272:                public void requestVisible() {
1273:                    if (multiViewObserver != null)
1274:                        multiViewObserver.requestVisible();
1275:                    else
1276:                        super .requestVisible();
1277:                }
1278:
1279:                @Override
1280:                public void requestActive() {
1281:                    if (multiViewObserver != null)
1282:                        multiViewObserver.requestActive();
1283:                    else
1284:                        super .requestActive();
1285:                }
1286:
1287:                @Override
1288:                public void componentClosed() {
1289:                    // Issue 52286 & 55818
1290:                    super .canClose(null, true);
1291:                    super .componentClosed();
1292:                }
1293:
1294:                @Override
1295:                public void componentShowing() {
1296:                    super .componentShowing();
1297:                    DataObject dob = ((DataEditorSupport) cloneableEditorSupport())
1298:                            .getDataObject();
1299:                    FormDataObject formDO = (FormDataObject) dob;
1300:                    FormModel model = null;
1301:                    if (formDO != null) {
1302:                        FormEditorSupport fe = formDO.getFormEditor();
1303:                        if (fe != null) {
1304:                            model = fe.getFormModel();
1305:                            if (model != null) {
1306:                                JavaCodeGenerator codeGen = (JavaCodeGenerator) FormEditor
1307:                                        .getCodeGenerator(model);
1308:                                codeGen.regenerateCode();
1309:                            }
1310:                        }
1311:                    }
1312:
1313:                }
1314:
1315:                @Override
1316:                public void componentHidden() {
1317:                    super .componentHidden();
1318:                }
1319:
1320:                @Override
1321:                public void componentOpened() {
1322:                    super .componentOpened();
1323:                    DataObject dob = ((DataEditorSupport) cloneableEditorSupport())
1324:                            .getDataObject();
1325:                    if ((multiViewObserver != null)
1326:                            && !(dob instanceof  FormDataObject)) {
1327:                        multiViewObserver.getTopComponent().close(); // Issue 67879
1328:                        EditorCookie ec = dob.getCookie(EditorCookie.class);
1329:                        ec.open();
1330:                    }
1331:                }
1332:
1333:                @Override
1334:                public void updateName() {
1335:                    super .updateName();
1336:                    if (multiViewObserver != null) {
1337:                        FormDataObject formDataObject = (FormDataObject) ((DataEditorSupport) cloneableEditorSupport())
1338:                                .getDataObject();
1339:                        String[] titles = getMVTCDisplayName(formDataObject);
1340:                        setDisplayName(titles[0]);
1341:                        setHtmlDisplayName(titles[1]);
1342:                    }
1343:                }
1344:
1345:                @Override
1346:                protected boolean closeLast() {
1347:                    return true;
1348:                }
1349:
1350:                public CloseOperationState canCloseElement() {
1351:                    // if this is not the last cloned java editor component, closing is OK
1352:                    if (!FormEditorSupport.isLastView(multiViewObserver
1353:                            .getTopComponent()))
1354:                        return CloseOperationState.STATE_OK;
1355:
1356:                    // return a placeholder state - to be sure our CloseHandler is called
1357:                    return MultiViewFactory.createUnsafeCloseState(
1358:                            "ID_JAVA_CLOSING", // dummy ID // NOI18N
1359:                            MultiViewFactory.NOOP_CLOSE_ACTION,
1360:                            MultiViewFactory.NOOP_CLOSE_ACTION);
1361:                }
1362:
1363:                protected boolean isActiveTC() {
1364:                    TopComponent selected = getRegistry().getActivated();
1365:
1366:                    if (selected == null)
1367:                        return false;
1368:                    if (selected == this )
1369:                        return true;
1370:
1371:                    MultiViewHandler handler = MultiViews
1372:                            .findMultiViewHandler(selected);
1373:                    if (handler != null
1374:                            && MV_JAVA_ID.equals(handler
1375:                                    .getSelectedPerspective().preferredID()))
1376:                        return true;
1377:
1378:                    return false;
1379:                }
1380:            }
1381:
1382:            // ------
1383:
1384:            /** Implementation of CloseOperationHandler for multiview. Ensures both form
1385:             * and java editor are correctly closed, data saved, etc. Holds a reference
1386:             * to form DataObject only - to be serializable with the multiview
1387:             * TopComponent without problems.
1388:             */
1389:            private static class CloseHandler implements  CloseOperationHandler,
1390:                    Serializable {
1391:                private static final long serialVersionUID = -3126744315424172415L;
1392:
1393:                private DataObject dataObject;
1394:
1395:                private CloseHandler() {
1396:                }
1397:
1398:                public CloseHandler(DataObject formDO) {
1399:                    dataObject = formDO;
1400:                }
1401:
1402:                private FormEditorSupport getFormEditor() {
1403:                    return dataObject != null
1404:                            && dataObject instanceof  FormDataObject ? ((FormDataObject) dataObject)
1405:                            .getFormEditorSupport()
1406:                            : null;
1407:                }
1408:
1409:                public boolean resolveCloseOperation(
1410:                        CloseOperationState[] elements) {
1411:                    FormEditorSupport formEditor = getFormEditor();
1412:                    return formEditor != null ? formEditor.canClose() : true;
1413:                }
1414:            }
1415:
1416:            // ------
1417:
1418:            private static final class Environment extends
1419:                    DataEditorSupport.Env {
1420:
1421:                private static final long serialVersionUID = -1;
1422:
1423:                public Environment(DataObject obj) {
1424:                    super (obj);
1425:                }
1426:
1427:                @Override
1428:                protected FileObject getFile() {
1429:                    return this .getDataObject().getPrimaryFile();
1430:                }
1431:
1432:                @Override
1433:                protected FileLock takeLock() throws java.io.IOException {
1434:                    return ((FormDataObject) getDataObject()).getPrimaryEntry()
1435:                            .takeLock();
1436:                }
1437:
1438:                @Override
1439:                public CloneableOpenSupport findCloneableOpenSupport() {
1440:                    return this .getDataObject().getCookie(
1441:                            FormEditorSupport.class);
1442:                }
1443:
1444:            }
1445:
1446:            private final SaveCookie saveCookie = new SaveCookie() {
1447:                public void save() throws java.io.IOException {
1448:                    if (formEditor == null) { // not saving form, only java
1449:                        doSave(false); // don't need to be in event dispatch thread (#102986)
1450:                    } else if (EventQueue.isDispatchThread()) {
1451:                        doSave(true);
1452:                    } else {
1453:                        try {
1454:                            EventQueue.invokeAndWait(new Runnable() {
1455:                                public void run() {
1456:                                    doSave(true);
1457:                                }
1458:                            });
1459:                        } catch (InterruptedException ex) {
1460:                            Logger.getLogger(FormEditorSupport.class.getName())
1461:                                    .log(Level.INFO, "", ex); // NOI18N
1462:                        } catch (InvocationTargetException ex) {
1463:                            Logger.getLogger(FormEditorSupport.class.getName())
1464:                                    .log(Level.INFO, "", ex); // NOI18N
1465:                        }
1466:                    }
1467:                }
1468:
1469:                private void doSave(boolean bothJavaAndForm) {
1470:                    try {
1471:                        if (bothJavaAndForm) {
1472:                            saveDocument();
1473:                        } else {
1474:                            saveSourceOnly();
1475:                        }
1476:                    } catch (IOException ex) {
1477:                        Logger.getLogger(FormEditorSupport.class.getName())
1478:                                .log(Level.INFO, "", ex); // NOI18N
1479:                    }
1480:                }
1481:            };
1482:
1483:            private final CookieSet cookies;
1484:
1485:            public void addSaveCookie() {
1486:                DataObject javaData = this .getDataObject();
1487:                if (javaData.getCookie(SaveCookie.class) == null) {
1488:                    cookies.add(saveCookie);
1489:                    javaData.setModified(true);
1490:                }
1491:            }
1492:
1493:            public void removeSaveCookie() {
1494:                DataObject javaData = this .getDataObject();
1495:                if (javaData.getCookie(SaveCookie.class) != null) {
1496:                    cookies.remove(saveCookie);
1497:                    javaData.setModified(false);
1498:                }
1499:            }
1500:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.