Source Code Cross Referenced for FormDesigner.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-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 java.awt.*;
0045:        import java.awt.event.*;
0046:        import java.util.*;
0047:        import java.util.List;
0048:        import java.util.prefs.PreferenceChangeEvent;
0049:        import java.util.prefs.PreferenceChangeListener;
0050:        import javax.swing.*;
0051:        import javax.swing.border.*;
0052:        import java.beans.*;
0053:
0054:        import org.jdesktop.layout.Baseline;
0055:        import org.jdesktop.layout.LayoutStyle;
0056:
0057:        import org.netbeans.core.spi.multiview.*;
0058:        import org.netbeans.modules.form.menu.MenuEditLayer;
0059:        import org.netbeans.modules.form.palette.PaletteItem;
0060:        import org.openide.DialogDisplayer;
0061:        import org.openide.NotifyDescriptor;
0062:        import org.openide.actions.FileSystemAction;
0063:        import org.openide.util.actions.SystemAction;
0064:        import org.openide.windows.TopComponent;
0065:        import org.openide.nodes.Node;
0066:        import org.openide.util.*;
0067:        import org.openide.util.lookup.*;
0068:        import org.openide.awt.UndoRedo;
0069:        import org.openide.explorer.ExplorerUtils;
0070:        import org.openide.ErrorManager;
0071:        import org.openide.explorer.ExplorerManager;
0072:
0073:        import org.netbeans.modules.form.assistant.*;
0074:        import org.netbeans.modules.form.wizard.ConnectionWizard;
0075:        import org.netbeans.modules.form.layoutsupport.LayoutSupportManager;
0076:        import org.netbeans.modules.form.layoutdesign.*;
0077:        import org.netbeans.modules.form.layoutdesign.LayoutConstants.PaddingType;
0078:        import org.netbeans.modules.form.layoutdesign.support.SwingLayoutBuilder;
0079:        import org.netbeans.modules.form.palette.PaletteUtils;
0080:        import org.netbeans.modules.form.project.ClassSource;
0081:        import org.netbeans.modules.form.project.ClassPathUtils;
0082:        import org.openide.filesystems.FileObject;
0083:
0084:        /**
0085:         * This is a TopComponent subclass holding the form designer. It consist of two
0086:         * layers - HandleLayer (responsible for interaction with user) and
0087:         * ComponentLayer (presenting the components, not accessible to the user).
0088:         *
0089:         * FormDesigner
0090:         *  +- AssistantView
0091:         *  +- JScrollPane
0092:         *      +- JLayeredPane
0093:         *          +- HandleLayer
0094:         *          +- ComponentLayer
0095:         *
0096:         * @author Tran Duc Trung, Tomas Pavek, Josef Kozak
0097:         */
0098:
0099:        public class FormDesigner extends TopComponent implements 
0100:                MultiViewElement {
0101:            static final String PROP_DESIGNER_SIZE = "designerSize"; // NOI18N
0102:
0103:            // UI components composition
0104:            private JLayeredPane layeredPane;
0105:            private ComponentLayer componentLayer;
0106:            private HandleLayer handleLayer;
0107:            private NonVisualTray nonVisualTray;
0108:            private FormToolBar formToolBar;
0109:
0110:            // in-place editing
0111:            private InPlaceEditLayer textEditLayer;
0112:            private FormProperty editedProperty;
0113:            private InPlaceEditLayer.FinishListener finnishListener;
0114:
0115:            private MenuEditLayer menuEditLayer;
0116:
0117:            // metadata
0118:            private FormModel formModel;
0119:            private FormModelListener formModelListener;
0120:            private RADVisualComponent topDesignComponent;
0121:
0122:            private FormEditor formEditor;
0123:
0124:            // layout visualization and interaction
0125:            private List<RADComponent> selectedComponents = new ArrayList<RADComponent>();
0126:            private List<RADComponent> selectedLayoutComponents = new ArrayList<RADComponent>();
0127:            private VisualReplicator replicator;
0128:            private LayoutDesigner layoutDesigner;
0129:            private List<Action> designerActions;
0130:            private List<Action> resizabilityActions;
0131:
0132:            private JToggleButton[] resizabilityButtons;
0133:
0134:            private int designerMode;
0135:            public static final int MODE_SELECT = 0;
0136:            public static final int MODE_CONNECT = 1;
0137:            public static final int MODE_ADD = 2;
0138:
0139:            private boolean initialized = false;
0140:
0141:            private RADComponent connectionSource;
0142:            private RADComponent connectionTarget;
0143:
0144:            MultiViewElementCallback multiViewObserver;
0145:
0146:            private ExplorerManager explorerManager;
0147:            private FormProxyLookup lookup;
0148:
0149:            private AssistantView assistantView;
0150:            private PreferenceChangeListener settingsListener;
0151:
0152:            /** The icons for FormDesigner */
0153:            private static String iconURL = "org/netbeans/modules/form/resources/formDesigner.gif"; // NOI18N
0154:
0155:            private boolean hasPropertyChangeListener = false;
0156:
0157:            // ----------
0158:            // constructors and setup
0159:
0160:            FormDesigner(FormEditor formEditor) {
0161:                setIcon(Utilities.loadImage(iconURL));
0162:                setLayout(new BorderLayout());
0163:
0164:                FormLoaderSettings settings = FormLoaderSettings.getInstance();
0165:                Color backgroundColor = settings
0166:                        .getFormDesignerBackgroundColor();
0167:                Color borderColor = settings.getFormDesignerBorderColor();
0168:
0169:                JPanel loadingPanel = new JPanel();
0170:                loadingPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 12,
0171:                        12 + (settings.getAssistantShown() ? 40 : 0)));
0172:                loadingPanel.setBackground(backgroundColor);
0173:                JLabel loadingLbl = new JLabel(FormUtils
0174:                        .getBundleString("LBL_FormLoading")); // NOI18N
0175:                loadingLbl.setOpaque(true);
0176:                loadingLbl.setPreferredSize(new Dimension(410, 310));
0177:                loadingLbl.setHorizontalAlignment(SwingConstants.CENTER);
0178:                loadingPanel.add(loadingLbl);
0179:                loadingLbl.setBorder(new CompoundBorder(new LineBorder(
0180:                        borderColor, 5),
0181:                        new EmptyBorder(new Insets(6, 6, 6, 6))));
0182:                add(loadingPanel, BorderLayout.CENTER);
0183:
0184:                this .formEditor = formEditor;
0185:
0186:                if (formEditor != null) { // Issue 67879
0187:                    explorerManager = new ExplorerManager();
0188:
0189:                    // add FormDataObject to lookup so it can be obtained from multiview TopComponent
0190:                    ActionMap map = ComponentInspector.getInstance()
0191:                            .setupActionMap(getActionMap());
0192:                    final FormDataObject formDataObject = formEditor
0193:                            .getFormDataObject();
0194:                    lookup = new FormProxyLookup(new Lookup[] {
0195:                            ExplorerUtils.createLookup(explorerManager, map),
0196:                            Lookups.fixed(new Object[] { formDataObject }),
0197:                            PaletteUtils.getPaletteLookup(formDataObject
0198:                                    .getPrimaryFile()),
0199:                            formDataObject.getNodeDelegate().getLookup() });
0200:                    associateLookup(lookup);
0201:
0202:                    formToolBar = new FormToolBar(this );
0203:                }
0204:            }
0205:
0206:            void initialize() {
0207:                initialized = true;
0208:                removeAll();
0209:
0210:                formModel = formEditor.getFormModel();
0211:
0212:                componentLayer = new ComponentLayer(formModel);
0213:                handleLayer = new HandleLayer(this );
0214:                nonVisualTray = FormEditor.isNonVisualTrayEnabled() ? new NonVisualTray(
0215:                        formModel)
0216:                        : null;
0217:
0218:                JPanel designPanel = new JPanel(new BorderLayout());
0219:                designPanel.add(componentLayer, BorderLayout.CENTER);
0220:                if (nonVisualTray != null) {
0221:                    designPanel.add(nonVisualTray, BorderLayout.SOUTH);
0222:                }
0223:
0224:                layeredPane = new JLayeredPane() {
0225:                    // hack: before each paint make sure the dragged components have
0226:                    // bounds set out of visible area (as they physically stay in their
0227:                    // container and the layout manager may lay them back if some
0228:                    // validation occurs)
0229:                    @Override
0230:                    protected void paintChildren(Graphics g) {
0231:                        handleLayer.maskDraggingComponents();
0232:                        super .paintChildren(g);
0233:                    }
0234:                };
0235:                layeredPane.setLayout(new OverlayLayout(layeredPane));
0236:                layeredPane.add(designPanel, new Integer(1000));
0237:                layeredPane.add(handleLayer, new Integer(1001));
0238:
0239:                updateAssistant();
0240:                settingsListener = new PreferenceChangeListener() {
0241:                    public void preferenceChange(PreferenceChangeEvent evt) {
0242:                        if (FormLoaderSettings.PROP_ASSISTANT_SHOWN.equals(evt
0243:                                .getKey())) {
0244:                            updateAssistant();
0245:                        }
0246:                    }
0247:
0248:                };
0249:                FormLoaderSettings.getPreferences()
0250:                        .addPreferenceChangeListener(settingsListener);
0251:
0252:                JScrollPane scrollPane = new JScrollPane(layeredPane);
0253:                scrollPane.setBorder(null); // disable border, winsys will handle borders itself
0254:                scrollPane.setViewportBorder(null); // disable also GTK L&F viewport border 
0255:                scrollPane.getVerticalScrollBar().setUnitIncrement(5); // Issue 50054
0256:                scrollPane.getHorizontalScrollBar().setUnitIncrement(5);
0257:                add(scrollPane, BorderLayout.CENTER);
0258:
0259:                explorerManager.setRootContext(formEditor.getFormRootNode());
0260:
0261:                if (!hasPropertyChangeListener) {
0262:                    addPropertyChangeListener("activatedNodes",
0263:                            new PropertyChangeListener() { // NOI18N
0264:                                public void propertyChange(
0265:                                        PropertyChangeEvent evt) {
0266:                                    try {
0267:                                        Lookup[] lookups = lookup
0268:                                                .getSubLookups();
0269:                                        Node[] oldNodes = (Node[]) evt
0270:                                                .getOldValue();
0271:                                        Node[] nodes = (Node[]) evt
0272:                                                .getNewValue();
0273:                                        Lookup lastLookup = lookups[lookups.length - 1];
0274:                                        Node delegate = formEditor
0275:                                                .getFormDataObject()
0276:                                                .getNodeDelegate();
0277:                                        if (!(lastLookup instanceof  NoNodeLookup)
0278:                                                && (oldNodes.length >= 1)
0279:                                                && (!oldNodes[0]
0280:                                                        .equals(delegate))) {
0281:                                            switchLookup();
0282:                                        } else if ((lastLookup instanceof  NoNodeLookup)
0283:                                                && (nodes.length == 0)) {
0284:                                            switchLookup();
0285:                                        }
0286:                                        List<Node> list = new ArrayList<Node>(
0287:                                                nodes.length);
0288:                                        for (int i = 0; i < nodes.length; i++) {
0289:                                            if ((nodes[i] != null)
0290:                                                    && (nodes[i] != delegate)) {
0291:                                                list.add(nodes[i]);
0292:                                            }
0293:                                        }
0294:                                        explorerManager
0295:                                                .setSelectedNodes(list
0296:                                                        .toArray(new Node[list
0297:                                                                .size()]));
0298:                                    } catch (PropertyVetoException ex) {
0299:                                        ex.printStackTrace();
0300:                                    }
0301:                                }
0302:                            });
0303:                    hasPropertyChangeListener = true;
0304:                }
0305:
0306:                if (formModelListener == null)
0307:                    formModelListener = new FormListener();
0308:                formModel.addFormModelListener(formModelListener);
0309:
0310:                replicator = new VisualReplicator(true, FormUtils
0311:                        .getViewConverters(), FormEditor
0312:                        .getBindingSupport(formModel));
0313:
0314:                resetTopDesignComponent(false);
0315:                handleLayer.setViewOnly(formModel.isReadOnly());
0316:
0317:                // Beans without layout model doesn't require layout designer
0318:                if (formModel.getLayoutModel() != null) {
0319:                    layoutDesigner = new LayoutDesigner(formModel
0320:                            .getLayoutModel(), new LayoutMapper());
0321:                }
0322:
0323:                updateWholeDesigner();
0324:
0325:                // not very nice hack - it's better FormEditorSupport has its
0326:                // listener registered after FormDesigner
0327:                formEditor.reinstallListener();
0328:
0329:                if (formEditor.getFormDesigner() == null) {
0330:                    // 70940: Make sure some form designer is registered
0331:                    formEditor.setFormDesigner(this );
0332:                }
0333:
0334:                //force the menu edit layer to be created
0335:                getMenuEditLayer();
0336:
0337:                // vlv: print
0338:                designPanel.putClientProperty(java.awt.print.Printable.class,
0339:                        ""); // NOI18N
0340:            }
0341:
0342:            void reset(FormEditor formEditor) {
0343:                if (initialized) {
0344:                    clearSelection();
0345:                }
0346:                initialized = false;
0347:
0348:                removeAll();
0349:
0350:                componentLayer = null;
0351:                handleLayer = null;
0352:                nonVisualTray = null;
0353:                layeredPane = null;
0354:                if (textEditLayer != null) {
0355:                    if (textEditLayer.isVisible()) {
0356:                        textEditLayer.finishEditing(false);
0357:                    }
0358:                    textEditLayer.removeFinishListener(getFinnishListener());
0359:                    textEditLayer = null;
0360:                }
0361:
0362:                if (menuEditLayer != null) {
0363:                    menuEditLayer = null;
0364:                }
0365:
0366:                if (formModel != null) {
0367:                    if (formModelListener != null) {
0368:                        formModel.removeFormModelListener(formModelListener);
0369:                    }
0370:                    if (settingsListener != null) {
0371:                        FormLoaderSettings.getPreferences()
0372:                                .removePreferenceChangeListener(
0373:                                        settingsListener);
0374:                    }
0375:                    topDesignComponent = null;
0376:                    formModel = null;
0377:                }
0378:
0379:                replicator = null;
0380:                layoutDesigner = null;
0381:
0382:                connectionSource = null;
0383:                connectionTarget = null;
0384:                this .formEditor = formEditor;
0385:            }
0386:
0387:            private void switchLookup() {
0388:                Lookup[] lookups = lookup.getSubLookups();
0389:                Lookup nodeLookup = formEditor.getFormDataObject()
0390:                        .getNodeDelegate().getLookup();
0391:                int index = lookups.length - 1;
0392:                if (lookups[index] instanceof  NoNodeLookup) {
0393:                    lookups[index] = nodeLookup;
0394:                } else {
0395:                    // should not affect selected nodes, but should provide cookies etc.
0396:                    lookups[index] = new NoNodeLookup(nodeLookup);
0397:                }
0398:                lookup.setSubLookups(lookups);
0399:            }
0400:
0401:            private void updateAssistant() {
0402:                if (FormLoaderSettings.getInstance().getAssistantShown()) {
0403:                    AssistantModel assistant = FormEditor
0404:                            .getAssistantModel(formModel);
0405:                    assistantView = new AssistantView(assistant);
0406:                    assistant.setContext("select"); // NOI18N
0407:                    add(assistantView, BorderLayout.NORTH);
0408:                } else {
0409:                    if (assistantView != null) {
0410:                        remove(assistantView);
0411:                        assistantView = null;
0412:                    }
0413:                }
0414:                revalidate();
0415:            }
0416:
0417:            // ------
0418:            // important getters
0419:
0420:            public FormModel getFormModel() {
0421:                return formModel;
0422:            }
0423:
0424:            public HandleLayer getHandleLayer() {
0425:                return handleLayer;
0426:            }
0427:
0428:            ComponentLayer getComponentLayer() {
0429:                return componentLayer;
0430:            }
0431:
0432:            NonVisualTray getNonVisualTray() {
0433:                return nonVisualTray;
0434:            }
0435:
0436:            FormToolBar getFormToolBar() {
0437:                return formToolBar;
0438:            }
0439:
0440:            public LayoutDesigner getLayoutDesigner() {
0441:                return layoutDesigner;
0442:            }
0443:
0444:            public FormEditor getFormEditor() {
0445:                return formEditor;
0446:            }
0447:
0448:            @Override
0449:            public javax.swing.Action[] getActions() {
0450:                Action[] actions = super .getActions();
0451:                SystemAction fsAction = SystemAction
0452:                        .get(FileSystemAction.class);
0453:                if (!Arrays.asList(actions).contains(fsAction)) {
0454:                    Action[] newActions = new Action[actions.length + 1];
0455:                    System.arraycopy(actions, 0, newActions, 0, actions.length);
0456:                    newActions[actions.length] = fsAction;
0457:                    actions = newActions;
0458:                }
0459:                return actions;
0460:            }
0461:
0462:            // ------------
0463:            // designer content
0464:
0465:            public Object getComponent(RADComponent metacomp) {
0466:                return replicator.getClonedComponent(metacomp.getId());
0467:            }
0468:
0469:            public Object getComponent(String componentId) {
0470:                return replicator.getClonedComponent(componentId);
0471:            }
0472:
0473:            public RADComponent getMetaComponent(Object comp) {
0474:                String id = replicator.getClonedComponentId(comp);
0475:                return id != null ? formModel.getMetaComponent(id) : null;
0476:            }
0477:
0478:            //    public RADComponent getMetaComponent(String componentId) {
0479:            //        return formModel.getMetaComponent(componentId);
0480:            //    }
0481:
0482:            public RADVisualComponent getTopDesignComponent() {
0483:                return topDesignComponent;
0484:            }
0485:
0486:            boolean isTopRADComponent() {
0487:                RADComponent topMetaComp = formModel.getTopRADComponent();
0488:                return topMetaComp != null && topMetaComp == topDesignComponent;
0489:            }
0490:
0491:            public void setTopDesignComponent(RADVisualComponent component,
0492:                    boolean update) {
0493:
0494:                highlightTopDesignComponentName(false);
0495:                // TODO need to remove bindings of the current cloned view (or clone bound components as well)
0496:                topDesignComponent = component;
0497:                highlightTopDesignComponentName(!isTopRADComponent());
0498:
0499:                FormDataObject formDO = formEditor.getFormDataObject();
0500:                if (formDO != null) {
0501:                    formDO.getFormEditorSupport().updateMVTCDisplayName();
0502:                }
0503:                if (update) {
0504:                    setSelectedComponent(topDesignComponent);
0505:                    updateWholeDesigner();
0506:                }
0507:            }
0508:
0509:            private void highlightTopDesignComponentName(boolean bl) {
0510:                if (topDesignComponent != null) {
0511:                    RADComponentNode node = topDesignComponent
0512:                            .getNodeReference();
0513:                    if (node != null) {
0514:                        node.highlightDisplayName(bl);
0515:                    }
0516:                }
0517:            }
0518:
0519:            public void resetTopDesignComponent(boolean update) {
0520:                RADComponent top = formModel.getTopRADComponent();
0521:                setTopDesignComponent(
0522:                        top instanceof  RADVisualComponent ? (RADVisualComponent) top
0523:                                : null, update);
0524:            }
0525:
0526:            /** Tests whether top designed container is some parent of given component
0527:             * (whether the component is in the tree under top designed container).
0528:             * 
0529:             * @param metacomp component.
0530:             * @return <code>true</code> if the component is in designer,
0531:             * returns <code>false</code> otherwise.
0532:             */
0533:            public boolean isInDesigner(RADVisualComponent metacomp) {
0534:                Object comp = replicator.getClonedComponent(metacomp);
0535:                return comp instanceof  Component ? componentLayer
0536:                        .isAncestorOf((Component) comp) : false;
0537:            }
0538:
0539:            void updateWholeDesigner() {
0540:                if (formModelListener != null)
0541:                    formModelListener.formChanged(null);
0542:            }
0543:
0544:            private void updateComponentLayer(final boolean fireChange) {
0545:                if (formModel == null) { // the form can be closed just after opened, before this gets called (#70439)
0546:                    return;
0547:                }
0548:                if (getLayoutDesigner() == null) {
0549:                    return;
0550:                }
0551:
0552:                // Ensure that the components are laid out
0553:                componentLayer.revalidate(); // Add componentLayer among components to validate
0554:                RepaintManager.currentManager(componentLayer)
0555:                        .validateInvalidComponents();
0556:
0557:                LayoutModel layoutModel = formModel.getLayoutModel();
0558:                if (getLayoutDesigner().updateCurrentState() && fireChange) {
0559:                    formModel.fireFormChanged(true); // hack: to regenerate code once again
0560:                }
0561:
0562:                layoutModel.endUndoableEdit();
0563:                updateResizabilityActions();
0564:                componentLayer.repaint();
0565:            }
0566:
0567:            // updates layout of a container in designer to match current model - used
0568:            // by HandleLayer when canceling component dragging
0569:            void updateContainerLayout(RADVisualContainer metacont) {
0570:                replicator.updateContainerLayout(metacont);
0571:                componentLayer.revalidate();
0572:                componentLayer.repaint();
0573:            }
0574:
0575:            public static Container createFormView(final RADComponent metacomp,
0576:                    final FormLAF.PreviewInfo previewInfo) throws Exception {
0577:                Container result = null;
0578:                FormModel formModel = metacomp.getFormModel();
0579:                FileObject formFile = FormEditor.getFormDataObject(formModel)
0580:                        .getFormFile();
0581:                final ClassLoader classLoader = ClassPathUtils
0582:                        .getProjectClassLoader(formFile);
0583:                Locale defaultLocale = switchToDesignLocale(formModel);
0584:                try {
0585:                    FormLAF.setUsePreviewDefaults(classLoader, previewInfo);
0586:                    result = (Container) FormLAF.executeWithLookAndFeel(
0587:                            formModel, new Mutex.ExceptionAction() {
0588:                                public Object run() throws Exception {
0589:                                    VisualReplicator r = new VisualReplicator(
0590:                                            false, FormUtils
0591:                                                    .getViewConverters(), null);
0592:                                    r.setTopMetaComponent(metacomp);
0593:                                    Object container = r.createClone();
0594:                                    if (container instanceof  RootPaneContainer) {
0595:                                        JRootPane rootPane = ((RootPaneContainer) container)
0596:                                                .getRootPane();
0597:                                        JLayeredPane newPane = new JLayeredPane() {
0598:                                            @Override
0599:                                            public void paint(Graphics g) {
0600:                                                try {
0601:                                                    FormLAF
0602:                                                            .setUsePreviewDefaults(
0603:                                                                    classLoader,
0604:                                                                    previewInfo);
0605:                                                    super .paint(g);
0606:                                                } finally {
0607:                                                    FormLAF
0608:                                                            .setUsePreviewDefaults(
0609:                                                                    null, null);
0610:                                                }
0611:                                            }
0612:                                        };
0613:                                        // Copy components from the original layered pane into our one
0614:                                        JLayeredPane oldPane = rootPane
0615:                                                .getLayeredPane();
0616:                                        Component[] comps = oldPane
0617:                                                .getComponents();
0618:                                        for (int i = 0; i < comps.length; i++) {
0619:                                            newPane
0620:                                                    .add(
0621:                                                            comps[i],
0622:                                                            Integer
0623:                                                                    .valueOf(oldPane
0624:                                                                            .getLayer(comps[i])));
0625:                                        }
0626:                                        // Use our layered pane that knows about LAF switching
0627:                                        rootPane.setLayeredPane(newPane);
0628:                                        // Make the glass pane visible to force repaint of the whole layered pane
0629:                                        rootPane.getGlassPane()
0630:                                                .setVisible(true);
0631:                                        // Mark it as design preview
0632:                                        rootPane.putClientProperty(
0633:                                                "designPreview", Boolean.TRUE); // NOI18N
0634:                                    } // else AWT Frame - we don't care that the L&F of the Swing
0635:                                    // components may not look good - it is a strange use case
0636:                                    return container;
0637:                                }
0638:                            }
0639:
0640:                    );
0641:                } finally {
0642:                    FormLAF.setUsePreviewDefaults(null, null);
0643:                    if (defaultLocale != null)
0644:                        Locale.setDefault(defaultLocale);
0645:                }
0646:                return result;
0647:            }
0648:
0649:            private static Locale switchToDesignLocale(FormModel formModel) {
0650:                Locale defaultLocale = null;
0651:                String locale = FormEditor.getResourceSupport(formModel)
0652:                        .getDesignLocale();
0653:                if (locale != null && !locale.equals("")) { // NOI18N
0654:                    defaultLocale = Locale.getDefault();
0655:
0656:                    String[] parts = locale.split("_"); // NOI18N
0657:                    int i = 0;
0658:                    if ("".equals(parts[i])) // NOI18N
0659:                        i++;
0660:                    String language = i < parts.length ? parts[i++] : null;
0661:                    String country = i < parts.length ? parts[i++] : ""; // NOI18N
0662:                    String variant = i < parts.length ? parts[i] : ""; // NOI18N
0663:                    if (language != null)
0664:                        Locale
0665:                                .setDefault(new Locale(language, country,
0666:                                        variant));
0667:                }
0668:                return defaultLocale;
0669:            }
0670:
0671:            Component getTopDesignComponentView() {
0672:                return topDesignComponent != null ? (Component) replicator
0673:                        .getClonedComponent(topDesignComponent) : null;
0674:            }
0675:
0676:            // NOTE: does not create a new Point instance
0677:            Point pointFromComponentToHandleLayer(Point p, Component sourceComp) {
0678:                Component commonParent = layeredPane;
0679:                Component comp = sourceComp;
0680:                while (comp != commonParent) {
0681:                    p.x += comp.getX();
0682:                    p.y += comp.getY();
0683:                    comp = comp.getParent();
0684:                }
0685:                comp = handleLayer;
0686:                while (comp != commonParent) {
0687:                    p.x -= comp.getX();
0688:                    p.y -= comp.getY();
0689:                    comp = comp.getParent();
0690:                }
0691:                return p;
0692:            }
0693:
0694:            // NOTE: does not create a new Point instance
0695:            Point pointFromHandleToComponentLayer(Point p, Component targetComp) {
0696:                Component commonParent = layeredPane;
0697:                Component comp = handleLayer;
0698:                while (comp != commonParent) {
0699:                    p.x += comp.getX();
0700:                    p.y += comp.getY();
0701:                    comp = comp.getParent();
0702:                }
0703:                comp = targetComp;
0704:                while (comp != commonParent) {
0705:                    p.x -= comp.getX();
0706:                    p.y -= comp.getY();
0707:                    comp = comp.getParent();
0708:                }
0709:                return p;
0710:            }
0711:
0712:            boolean isCoordinatesRoot(Component comp) {
0713:                return (layeredPane == comp);
0714:            }
0715:
0716:            private Rectangle componentBoundsToTop(Component component) {
0717:                if (component == null)
0718:                    return null;
0719:
0720:                Component top = getTopDesignComponentView();
0721:
0722:                int dx = 0;
0723:                int dy = 0;
0724:
0725:                if (component != top) {
0726:                    Component comp = component.getParent();
0727:                    while (comp != top) {
0728:                        if (comp == null) {
0729:                            break;//return null;
0730:                        }
0731:                        dx += comp.getX();
0732:                        dy += comp.getY();
0733:                        comp = comp.getParent();
0734:                    }
0735:                } else {
0736:                    dx = -top.getX();
0737:                    dy = -top.getY();
0738:                }
0739:
0740:                Rectangle bounds = component.getBounds();
0741:                bounds.x += dx;
0742:                bounds.y += dy;
0743:
0744:                return bounds;
0745:            }
0746:
0747:            // -------
0748:            // designer mode
0749:
0750:            void setDesignerMode(int mode) {
0751:                formToolBar.updateDesignerMode(mode);
0752:
0753:                if (mode == designerMode || !initialized) {
0754:                    return;
0755:                }
0756:
0757:                if (mode == MODE_ADD) {
0758:                    PaletteItem pitem = PaletteUtils.getSelectedItem();
0759:                    if ((pitem != null)
0760:                            && PaletteItem.TYPE_CHOOSE_BEAN.equals(pitem
0761:                                    .getExplicitComponentType())
0762:                            && ComponentInspector.getInstance()
0763:                                    .getFocusedForm() == formEditor) {
0764:                        NotifyDescriptor.InputLine desc = new NotifyDescriptor.InputLine(
0765:                                FormUtils.getBundleString("MSG_Choose_Bean"), // NOI18N
0766:                                FormUtils.getBundleString("TITLE_Choose_Bean")); // NOI18N
0767:                        DialogDisplayer.getDefault().notify(desc);
0768:                        if (NotifyDescriptor.OK_OPTION.equals(desc.getValue())) {
0769:                            pitem.setClassFromCurrentProject(desc
0770:                                    .getInputText(), formEditor
0771:                                    .getFormDataObject().getPrimaryFile());
0772:                        } else {
0773:                            toggleSelectionMode();
0774:                            return;
0775:                        }
0776:                    }
0777:                }
0778:
0779:                designerMode = mode;
0780:
0781:                resetConnection();
0782:                if (mode == MODE_CONNECT)
0783:                    clearSelection();
0784:
0785:                handleLayer.endDragging(null);
0786:                AssistantModel aModel = FormEditor.getAssistantModel(formModel);
0787:                switch (mode) {
0788:                case MODE_CONNECT:
0789:                    aModel.setContext("connectSource");
0790:                    break; // NOI18N
0791:                case MODE_SELECT:
0792:                    aModel.setContext("select");
0793:                    break; // NOI18N
0794:                }
0795:            }
0796:
0797:            public int getDesignerMode() {
0798:                return designerMode;
0799:            }
0800:
0801:            public void toggleSelectionMode() {
0802:                setDesignerMode(MODE_SELECT);
0803:                PaletteUtils.clearPaletteSelection();
0804:            }
0805:
0806:            void toggleConnectionMode() {
0807:                setDesignerMode(MODE_CONNECT);
0808:                PaletteUtils.clearPaletteSelection();
0809:            }
0810:
0811:            void toggleAddMode() {
0812:                setDesignerMode(MODE_ADD);
0813:                PaletteUtils.clearPaletteSelection();
0814:            }
0815:
0816:            // -------
0817:            // designer size
0818:
0819:            Dimension getDesignerSize() {
0820:                return componentLayer.getDesignerSize();
0821:            }
0822:
0823:            void setDesignerSize(Dimension size, Dimension oldSize) {
0824:                if (topDesignComponent instanceof  RADVisualFormContainer) {
0825:                    ((RADVisualFormContainer) topDesignComponent)
0826:                            .setDesignerSize(size);
0827:                } else if (topDesignComponent != null) {
0828:                    if (topDesignComponent == formModel.getTopRADComponent()) {
0829:                        oldSize = (Dimension) topDesignComponent
0830:                                .getAuxValue(PROP_DESIGNER_SIZE);
0831:                        topDesignComponent
0832:                                .setAuxValue(PROP_DESIGNER_SIZE, size);
0833:                    }
0834:                    if (oldSize == null)
0835:                        oldSize = getDesignerSize();
0836:
0837:                    getFormModel().fireSyntheticPropertyChanged(
0838:                            topDesignComponent,
0839:                            FormDesigner.PROP_DESIGNER_SIZE, oldSize, size);
0840:                }
0841:            }
0842:
0843:            public void resetDesignerSize() {
0844:                setDesignerSize(null, null);
0845:            }
0846:
0847:            void storeDesignerSize(Dimension size) { // without firing model change
0848:                if (topDesignComponent instanceof  RADVisualFormContainer)
0849:                    ((RADVisualFormContainer) topDesignComponent)
0850:                            .setDesignerSizeImpl(size);
0851:                else if (topDesignComponent == formModel.getTopRADComponent()) // root not a visual container
0852:                    topDesignComponent.setAuxValue(PROP_DESIGNER_SIZE, size);
0853:            }
0854:
0855:            private void setupDesignerSize() {
0856:                Dimension size = null;
0857:                RADVisualFormContainer formCont = topDesignComponent instanceof  RADVisualFormContainer ? (RADVisualFormContainer) topDesignComponent
0858:                        : null;
0859:                if (formCont == null
0860:                        || formCont.hasExplicitSize()
0861:                        || !RADVisualContainer
0862:                                .isFreeDesignContainer(topDesignComponent)) { // try to obtain stored designer size
0863:                    if (formCont != null)
0864:                        size = formCont.getDesignerSize();
0865:                    if (size == null)
0866:                        size = (Dimension) topDesignComponent
0867:                                .getAuxValue(PROP_DESIGNER_SIZE);
0868:                    if (size == null
0869:                            && (!formModel.isFreeDesignDefaultLayout() || topDesignComponent == formModel
0870:                                    .getTopRADComponent())) { // use default size if no stored size is available and
0871:                        // old layout form or top design comp is root in the form (but not a container)
0872:                        size = new Dimension(400, 300);
0873:                    }
0874:                }
0875:
0876:                Dimension setSize = componentLayer.setDesignerSize(size); // null computes preferred size
0877:                storeDesignerSize(setSize);
0878:            }
0879:
0880:            private void checkDesignerSize() {
0881:                if ((formModel.isFreeDesignDefaultLayout() || RADVisualContainer
0882:                        .isFreeDesignContainer(topDesignComponent))
0883:                        && topDesignComponent instanceof  RADVisualComponent
0884:                        && (!(topDesignComponent instanceof  RADVisualFormContainer) || !((RADVisualFormContainer) topDesignComponent)
0885:                                .hasExplicitSize())) { // new layout container defining designer size
0886:                    // designer size not defined explicitly - check minimum size
0887:                    Component topComp = getTopDesignComponentView();
0888:                    Component topCont = null;
0889:                    if (topDesignComponent instanceof  RADVisualContainer) {
0890:                        topCont = ((RADVisualContainer) topDesignComponent)
0891:                                .getContainerDelegate(topComp);
0892:                    }
0893:                    if (topCont == null) {
0894:                        topCont = topComp;
0895:                    }
0896:                    // can't rely on minimum size of the container wrap - e.g. menu bar
0897:                    // returns wrong min height
0898:                    int wDiff = topComp.getWidth() - topCont.getWidth();
0899:                    int hDiff = topComp.getHeight() - topCont.getHeight();
0900:
0901:                    Dimension designerSize = new Dimension(getDesignerSize());
0902:                    designerSize.width -= wDiff;
0903:                    designerSize.height -= hDiff;
0904:                    Dimension minSize = topCont.getMinimumSize();
0905:                    boolean corrected = false;
0906:                    if (designerSize.width < minSize.width) {
0907:                        designerSize.width = minSize.width;
0908:                        corrected = true;
0909:                    }
0910:                    if (designerSize.height < minSize.height) {
0911:                        designerSize.height = minSize.height;
0912:                        corrected = true;
0913:                    }
0914:
0915:                    if (corrected) {
0916:                        designerSize.width += wDiff;
0917:                        designerSize.height += hDiff;
0918:
0919:                        // hack: we need the size correction in the undo/redo
0920:                        if (formModel.isCompoundEditInProgress()) {
0921:                            FormModelEvent ev = new FormModelEvent(formModel,
0922:                                    FormModelEvent.SYNTHETIC_PROPERTY_CHANGED);
0923:                            ev.setComponentAndContainer(topDesignComponent,
0924:                                    null);
0925:                            ev.setProperty(PROP_DESIGNER_SIZE,
0926:                                    getDesignerSize(), designerSize);
0927:                            formModel.addUndoableEdit(ev.getUndoableEdit());
0928:                        }
0929:
0930:                        componentLayer.setDesignerSize(designerSize);
0931:                        storeDesignerSize(designerSize);
0932:                    }
0933:                }
0934:            }
0935:
0936:            // ---------
0937:            // components selection
0938:
0939:            public java.util.List<RADComponent> getSelectedComponents() {
0940:                return selectedComponents;
0941:            }
0942:
0943:            Node[] getSelectedComponentNodes() {
0944:                List<Node> selectedNodes = new ArrayList<Node>(
0945:                        selectedComponents.size());
0946:                for (RADComponent c : selectedComponents) {
0947:                    if (c.getNodeReference() != null) { // issue 126192 workaround
0948:                        selectedNodes.add(c.getNodeReference());
0949:                    }
0950:                }
0951:                return selectedNodes.toArray(new Node[selectedNodes.size()]);
0952:            }
0953:
0954:            java.util.List<RADComponent> getSelectedLayoutComponents() {
0955:                return selectedLayoutComponents;
0956:            }
0957:
0958:            boolean isComponentSelected(RADComponent metacomp) {
0959:                return selectedComponents.contains(metacomp);
0960:            }
0961:
0962:            public void setSelectedComponent(RADComponent metacomp) {
0963:                clearSelectionImpl();
0964:                addComponentToSelectionImpl(metacomp);
0965:                repaintSelection();
0966:                updateComponentInspector();
0967:            }
0968:
0969:            public void setSelectedComponents(RADComponent[] metacomps) {
0970:                clearSelectionImpl();
0971:
0972:                for (int i = 0; i < metacomps.length; i++)
0973:                    addComponentToSelectionImpl(metacomps[i]);
0974:
0975:                repaintSelection();
0976:                updateComponentInspector();
0977:            }
0978:
0979:            void setSelectedNode(FormNode node) {
0980:                if (node instanceof  RADComponentNode)
0981:                    setSelectedComponent(((RADComponentNode) node)
0982:                            .getRADComponent());
0983:                else {
0984:                    clearSelectionImpl();
0985:                    repaintSelection();
0986:
0987:                    ComponentInspector ci = ComponentInspector.getInstance();
0988:                    if (ci.getFocusedForm() != formEditor)
0989:                        return;
0990:
0991:                    Node[] selectedNodes = new Node[] { node };
0992:                    try {
0993:                        ci.setSelectedNodes(selectedNodes, formEditor);
0994:                        // sets also the activated nodes (both for ComponentInspector
0995:                        // and FormDesigner)
0996:                    } catch (java.beans.PropertyVetoException ex) {
0997:                        ex.printStackTrace();
0998:                    }
0999:                }
1000:            }
1001:
1002:            public void addComponentToSelection(RADComponent metacomp) {
1003:                addComponentToSelectionImpl(metacomp);
1004:                repaintSelection();
1005:                updateComponentInspector();
1006:            }
1007:
1008:            void addComponentsToSelection(RADComponent[] metacomps) {
1009:                for (int i = 0; i < metacomps.length; i++)
1010:                    addComponentToSelectionImpl(metacomps[i]);
1011:
1012:                repaintSelection();
1013:                updateComponentInspector();
1014:            }
1015:
1016:            void removeComponentFromSelection(RADComponent metacomp) {
1017:                removeComponentFromSelectionImpl(metacomp);
1018:                repaintSelection();
1019:                updateComponentInspector();
1020:            }
1021:
1022:            public void clearSelection() {
1023:                clearSelectionImpl();
1024:                repaintSelection();
1025:                updateComponentInspector();
1026:            }
1027:
1028:            void addComponentToSelectionImpl(RADComponent metacomp) {
1029:                if (metacomp != null) {
1030:                    selectedComponents.add(metacomp);
1031:                    RADVisualComponent layoutComponent = componentToLayoutComponent(metacomp);
1032:                    if (layoutComponent != null) {
1033:                        selectedLayoutComponents.add(layoutComponent);
1034:                        ensureComponentIsShown((RADVisualComponent) metacomp);
1035:                        selectionChanged();
1036:                    }
1037:                }
1038:            }
1039:
1040:            RADVisualComponent componentToLayoutComponent(RADComponent metacomp) {
1041:                if (metacomp instanceof  RADVisualComponent) {
1042:                    RADVisualComponent visualComp = (RADVisualComponent) metacomp;
1043:                    if (!visualComp.isMenuComponent()) {
1044:                        RADVisualContainer metacont = visualComp
1045:                                .getParentContainer();
1046:                        if ((metacont != null)
1047:                                && JScrollPane.class.isAssignableFrom(metacont
1048:                                        .getBeanInstance().getClass())
1049:                                && isInDesigner(metacont)) { // substitute with scroll pane...
1050:                            return metacont;
1051:                        }
1052:                        // otherwise just check if it is visible in the designer
1053:                        return isInDesigner(visualComp) ? visualComp : null;
1054:                    }
1055:                }
1056:                return null;
1057:            }
1058:
1059:            void removeComponentFromSelectionImpl(RADComponent metacomp) {
1060:                selectedComponents.remove(metacomp);
1061:                selectedLayoutComponents.remove(metacomp);
1062:                selectionChanged();
1063:            }
1064:
1065:            void clearSelectionImpl() {
1066:                selectedComponents.clear();
1067:                selectedLayoutComponents.clear();
1068:                selectionChanged();
1069:            }
1070:
1071:            void selectionChanged() {
1072:                updateDesignerActions();
1073:                updateResizabilityActions();
1074:                updateAssistantContext();
1075:            }
1076:
1077:            void repaintSelection() {
1078:                handleLayer.repaint();
1079:            }
1080:
1081:            private void updateDesignerActions() {
1082:                Collection selectedIds = selectedLayoutComponentIds();
1083:                boolean enabled = false;
1084:                if (selectedIds.size() >= 2) {
1085:                    RADComponent parent = commonParent(selectedIds);
1086:                    if (parent != null) {
1087:                        LayoutModel layoutModel = formModel.getLayoutModel();
1088:                        LayoutComponent parentLC = layoutModel
1089:                                .getLayoutComponent(parent.getId());
1090:                        if ((parentLC != null)
1091:                                && (parentLC.isLayoutContainer())) {
1092:                            enabled = true;
1093:                        }
1094:                    }
1095:                }
1096:                Iterator iter = getDesignerActions(true).iterator();
1097:                while (iter.hasNext()) {
1098:                    Action action = (Action) iter.next();
1099:                    action.setEnabled(enabled);
1100:                }
1101:            }
1102:
1103:            void setResizabilityButtons(JToggleButton[] buttons) {
1104:                this .resizabilityButtons = buttons;
1105:            }
1106:
1107:            public JToggleButton[] getResizabilityButtons() {
1108:                return resizabilityButtons;
1109:            }
1110:
1111:            public void updateResizabilityActions() {
1112:                Collection componentIds = componentIds();
1113:                LayoutModel layoutModel = getFormModel().getLayoutModel();
1114:                LayoutDesigner layoutDesigner = getLayoutDesigner();
1115:                Iterator iter = componentIds.iterator();
1116:                boolean resizable[] = new boolean[2];
1117:                boolean nonResizable[] = new boolean[2];
1118:                while (iter.hasNext()) {
1119:                    String id = (String) iter.next();
1120:                    LayoutComponent comp = layoutModel.getLayoutComponent(id);
1121:                    for (int i = 0; i < 2; i++) {
1122:                        if (layoutDesigner.isComponentResizing(comp,
1123:                                (i == 0) ? LayoutConstants.HORIZONTAL
1124:                                        : LayoutConstants.VERTICAL)) {
1125:                            resizable[i] = true;
1126:                        } else {
1127:                            nonResizable[i] = true;
1128:                        }
1129:                    }
1130:                }
1131:                for (int i = 0; i < 2; i++) {
1132:                    boolean match;
1133:                    boolean miss;
1134:                    match = resizable[i];
1135:                    miss = nonResizable[i];
1136:                    getResizabilityButtons()[i].setSelected(!miss && match);
1137:                    ((ResizabilityAction) getResizabilityActions().toArray()[i])
1138:                            .setEnabled(match || miss);
1139:                    //                getResizabilityButtons()[i].setPaintDisabledIcon(match && miss);
1140:                }
1141:            }
1142:
1143:            private void updateAssistantContext() {
1144:                String context = null;
1145:                String additionalCtx = null;
1146:                List<RADComponent> selComps = getSelectedComponents();
1147:                int selCount = selComps.size();
1148:                if (selCount > 0) {
1149:                    RADComponent metacomp = selComps.get(0);
1150:                    if (layoutDesigner != null
1151:                            && layoutDesigner.isUnplacedComponent(metacomp
1152:                                    .getId())) {
1153:                        if (selCount > 1) {
1154:                            List<String> ids = new ArrayList<String>(selCount);
1155:                            for (RADComponent c : selComps) {
1156:                                ids.add(c.getId());
1157:                            }
1158:                            if (layoutDesigner.getDraggableComponents(ids)
1159:                                    .size() == selCount) {
1160:                                // all selected components are "unplaced" in the same container
1161:                                context = "unplacedComponents1"; // NOI18N
1162:                                additionalCtx = "unplacedComponents2"; // NOI18N
1163:                            }
1164:                        } else {
1165:                            context = "unplacedComponent1"; // NOI18N
1166:                            additionalCtx = "unplacedComponent2"; // NOI18N
1167:                        }
1168:                    }
1169:                    if (selCount == 1 && context == null) {
1170:                        Object bean = metacomp.getBeanInstance();
1171:                        if (bean instanceof  JTabbedPane) {
1172:                            JTabbedPane pane = (JTabbedPane) bean;
1173:                            int count = pane.getTabCount();
1174:                            switch (count) {
1175:                            case 0:
1176:                                context = "tabbedPaneEmpty";
1177:                                break; // NOI18N
1178:                            case 1:
1179:                                context = "tabbedPaneOne";
1180:                                break; // NOI18N
1181:                            default:
1182:                                context = "tabbedPane";
1183:                                break; // NOI18N
1184:                            }
1185:                        } else if (bean instanceof  JRadioButton) {
1186:                            Node.Property property = metacomp
1187:                                    .getPropertyByName("buttonGroup"); // NOI18N
1188:                            try {
1189:                                if ((property != null)
1190:                                        && (property.getValue() == null)) {
1191:                                    context = "buttonGroup"; // NOI18N
1192:                                }
1193:                            } catch (Exception ex) {
1194:                                ex.printStackTrace();
1195:                            }
1196:                        } else if ((bean instanceof  JPanel)
1197:                                && (getTopDesignComponent() != metacomp)
1198:                                && (Math.random() < 0.2)) {
1199:                            context = "designThisContainer"; // NOI18N
1200:                        } else if ((bean instanceof  JComboBox)
1201:                                && (Math.random() < 0.4)) {
1202:                            context = "comboBoxModel"; // NOI18N
1203:                        } else if ((bean instanceof  JList)
1204:                                && (Math.random() < 0.4)) {
1205:                            context = "listModel"; // NOI18N
1206:                        } else if ((bean instanceof  JTable)
1207:                                && (Math.random() < 0.4)) {
1208:                            context = "tableModel"; // NOI18N
1209:                        } else if (bean instanceof  JScrollPane) {
1210:                            JScrollPane scrollPane = (JScrollPane) bean;
1211:                            if ((scrollPane.getViewport() != null)
1212:                                    && (scrollPane.getViewport().getView() == null)) {
1213:                                context = "scrollPaneEmpty"; // NOI18N
1214:                            } else if (Math.random() < 0.5) {
1215:                                context = "scrollPane"; // NOI18N
1216:                            }
1217:                        }
1218:                    }
1219:                }
1220:                if (context == null) {
1221:                    context = "select"; // NOI18N
1222:                }
1223:                FormEditor.getAssistantModel(formModel).setContext(context,
1224:                        additionalCtx);
1225:            }
1226:
1227:            /** Finds out what component follows after currently selected component
1228:             * when TAB (forward true) or Shift+TAB (forward false) is pressed. 
1229:             * @return the next or previous component for selection
1230:             */
1231:            RADComponent getNextVisualComponent(boolean forward) {
1232:                RADComponent currentComp = null;
1233:                int n = selectedComponents.size();
1234:                if (n > 0) {
1235:                    if (n > 1)
1236:                        return null;
1237:                    RADComponent sel = selectedComponents.get(0);
1238:                    if (sel instanceof  RADVisualComponent) {
1239:                        currentComp = sel;
1240:                    } else {
1241:                        return null;
1242:                    }
1243:                }
1244:
1245:                return getNextVisualComponent(currentComp, forward);
1246:            }
1247:
1248:            /** @return the next or prevoius component to component comp
1249:             */
1250:            RADComponent getNextVisualComponent(RADComponent comp,
1251:                    boolean forward) {
1252:                if (comp == null)
1253:                    return topDesignComponent;
1254:                if (getComponent(comp) == null)
1255:                    return null;
1256:
1257:                RADVisualContainer cont;
1258:                RADComponent[] subComps;
1259:
1260:                if (forward) {
1261:                    // try the first sub-component
1262:                    subComps = getVisualSubComponents(comp);
1263:                    if (subComps.length > 0) {
1264:                        return subComps[0];
1265:                    }
1266:
1267:                    // try the next component (or the next of the parent then)
1268:                    if (comp == topDesignComponent)
1269:                        return topDesignComponent;
1270:                    cont = (RADVisualContainer) comp.getParentComponent();
1271:                    if (cont == null) {
1272:                        return null;
1273:                    }
1274:                    int i = cont.getIndexOf(comp);
1275:                    while (i >= 0) {
1276:                        subComps = cont.getSubComponents();
1277:                        if (i + 1 < subComps.length)
1278:                            return subComps[i + 1];
1279:
1280:                        if (cont == topDesignComponent)
1281:                            break;
1282:                        comp = cont; // one level up
1283:                        cont = (RADVisualContainer) comp.getParentComponent();
1284:                        if (cont == null)
1285:                            return null; // should not happen
1286:                        i = cont.getIndexOf(comp);
1287:                    }
1288:
1289:                    return topDesignComponent;
1290:                } else { // backward
1291:                    // take the previuos component
1292:                    if (comp != topDesignComponent) {
1293:                        cont = (RADVisualContainer) comp.getParentComponent();
1294:                        if (cont == null) {
1295:                            return null;
1296:                        }
1297:                        int i = cont.getIndexOf(comp);
1298:                        if (i >= 0) { // should be always true
1299:                            if (i == 0)
1300:                                return cont; // the opposite to the 1st forward step
1301:
1302:                            subComps = cont.getSubComponents();
1303:                            comp = subComps[i - 1];
1304:                        } else
1305:                            comp = topDesignComponent;
1306:                    }
1307:
1308:                    // find the last subcomponent of it
1309:                    do {
1310:                        subComps = getVisualSubComponents(comp);
1311:                        if (subComps.length > 0) {
1312:                            comp = subComps[subComps.length - 1];
1313:                            continue;
1314:                        } else {
1315:                            break;
1316:                        }
1317:                    } while (true);
1318:                    return comp;
1319:                }
1320:            }
1321:
1322:            private RADComponent[] getVisualSubComponents(RADComponent metacomp) {
1323:                return metacomp instanceof  RADVisualContainer ? ((RADVisualContainer) metacomp)
1324:                        .getSubComponents()
1325:                        : new RADComponent[0];
1326:                // TBD components set as properties
1327:            }
1328:
1329:            /**
1330:             * Aligns selected components in the specified direction.
1331:             *
1332:             * @param closed determines if closed group should be created.
1333:             * @param dimension dimension to align in.
1334:             * @param alignment requested alignment.
1335:             */
1336:            void align(boolean closed, int dimension, int alignment) {
1337:                // Check that the action is enabled
1338:                Action action = null;
1339:                Iterator iter = getDesignerActions(true).iterator();
1340:                while (iter.hasNext()) {
1341:                    Action candidate = (Action) iter.next();
1342:                    if (candidate instanceof  AlignAction) {
1343:                        AlignAction alignCandidate = (AlignAction) candidate;
1344:                        if ((alignCandidate.getAlignment() == alignment)
1345:                                && (alignCandidate.getDimension() == dimension)) {
1346:                            action = alignCandidate;
1347:                            break;
1348:                        }
1349:                    }
1350:                }
1351:                if ((action == null) || (!action.isEnabled())) {
1352:                    return;
1353:                }
1354:                Collection selectedIds = selectedLayoutComponentIds();
1355:                RADComponent parent = commonParent(selectedIds);
1356:                LayoutModel layoutModel = formModel.getLayoutModel();
1357:                Object layoutUndoMark = layoutModel.getChangeMark();
1358:                javax.swing.undo.UndoableEdit ue = layoutModel
1359:                        .getUndoableEdit();
1360:                boolean autoUndo = true;
1361:                try {
1362:                    getLayoutDesigner().align(selectedIds, closed, dimension,
1363:                            alignment);
1364:                    autoUndo = false;
1365:                } finally {
1366:                    formModel.fireContainerLayoutChanged(
1367:                            (RADVisualContainer) parent, null, null, null);
1368:                    if (!layoutUndoMark.equals(layoutModel.getChangeMark())) {
1369:                        formModel.addUndoableEdit(ue);
1370:                    }
1371:                    if (autoUndo) {
1372:                        formModel.forceUndoOfCompoundEdit();
1373:                    }
1374:                }
1375:            }
1376:
1377:            /**
1378:             * Returns designer actions (they will be displayed in toolbar).
1379:             *
1380:             * @param forToolbar determines whether the method should return
1381:             * all designer actions or just the subset for the form toolbar.
1382:             * @return <code>Collection</code> of <code>Action</code> objects.
1383:             */
1384:            public Collection<Action> getDesignerActions(boolean forToolbar) {
1385:                if (designerActions == null) {
1386:                    designerActions = new LinkedList<Action>();
1387:                    // Grouping actions
1388:                    designerActions.add(new AlignAction(
1389:                            LayoutConstants.HORIZONTAL,
1390:                            LayoutConstants.LEADING, true));
1391:                    designerActions.add(new AlignAction(
1392:                            LayoutConstants.HORIZONTAL,
1393:                            LayoutConstants.TRAILING, true));
1394:                    designerActions.add(new AlignAction(
1395:                            LayoutConstants.HORIZONTAL, LayoutConstants.CENTER,
1396:                            true));
1397:                    designerActions.add(new AlignAction(
1398:                            LayoutConstants.VERTICAL, LayoutConstants.LEADING,
1399:                            true));
1400:                    designerActions.add(new AlignAction(
1401:                            LayoutConstants.VERTICAL, LayoutConstants.TRAILING,
1402:                            true));
1403:                    designerActions.add(new AlignAction(
1404:                            LayoutConstants.VERTICAL, LayoutConstants.CENTER,
1405:                            true));
1406:                    // Align actions
1407:                    designerActions.add(new AlignAction(
1408:                            LayoutConstants.HORIZONTAL,
1409:                            LayoutConstants.LEADING, false));
1410:                    designerActions.add(new AlignAction(
1411:                            LayoutConstants.HORIZONTAL,
1412:                            LayoutConstants.TRAILING, false));
1413:                    designerActions.add(new AlignAction(
1414:                            LayoutConstants.VERTICAL, LayoutConstants.LEADING,
1415:                            false));
1416:                    designerActions.add(new AlignAction(
1417:                            LayoutConstants.VERTICAL, LayoutConstants.TRAILING,
1418:                            false));
1419:                }
1420:                return forToolbar ? designerActions.subList(0, 6)
1421:                        : designerActions;
1422:            }
1423:
1424:            public Collection<Action> getResizabilityActions() {
1425:                if (resizabilityActions == null) {
1426:                    resizabilityActions = new LinkedList<Action>();
1427:                    resizabilityActions.add(new ResizabilityAction(
1428:                            LayoutConstants.HORIZONTAL));
1429:                    resizabilityActions.add(new ResizabilityAction(
1430:                            LayoutConstants.VERTICAL));
1431:                }
1432:                return resizabilityActions;
1433:            }
1434:
1435:            /**
1436:             * Returns collection of ids of the selected layout components.
1437:             *
1438:             * @return <code>Collection</code> of <code>String</code> objects.
1439:             */
1440:            Collection<String> selectedLayoutComponentIds() {
1441:                Iterator metacomps = getSelectedLayoutComponents().iterator();
1442:                Collection<String> selectedIds = new LinkedList<String>();
1443:                while (metacomps.hasNext()) {
1444:                    RADComponent metacomp = (RADComponent) metacomps.next();
1445:                    selectedIds.add(metacomp.getId());
1446:                }
1447:                return selectedIds;
1448:            }
1449:
1450:            /**
1451:             * Checks whether the given components are in the same containter.
1452:             *
1453:             * @param compIds <code>Collection</code> of component IDs.
1454:             * @return common container parent or <code>null</code>
1455:             * if the components are not from the same container.
1456:             */
1457:            private RADComponent commonParent(Collection compIds) {
1458:                RADComponent parent = null;
1459:                Iterator iter = compIds.iterator();
1460:                FormModel formModel = getFormModel();
1461:                while (iter.hasNext()) {
1462:                    String compId = (String) iter.next();
1463:                    RADComponent metacomp = formModel.getMetaComponent(compId);
1464:                    RADComponent metacont = metacomp.getParentComponent();
1465:                    if (parent == null) {
1466:                        parent = metacont;
1467:                    }
1468:                    if ((metacont == null) || (parent != metacont)) {
1469:                        return null;
1470:                    }
1471:                }
1472:                return parent;
1473:            }
1474:
1475:            // ---------
1476:            // visibility update
1477:
1478:            // synchronizes ComponentInspector with selection in FormDesigner
1479:            // [there is a hardcoded relationship between these two views]
1480:            void updateComponentInspector() {
1481:                ComponentInspector ci = ComponentInspector.getInstance();
1482:                if (ci.getFocusedForm() != formEditor)
1483:                    return;
1484:
1485:                Node[] selectedNodes = getSelectedComponentNodes();
1486:                try {
1487:                    setActivatedNodes(selectedNodes); // Issue 62356
1488:                    ci.setSelectedNodes(selectedNodes, formEditor);
1489:                    // sets also the activated nodes (both for ComponentInspector
1490:                    // and FormDesigner)
1491:                } catch (java.beans.PropertyVetoException ex) {
1492:                    ex.printStackTrace();
1493:                }
1494:            }
1495:
1496:            void updateVisualSettings() {
1497:                componentLayer.updateVisualSettings();
1498:                if (nonVisualTray != null) {
1499:                    nonVisualTray.updateVisualSettings();
1500:                }
1501:                layeredPane.revalidate();
1502:                layeredPane.repaint(); // repaints both HanleLayer and ComponentLayer
1503:            }
1504:
1505:            private void ensureComponentIsShown(RADVisualComponent metacomp) {
1506:                Component comp = (Component) getComponent(metacomp);
1507:                if (comp == null)
1508:                    return; // component is not in the visualized tree
1509:
1510:                //        if (comp == null) { // visual component doesn't exist yet
1511:                //            if (metacont != null)
1512:                //                metacont.getLayoutSupport().selectComponent(
1513:                //                               metacont.getIndexOf(metacomp));
1514:                //            return;
1515:                //        }
1516:
1517:                if (comp.isShowing())
1518:                    return; // component is showing
1519:                if (!isInDesigner(metacomp))
1520:                    return; // component is not in designer
1521:
1522:                Component topComp = (Component) getComponent(topDesignComponent);
1523:                if (topComp == null || !topComp.isShowing())
1524:                    return; // designer is not showing
1525:
1526:                RADVisualContainer metacont = metacomp.getParentContainer();
1527:                RADVisualComponent child = metacomp;
1528:
1529:                while (metacont != null) {
1530:                    Container cont = (Container) getComponent(metacont);
1531:
1532:                    LayoutSupportManager laysup = metacont.getLayoutSupport();
1533:                    if (laysup != null) {
1534:                        Container contDelegate = metacont
1535:                                .getContainerDelegate(cont);
1536:                        laysup.selectComponent(child.getComponentIndex());
1537:                        laysup.arrangeContainer(cont, contDelegate);
1538:                    }
1539:
1540:                    if (metacont == topDesignComponent || cont.isShowing())
1541:                        break;
1542:
1543:                    child = metacont;
1544:                    metacont = metacont.getParentContainer();
1545:                }
1546:            }
1547:
1548:            // --------------
1549:            // bean connection
1550:
1551:            void connectBean(RADComponent metacomp, boolean showDialog) {
1552:                if (connectionSource == null) {
1553:                    connectionSource = metacomp;
1554:                    FormEditor.getAssistantModel(formModel).setContext(
1555:                            "connectTarget"); // NOI18N
1556:                    handleLayer.repaint();
1557:                } else {
1558:                    if (metacomp == connectionSource) {
1559:                        if (connectionTarget != null) {
1560:                            resetConnection();
1561:                            toggleSelectionMode();
1562:                        }
1563:                        return;
1564:                    }
1565:                    connectionTarget = metacomp;
1566:                    handleLayer.repaint();
1567:                    if (showDialog) {
1568:                        if (connectionTarget != null) {
1569:                            FormEditor.getAssistantModel(formModel).setContext(
1570:                                    "connectWizard"); // NOI18N
1571:                            createConnection(connectionSource, connectionTarget);
1572:                        }
1573:                        //                resetConnection();
1574:                        toggleSelectionMode();
1575:                    }
1576:                }
1577:            }
1578:
1579:            public RADComponent getConnectionSource() {
1580:                return connectionSource;
1581:            }
1582:
1583:            public RADComponent getConnectionTarget() {
1584:                return connectionTarget;
1585:            }
1586:
1587:            public void resetConnection() {
1588:                if (connectionSource != null || connectionTarget != null) {
1589:                    connectionSource = null;
1590:                    connectionTarget = null;
1591:                    handleLayer.repaint();
1592:                }
1593:            }
1594:
1595:            private void createConnection(RADComponent source,
1596:                    RADComponent target) {
1597:                ConnectionWizard cw = new ConnectionWizard(formModel, source,
1598:                        target);
1599:
1600:                if (cw.show()) {
1601:                    final Event event = cw.getSelectedEvent();
1602:                    final String eventName = cw.getEventName();
1603:                    String bodyText = cw.getGeneratedCode();
1604:
1605:                    formModel.getFormEvents().attachEvent(event, eventName,
1606:                            bodyText);
1607:
1608:                    // hack: after all updates, switch to editor
1609:                    SwingUtilities.invokeLater(new Runnable() {
1610:                        public void run() {
1611:                            formModel.getFormEvents().attachEvent(event,
1612:                                    eventName, null);
1613:                        }
1614:                    });
1615:                }
1616:            }
1617:
1618:            // -----------------
1619:            // in-place editing
1620:
1621:            public void startInPlaceEditing(RADComponent metacomp) {
1622:
1623:                if (formModel.isReadOnly())
1624:                    return;
1625:                if (textEditLayer != null && textEditLayer.isVisible())
1626:                    return;
1627:                if (!isEditableInPlace(metacomp)) // check for sure
1628:                    return;
1629:
1630:                Component comp = (Component) getComponent(metacomp);
1631:                if (comp == null) { // component is not visible
1632:                    notifyCannotEditInPlace();
1633:                    return;
1634:                }
1635:
1636:                FormProperty property = null;
1637:                if (JTabbedPane.class.isAssignableFrom(metacomp.getBeanClass())) {
1638:                    JTabbedPane tabbedPane = (JTabbedPane) comp;
1639:                    int index = tabbedPane.getSelectedIndex();
1640:                    RADVisualContainer metacont = (RADVisualContainer) metacomp;
1641:                    RADVisualComponent tabComp = metacont
1642:                            .getSubComponent(index);
1643:                    Node.Property[] props = tabComp.getConstraintsProperties();
1644:                    for (int i = 0; i < props.length; i++) {
1645:                        if (props[i].getName()
1646:                                .equals("TabConstraints.tabTitle")) { // NOI18N
1647:                            if (props[i] instanceof  FormProperty) {
1648:                                property = (FormProperty) props[i];
1649:                            } else {
1650:                                return;
1651:                            }
1652:                        }
1653:                    }
1654:                    if (property == null)
1655:                        return;
1656:                } else {
1657:                    property = metacomp.getBeanProperty("text"); // NOI18N
1658:                    if (property == null)
1659:                        return; // should not happen
1660:                }
1661:
1662:                String editText = null;
1663:                try {
1664:                    Object text = property.getRealValue();
1665:                    if (!(text instanceof  String))
1666:                        text = ""; // or return?
1667:                    editText = (String) text;
1668:                } catch (Exception ex) { // should not happen
1669:                    ex.printStackTrace();
1670:                    return;
1671:                }
1672:
1673:                editedProperty = property;
1674:
1675:                getInPlaceEditLayer();
1676:                try {
1677:                    textEditLayer.setEditedComponent(comp, editText);
1678:                } catch (IllegalArgumentException ex) {
1679:                    notifyCannotEditInPlace();
1680:                    return;
1681:                }
1682:
1683:                textEditLayer.setVisible(true);
1684:                handleLayer.setVisible(false);
1685:                textEditLayer.requestFocus();
1686:            }
1687:
1688:            private InPlaceEditLayer.FinishListener getFinnishListener() {
1689:                if (finnishListener == null) {
1690:                    finnishListener = new InPlaceEditLayer.FinishListener() {
1691:                        public void editingFinished(boolean textChanged) {
1692:                            finishInPlaceEditing(textEditLayer.isTextChanged());
1693:                        }
1694:                    };
1695:                }
1696:                return finnishListener;
1697:            }
1698:
1699:            private void finishInPlaceEditing(boolean applyChanges) {
1700:                if (applyChanges) {
1701:                    try {
1702:                        Object value = editedProperty.getValue();
1703:                        if (value instanceof  String) {
1704:                            editedProperty.setValue(textEditLayer
1705:                                    .getEditedText());
1706:                        } else {
1707:                            PropertyEditor prEd = editedProperty
1708:                                    .findDefaultEditor();
1709:                            editedProperty
1710:                                    .setValue(new FormProperty.ValueWithEditor(
1711:                                            textEditLayer.getEditedText(), prEd));
1712:                        }
1713:                    } catch (Exception ex) { // should not happen
1714:                        ex.printStackTrace();
1715:                    }
1716:                }
1717:                if (handleLayer != null) {
1718:                    textEditLayer.setVisible(false);
1719:                    handleLayer.setVisible(true);
1720:                    handleLayer.requestFocus();
1721:                }
1722:                editedProperty = null;
1723:            }
1724:
1725:            public boolean isEditableInPlace(RADComponent metacomp) {
1726:                if (metacomp == null) {
1727:                    return false;
1728:                }
1729:                Object comp = getComponent(metacomp);
1730:                if (!(comp instanceof  Component)) {
1731:                    return false;
1732:                }
1733:
1734:                // don't allow in-place editing if there's some AWT parent (it may
1735:                // cause problems with fake peers on some platforms)
1736:                RADComponent parent = metacomp.getParentComponent();
1737:                while (parent != null) {
1738:                    if (!JComponent.class.isAssignableFrom(parent
1739:                            .getBeanClass())
1740:                            && !RootPaneContainer.class.isAssignableFrom(parent
1741:                                    .getBeanClass()))
1742:                        return false;
1743:                    parent = parent.getParentComponent();
1744:                }
1745:
1746:                Class beanClass = metacomp.getBeanClass();
1747:                return InPlaceEditLayer.supportsEditingFor(beanClass, false)
1748:                        && (!JTabbedPane.class.isAssignableFrom(beanClass) || ((JTabbedPane) comp)
1749:                                .getTabCount() != 0);
1750:            }
1751:
1752:            private void notifyCannotEditInPlace() {
1753:                DialogDisplayer.getDefault().notify(
1754:                        new NotifyDescriptor.Message(FormUtils
1755:                                .getBundleString("MSG_ComponentNotShown"), // NOI18N
1756:                                NotifyDescriptor.WARNING_MESSAGE));
1757:            }
1758:
1759:            // -----------------
1760:            // menu editing
1761:
1762:            public void openMenu(RADComponent metacomp) {
1763:                MenuEditLayer menuEditLayer = getMenuEditLayer();
1764:                Component comp = (Component) getComponent(metacomp);
1765:                menuEditLayer.setVisible(true);
1766:                menuEditLayer.openAndShowMenu(metacomp, comp);
1767:            }
1768:
1769:            // --------
1770:            // methods of TopComponent
1771:
1772:            // only MultiViewDescriptor is stored, not MultiViewElement
1773:            @Override
1774:            public int getPersistenceType() {
1775:                return TopComponent.PERSISTENCE_NEVER;
1776:            }
1777:
1778:            @Override
1779:            public HelpCtx getHelpCtx() {
1780:                return new HelpCtx("gui.formeditor"); // NOI18N
1781:            }
1782:
1783:            @Override
1784:            public void componentActivated() {
1785:                if (formModel == null)
1786:                    return;
1787:
1788:                formEditor.setFormDesigner(this );
1789:                ComponentInspector ci = ComponentInspector.getInstance();
1790:                if (ci.getFocusedForm() != formEditor) {
1791:                    ci.focusForm(formEditor);
1792:                    if (getDesignerMode() == MODE_CONNECT)
1793:                        clearSelection();
1794:                    else
1795:                        updateComponentInspector();
1796:                }
1797:
1798:                ci.attachActions();
1799:                if (textEditLayer == null || !textEditLayer.isVisible())
1800:                    handleLayer.requestFocus();
1801:            }
1802:
1803:            @Override
1804:            public void componentDeactivated() {
1805:                if (formModel == null)
1806:                    return;
1807:
1808:                if (textEditLayer != null && textEditLayer.isVisible())
1809:                    textEditLayer.finishEditing(false);
1810:
1811:                ComponentInspector.getInstance().detachActions();
1812:                resetConnection();
1813:            }
1814:
1815:            @Override
1816:            public UndoRedo getUndoRedo() {
1817:                UndoRedo ur = formModel != null ? formModel
1818:                        .getUndoRedoManager() : null;
1819:                return ur != null ? ur : super .getUndoRedo();
1820:            }
1821:
1822:            @Override
1823:            protected String preferredID() {
1824:                return formEditor.getFormDataObject().getName();
1825:            }
1826:
1827:            // ------
1828:            // multiview stuff
1829:
1830:            public JComponent getToolbarRepresentation() {
1831:                return getFormToolBar();
1832:            }
1833:
1834:            public JComponent getVisualRepresentation() {
1835:                return this ;
1836:            }
1837:
1838:            public void setMultiViewCallback(MultiViewElementCallback callback) {
1839:                multiViewObserver = callback;
1840:
1841:                // add FormDesigner as a client property so it can be obtained
1842:                // from multiview TopComponent (it is not sufficient to put
1843:                // it into lookup - only content of the lookup of the active
1844:                // element is accessible)
1845:                callback.getTopComponent().putClientProperty("formDesigner",
1846:                        this ); // NOI18N
1847:
1848:                // needed for deserialization...
1849:                if (formEditor != null) {
1850:                    // this is used (or misused?) to obtain the deserialized multiview
1851:                    // topcomponent and set it to FormEditorSupport
1852:                    FormDataObject formDO = formEditor.getFormDataObject();
1853:                    formDO.getFormEditorSupport().setTopComponent(
1854:                            callback.getTopComponent());
1855:                }
1856:            }
1857:
1858:            @Override
1859:            public void requestVisible() {
1860:                if (multiViewObserver != null)
1861:                    multiViewObserver.requestVisible();
1862:                else
1863:                    super .requestVisible();
1864:            }
1865:
1866:            @Override
1867:            public void requestActive() {
1868:                if (multiViewObserver != null)
1869:                    multiViewObserver.requestActive();
1870:                else
1871:                    super .requestActive();
1872:            }
1873:
1874:            @Override
1875:            public void componentClosed() {
1876:                super .componentClosed();
1877:                if (formModel != null) {
1878:                    if (formModelListener != null) {
1879:                        formModel.removeFormModelListener(formModelListener);
1880:                    }
1881:                    if (settingsListener != null) {
1882:                        FormLoaderSettings.getPreferences()
1883:                                .removePreferenceChangeListener(
1884:                                        settingsListener);
1885:                    }
1886:                    topDesignComponent = null;
1887:                    formModel = null;
1888:                }
1889:            }
1890:
1891:            @Override
1892:            public void componentShowing() {
1893:                super .componentShowing();
1894:                if (!formEditor.isFormLoaded()) {
1895:                    formEditor.loadFormDesigner();
1896:                    if (!formEditor.isFormLoaded()) { // there was a loading error
1897:                        removeAll();
1898:                        return;
1899:                    }
1900:                    // hack: after IDE start, if some form is opened but not active in
1901:                    // winsys, we need to select it in ComponentInspector
1902:                    EventQueue.invokeLater(new Runnable() {
1903:                        public void run() {
1904:                            if (formEditor != null
1905:                                    && formEditor.isFormLoaded()
1906:                                    && ComponentInspector.exists()
1907:                                    && ComponentInspector.getInstance()
1908:                                            .getFocusedForm() == null) {
1909:                                ComponentInspector.getInstance().focusForm(
1910:                                        formEditor);
1911:                            }
1912:                        }
1913:                    });
1914:                }
1915:                if (!initialized) {
1916:                    initialize();
1917:                }
1918:                FormEditorSupport.checkFormGroupVisibility();
1919:            }
1920:
1921:            @Override
1922:            public void componentHidden() {
1923:                super .componentHidden();
1924:                FormEditorSupport.checkFormGroupVisibility();
1925:            }
1926:
1927:            @Override
1928:            public void componentOpened() {
1929:                super .componentOpened();
1930:                if ((formEditor == null) && (multiViewObserver != null)) { // Issue 67879
1931:                    multiViewObserver.getTopComponent().close();
1932:                    EventQueue.invokeLater(new Runnable() {
1933:                        public void run() {
1934:                            FormEditorSupport.checkFormGroupVisibility();
1935:                        }
1936:                    });
1937:                }
1938:            }
1939:
1940:            public CloseOperationState canCloseElement() {
1941:                // if this is not the last cloned designer, closing is OK
1942:                if (!FormEditorSupport.isLastView(multiViewObserver
1943:                        .getTopComponent()))
1944:                    return CloseOperationState.STATE_OK;
1945:
1946:                // return a placeholder state - to be sure our CloseHandler is called
1947:                return MultiViewFactory.createUnsafeCloseState(
1948:                        "ID_FORM_CLOSING", // dummy ID // NOI18N
1949:                        MultiViewFactory.NOOP_CLOSE_ACTION,
1950:                        MultiViewFactory.NOOP_CLOSE_ACTION);
1951:            }
1952:
1953:            public InPlaceEditLayer getInPlaceEditLayer() {
1954:                if (textEditLayer == null) {
1955:                    textEditLayer = new InPlaceEditLayer();
1956:                    textEditLayer.setVisible(false);
1957:                    textEditLayer.addFinishListener(getFinnishListener());
1958:                    layeredPane.add(textEditLayer, new Integer(2001));
1959:                }
1960:                return textEditLayer;
1961:            }
1962:
1963:            MenuEditLayer getMenuEditLayer() {
1964:                if (menuEditLayer == null) {
1965:                    menuEditLayer = new MenuEditLayer(this );
1966:                    menuEditLayer.setVisible(false);
1967:                    layeredPane.add(menuEditLayer, new Integer(2000));
1968:                }
1969:                return menuEditLayer;
1970:            }
1971:
1972:            // -----------
1973:            // innerclasses
1974:
1975:            private class LayoutMapper implements  VisualMapper {
1976:
1977:                // -------
1978:
1979:                //        public String getTopComponentId() {
1980:                //            return getTopDesignComponent().getId();
1981:                //        }
1982:
1983:                public Rectangle getComponentBounds(String componentId) {
1984:                    Component visual = getVisualComponent(componentId, true,
1985:                            false);
1986:                    Rectangle rect = null;
1987:                    if (visual != null) {
1988:                        rect = componentBoundsToTop(visual);
1989:                    }
1990:
1991:                    if (getLayoutDesigner().logTestCode()) {
1992:                        getLayoutDesigner().testCode.add("  compBounds.put(\""
1993:                                + componentId + "\", new Rectangle("
1994:                                + //NOI18N
1995:                                rect.x + ", " + rect.y + ", " + rect.width
1996:                                + ", " + rect.height + "));"); //NOI18N
1997:                    }
1998:
1999:                    return rect;
2000:                }
2001:
2002:                public Rectangle getContainerInterior(String componentId) {
2003:                    Component visual = getVisualComponent(componentId, true,
2004:                            false);
2005:                    if (visual == null)
2006:                        return null;
2007:
2008:                    RADVisualContainer metacont = (RADVisualContainer) getMetaComponent(componentId);
2009:                    Container cont = metacont.getContainerDelegate(visual);
2010:
2011:                    Rectangle rect = componentBoundsToTop(cont);
2012:                    Insets insets = cont.getInsets();
2013:                    rect.x += insets.left;
2014:                    rect.y += insets.top;
2015:                    rect.width -= insets.left + insets.right;
2016:                    rect.height -= insets.top + insets.bottom;
2017:
2018:                    if (getLayoutDesigner().logTestCode()) {
2019:                        getLayoutDesigner().testCode
2020:                                .add("  contInterior.put(\""
2021:                                        + componentId
2022:                                        + "\", new Rectangle("
2023:                                        + //NOI18N
2024:                                        rect.x + ", " + rect.y + ", "
2025:                                        + rect.width + ", " + rect.height
2026:                                        + "));"); //NOI18N
2027:                    }
2028:
2029:                    return rect;
2030:                }
2031:
2032:                public Dimension getComponentMinimumSize(String componentId) {
2033:                    Component visual = getVisualComponent(componentId, false,
2034:                            false);
2035:                    Dimension dim = null;
2036:                    if (visual != null) {
2037:                        dim = visual.getMinimumSize();
2038:                    }
2039:                    if (getLayoutDesigner().logTestCode()) {
2040:                        getLayoutDesigner().testCode.add("  compMinSize.put(\""
2041:                                + componentId
2042:                                + "\", new Dimension("
2043:                                + //NOI18N
2044:                                new Double(dim.getWidth()).intValue() + ", "
2045:                                + new Double(dim.getHeight()).intValue()
2046:                                + "));"); //NOI18N
2047:                    }
2048:                    return dim;
2049:                }
2050:
2051:                public Dimension getComponentPreferredSize(String componentId) {
2052:                    Component visual = getVisualComponent(componentId, false,
2053:                            false);
2054:                    Dimension dim = null;
2055:                    if (visual != null) {
2056:                        dim = visual.getPreferredSize();
2057:                    }
2058:                    if (getLayoutDesigner().logTestCode()) {
2059:                        getLayoutDesigner().testCode
2060:                                .add("  compPrefSize.put(\""
2061:                                        + componentId
2062:                                        + "\", new Dimension("
2063:                                        + //NOI18N
2064:                                        new Double(dim.getWidth()).intValue()
2065:                                        + ", "
2066:                                        + new Double(dim.getHeight())
2067:                                                .intValue() + "));"); //NOI18N
2068:                    }
2069:                    return dim;
2070:                }
2071:
2072:                public boolean hasExplicitPreferredSize(String componentId) {
2073:                    JComponent visual = (JComponent) getVisualComponent(
2074:                            componentId, false, true);
2075:                    boolean hasExplPrefSize = false;
2076:                    if (visual != null) {
2077:                        hasExplPrefSize = visual.isPreferredSizeSet();
2078:                    }
2079:                    if (getLayoutDesigner().logTestCode()) {
2080:                        getLayoutDesigner().testCode
2081:                                .add("  hasExplicitPrefSize.put(\""
2082:                                        + componentId + "\", new Boolean("
2083:                                        + hasExplPrefSize + "));"); //NOI18N
2084:                    }
2085:                    return hasExplPrefSize;
2086:                }
2087:
2088:                public int getBaselinePosition(String componentId, int width,
2089:                        int height) {
2090:                    int baseLinePos = -1;
2091:                    JComponent comp = (JComponent) getVisualComponent(
2092:                            componentId, true, true);
2093:                    // [hack - vertically resizable components cannot be baseline aligned]
2094:                    // [this should be either solved or filtered in LayoutDragger according to vertical resizability of the component]
2095:                    if (comp != null
2096:                            && (comp instanceof  JScrollPane
2097:                                    || comp.getClass().equals(JPanel.class) || comp instanceof  JTabbedPane)) {
2098:                        //                    || comp instanceof JTextArea
2099:                        //                    || comp instanceof JTree || comp instanceof JTable || comp instanceof JList
2100:                        baseLinePos = 0;
2101:                    }
2102:
2103:                    if (baseLinePos == -1) {
2104:                        if (comp != null) {
2105:                            baseLinePos = Baseline.getBaseline(comp, width,
2106:                                    height);
2107:                        } else {
2108:                            baseLinePos = 0;
2109:                        }
2110:                    }
2111:
2112:                    if (getLayoutDesigner().logTestCode()) {
2113:                        String id = componentId + "-" + width + "-" + height; //NOI18N
2114:                        getLayoutDesigner().testCode
2115:                                .add("  baselinePosition.put(\"" + id
2116:                                        + "\", new Integer(" + baseLinePos
2117:                                        + "));"); //NOI18N
2118:                    }
2119:
2120:                    return baseLinePos;
2121:                }
2122:
2123:                public int getPreferredPadding(String comp1Id, String comp2Id,
2124:                        int dimension, int comp2Alignment,
2125:                        PaddingType paddingType) {
2126:                    String id = null;
2127:                    if (getLayoutDesigner().logTestCode()) {
2128:                        id = comp1Id + "-"
2129:                                + comp2Id
2130:                                + "-"
2131:                                + dimension
2132:                                + "-"
2133:                                + comp2Alignment
2134:                                + "-" // NOI18N
2135:                                + (paddingType != null ? paddingType.ordinal()
2136:                                        : 0);
2137:                    }
2138:
2139:                    JComponent comp1 = (JComponent) getVisualComponent(comp1Id,
2140:                            true, true);
2141:                    JComponent comp2 = (JComponent) getVisualComponent(comp2Id,
2142:                            true, true);
2143:                    if (comp1 == null || comp2 == null) { // not JComponents...
2144:                        if (getLayoutDesigner().logTestCode()) {
2145:                            getLayoutDesigner().testCode
2146:                                    .add("  prefPadding.put(\"" + id + //NOI18N
2147:                                            "\", new Integer(10)); // comp1Id-comp2Id-dimension-comp2Alignment-paddingType"); //NOI18N
2148:                        }
2149:                        return 10; // default distance between components (for non-JComponents)
2150:                    }
2151:
2152:                    assert dimension == HORIZONTAL || dimension == VERTICAL;
2153:                    assert comp2Alignment == LEADING
2154:                            || comp2Alignment == TRAILING;
2155:
2156:                    int type = paddingType == PaddingType.INDENT ? LayoutStyle.INDENT
2157:                            : (paddingType == PaddingType.RELATED ? LayoutStyle.RELATED
2158:                                    : LayoutStyle.UNRELATED);
2159:                    int position = 0;
2160:                    if (dimension == HORIZONTAL) {
2161:                        if (paddingType == PaddingType.INDENT) {
2162:                            position = comp2Alignment == LEADING ? SwingConstants.WEST
2163:                                    : SwingConstants.EAST;
2164:                        } else {
2165:                            position = comp2Alignment == LEADING ? SwingConstants.EAST
2166:                                    : SwingConstants.WEST;
2167:                        }
2168:                    } else {
2169:                        position = comp2Alignment == LEADING ? SwingConstants.SOUTH
2170:                                : SwingConstants.NORTH;
2171:                    }
2172:
2173:                    int prefPadding = paddingType != PaddingType.SEPARATE ? FormLAF
2174:                            .getDesignerLayoutStyle().getPreferredGap(comp1,
2175:                                    comp2, type, position, null)
2176:                            : SwingLayoutBuilder.PADDING_SEPARATE_VALUE; // not in LayoutStyle
2177:
2178:                    if (getLayoutDesigner().logTestCode()) {
2179:                        getLayoutDesigner().testCode
2180:                                .add("  prefPadding.put(\"" + id
2181:                                        + "\", new Integer(" + prefPadding + //NOI18N
2182:                                        ")); // comp1Id-comp2Id-dimension-comp2Alignment-paddingType"); //NOI18N
2183:                    }
2184:
2185:                    return prefPadding;
2186:                }
2187:
2188:                public int getPreferredPaddingInParent(String parentId,
2189:                        String compId, int dimension, int compAlignment) {
2190:                    String id = null;
2191:                    if (getLayoutDesigner().logTestCode()) {
2192:                        id = parentId + "-" + compId + "-" + dimension + "-"
2193:                                + compAlignment; //NOI18N
2194:                    }
2195:
2196:                    JComponent comp = null;
2197:                    Container parent = (Container) getVisualComponent(parentId,
2198:                            true, false);
2199:                    if (parent != null) {
2200:                        RADVisualContainer metacont = (RADVisualContainer) getMetaComponent(parentId);
2201:                        parent = metacont.getContainerDelegate(parent);
2202:                        comp = (JComponent) getVisualComponent(compId, true,
2203:                                true);
2204:                    }
2205:                    if (comp == null) {
2206:                        if (getLayoutDesigner().logTestCode()) {
2207:                            getLayoutDesigner().testCode
2208:                                    .add("  prefPaddingInParent.put(\"" + id + //NOI18N
2209:                                            "\", new Integer(10)); // parentId-compId-dimension-compAlignment"); //NOI18N
2210:                        }
2211:                        return 10; // default distance from parent border (for non-JComponents)
2212:                    }
2213:
2214:                    assert dimension == HORIZONTAL || dimension == VERTICAL;
2215:                    assert compAlignment == LEADING
2216:                            || compAlignment == TRAILING;
2217:
2218:                    int alignment;
2219:
2220:                    if (dimension == HORIZONTAL) {
2221:                        if (compAlignment == LEADING) {
2222:                            alignment = SwingConstants.WEST;
2223:                        } else {
2224:                            alignment = SwingConstants.EAST;
2225:                        }
2226:                    } else {
2227:                        if (compAlignment == LEADING) {
2228:                            alignment = SwingConstants.NORTH;
2229:                        } else {
2230:                            alignment = SwingConstants.SOUTH;
2231:                        }
2232:                    }
2233:                    int prefPadding = FormLAF.getDesignerLayoutStyle()
2234:                            .getContainerGap(comp, alignment, parent);
2235:
2236:                    if (getLayoutDesigner().logTestCode()) {
2237:                        getLayoutDesigner().testCode
2238:                                .add("  prefPaddingInParent.put(\"" + id
2239:                                        + "\", new Integer("
2240:                                        + //NOI18N
2241:                                        prefPadding
2242:                                        + ")); // parentId-compId-dimension-compAlignment"); //NOI18N
2243:                    }
2244:
2245:                    return prefPadding;
2246:                }
2247:
2248:                public boolean[] getComponentResizability(String compId,
2249:                        boolean[] resizability) {
2250:                    resizability[0] = resizability[1] = true;
2251:                    // [real resizability spec TBD]
2252:                    return resizability;
2253:                }
2254:
2255:                public void rebuildLayout(String contId) {
2256:                    replicator
2257:                            .updateContainerLayout((RADVisualContainer) getMetaComponent(contId));
2258:                    replicator.getLayoutBuilder(contId).doLayout();
2259:                }
2260:
2261:                public void setComponentVisibility(String componentId,
2262:                        boolean visible) {
2263:                    Object comp = getComponent(componentId);
2264:                    if (comp instanceof  Component) {
2265:                        ((Component) comp).setVisible(visible);
2266:                    }
2267:                }
2268:
2269:                // -------
2270:
2271:                private RADComponent getMetaComponent(String compId) {
2272:                    RADComponent metacomp = formModel.getMetaComponent(compId);
2273:                    if (metacomp == null) {
2274:                        RADComponent precreated = formModel
2275:                                .getComponentCreator()
2276:                                .getPrecreatedMetaComponent();
2277:                        if (precreated != null
2278:                                && precreated.getId().equals(compId)) {
2279:                            metacomp = precreated;
2280:                        }
2281:                    }
2282:                    return metacomp;
2283:                }
2284:
2285:                private Component getVisualComponent(String compId,
2286:                        boolean needVisible, boolean needJComponent) {
2287:                    Object comp = getComponent(compId);
2288:                    if (comp == null) {
2289:                        RADVisualComponent precreated = formModel
2290:                                .getComponentCreator()
2291:                                .getPrecreatedMetaComponent();
2292:                        if (precreated != null
2293:                                && precreated.getId().equals(compId)) {
2294:                            comp = precreated.getBeanInstance();
2295:                        }
2296:                        if (comp == null && !needVisible) {
2297:                            RADComponent metacomp = getMetaComponent(compId);
2298:                            if (metacomp != null) {
2299:                                comp = metacomp.getBeanInstance();
2300:                            }
2301:                        }
2302:                    }
2303:                    Class<?> type = needJComponent ? JComponent.class
2304:                            : Component.class;
2305:                    return comp != null
2306:                            && type.isAssignableFrom(comp.getClass()) ? (Component) comp
2307:                            : null;
2308:                }
2309:
2310:            }
2311:
2312:            // --------
2313:
2314:            private Collection<String> componentIds() {
2315:                List<String> componentIds = new LinkedList<String>();
2316:                List selectedComps = getSelectedLayoutComponents();
2317:                LayoutModel layoutModel = getFormModel().getLayoutModel();
2318:                Iterator iter = selectedComps.iterator();
2319:                while (iter.hasNext()) {
2320:                    RADVisualComponent visualComp = (RADVisualComponent) iter
2321:                            .next();
2322:                    if ((visualComp.getParentContainer() != null)
2323:                            && (visualComp.getParentLayoutSupport() == null)
2324:                            && layoutModel.getLayoutComponent(visualComp
2325:                                    .getId()) != null)
2326:                        componentIds.add(visualComp.getId());
2327:                }
2328:                return componentIds;
2329:            }
2330:
2331:            // Listener on FormModel - ensures updating of designer view.
2332:            private class FormListener implements  FormModelListener, Runnable {
2333:
2334:                private FormModelEvent[] events;
2335:
2336:                public void formChanged(final FormModelEvent[] events) {
2337:                    if (!EventQueue.isDispatchThread()) {
2338:                        EventQueue.invokeLater(new Runnable() {
2339:                            public void run() {
2340:                                processEvents(events);
2341:                            }
2342:                        });
2343:                    } else {
2344:                        processEvents(events);
2345:                    }
2346:                }
2347:
2348:                private void processEvents(FormModelEvent[] events) {
2349:                    boolean lafBlock;
2350:                    if (events == null) {
2351:                        lafBlock = true;
2352:                    } else {
2353:                        lafBlock = false;
2354:                        boolean modifying = false;
2355:                        for (int i = 0; i < events.length; i++) {
2356:                            FormModelEvent ev = events[i];
2357:                            if (ev.isModifying())
2358:                                modifying = true;
2359:                            if ((ev.getChangeType() == FormModelEvent.COMPONENT_ADDED)
2360:                                    || (ev.getChangeType() == FormModelEvent.COMPONENT_PROPERTY_CHANGED)
2361:                                    || (ev.getChangeType() == FormModelEvent.BINDING_PROPERTY_CHANGED)) {
2362:                                lafBlock = true;
2363:                                break;
2364:                            }
2365:                        }
2366:                        if (!modifying)
2367:                            return;
2368:
2369:                        assert EventQueue.isDispatchThread();
2370:                    }
2371:
2372:                    this .events = events;
2373:
2374:                    if (lafBlock) { // Look&Feel UI defaults remapping needed
2375:                        Locale defaultLocale = switchToDesignLocale(getFormModel());
2376:                        try {
2377:                            FormLAF.executeWithLookAndFeel(formModel, this );
2378:                        } finally {
2379:                            if (defaultLocale != null)
2380:                                Locale.setDefault(defaultLocale);
2381:                        }
2382:                    } else
2383:                        run();
2384:                }
2385:
2386:                public void run() {
2387:                    if (events == null) {
2388:                        Object originalVisualComp = (topDesignComponent == null) ? null
2389:                                : replicator
2390:                                        .getClonedComponent(topDesignComponent);
2391:                        Dimension originalSize = originalVisualComp instanceof  Component ? ((Component) originalVisualComp)
2392:                                .getSize()
2393:                                : null;
2394:
2395:                        replicator.setTopMetaComponent(topDesignComponent);
2396:                        Component formClone = (Component) replicator
2397:                                .createClone();
2398:                        if (formClone != null) {
2399:                            formClone.setVisible(true);
2400:                            componentLayer.setTopDesignComponent(formClone);
2401:                            if (originalSize != null) {
2402:                                componentLayer.setDesignerSize(originalSize);
2403:                                checkDesignerSize();
2404:                            } else
2405:                                setupDesignerSize();
2406:                            if (getLayoutDesigner() != null)
2407:                                getLayoutDesigner()
2408:                                        .externalSizeChangeHappened();
2409:                            // Must be invoked later. ComponentLayer doesn't have a peer (yet)
2410:                            // when the form is opened and validate does nothing on components
2411:                            // without peer.
2412:                            EventQueue.invokeLater(new Runnable() {
2413:                                public void run() {
2414:                                    updateComponentLayer(false);
2415:                                }
2416:                            });
2417:                        }
2418:                        return;
2419:                    }
2420:
2421:                    FormModelEvent[] events = this .events;
2422:                    this .events = null;
2423:
2424:                    int prevType = 0;
2425:                    ComponentContainer prevContainer = null;
2426:                    boolean updateDone = false;
2427:                    boolean deriveDesignerSize = false;
2428:
2429:                    for (int i = 0; i < events.length; i++) {
2430:                        FormModelEvent ev = events[i];
2431:                        int type = ev.getChangeType();
2432:                        ComponentContainer metacont = ev.getContainer();
2433:
2434:                        if (type == FormModelEvent.CONTAINER_LAYOUT_EXCHANGED
2435:                                || type == FormModelEvent.CONTAINER_LAYOUT_CHANGED
2436:                                || type == FormModelEvent.COMPONENT_LAYOUT_CHANGED) {
2437:                            if ((prevType != FormModelEvent.CONTAINER_LAYOUT_EXCHANGED
2438:                                    && prevType != FormModelEvent.CONTAINER_LAYOUT_CHANGED && prevType != FormModelEvent.COMPONENT_LAYOUT_CHANGED)
2439:                                    || prevContainer != metacont) {
2440:                                replicator
2441:                                        .updateContainerLayout((RADVisualContainer) metacont);
2442:                                updateDone = true;
2443:                            }
2444:                        } else if (type == FormModelEvent.COMPONENT_ADDED) {
2445:                            if ((metacont instanceof  RADVisualContainer || metacont instanceof  RADMenuComponent)
2446:                                    && (prevType != FormModelEvent.COMPONENT_ADDED || prevContainer != metacont)) {
2447:                                replicator.updateAddedComponents(metacont);
2448:                                // Note: replicator calls BindingDesignSupport to establish
2449:                                // bindings for the the cloned instance (e.g. in remove undo)
2450:                                updateDone = true;
2451:                            }
2452:                        } else if (type == FormModelEvent.COMPONENT_REMOVED) {
2453:                            RADComponent removed = ev.getComponent();
2454:
2455:                            // if the top designed component (or some of its parents)
2456:                            // was removed then whole designer view must be recreated
2457:                            if (removed instanceof  RADVisualComponent
2458:                                    && (removed == topDesignComponent || removed
2459:                                            .isParentComponent(topDesignComponent))) {
2460:                                resetTopDesignComponent(false);
2461:                                updateWholeDesigner();
2462:                                return;
2463:                            } else {
2464:                                replicator.removeComponent(ev.getComponent(),
2465:                                        ev.getContainer());
2466:                                updateDone = true;
2467:                            }
2468:                            // Note: BindingDesignSupport takes care of removing bindings
2469:                        } else if (type == FormModelEvent.COMPONENTS_REORDERED) {
2470:                            if (prevType != FormModelEvent.COMPONENTS_REORDERED
2471:                                    || prevContainer != metacont) {
2472:                                replicator.reorderComponents(metacont);
2473:                                updateDone = true;
2474:                            }
2475:                        } else if (type == FormModelEvent.COMPONENT_PROPERTY_CHANGED) {
2476:                            RADProperty eventProperty = ev
2477:                                    .getComponentProperty();
2478:                            RADComponent eventComponent = ev.getComponent();
2479:
2480:                            replicator.updateComponentProperty(eventProperty);
2481:                            updateConnectedProperties(eventProperty,
2482:                                    eventComponent);
2483:
2484:                            updateDone = true;
2485:                        } else if (type == FormModelEvent.BINDING_PROPERTY_CHANGED) {
2486:                            if (ev.getSubPropertyName() == null) {
2487:                                replicator.updateBinding(ev.getNewBinding());
2488:                            }
2489:                            // Note: BindingDesignSupport takes care of removing the old binding
2490:                            updateDone = true;
2491:                        } else if (type == FormModelEvent.SYNTHETIC_PROPERTY_CHANGED
2492:                                && PROP_DESIGNER_SIZE.equals(ev
2493:                                        .getPropertyName())) {
2494:                            Dimension size = (Dimension) ev
2495:                                    .getNewPropertyValue();
2496:                            if (size != null) {
2497:                                componentLayer.setDesignerSize(size);
2498:                                deriveDesignerSize = false;
2499:                                updateDone = true;
2500:                            } else { // null size to compute designer size based on content (from resetDesignerSize)
2501:                                deriveDesignerSize = true;
2502:                                updateDone = true;
2503:                            }
2504:                        }
2505:
2506:                        prevType = type;
2507:                        prevContainer = metacont;
2508:                    }
2509:
2510:                    if (updateDone) {
2511:                        if (deriveDesignerSize) { // compute from preferred size
2512:                            setupDesignerSize();
2513:                        } else { // check if not smaller than minimum size
2514:                            checkDesignerSize();
2515:                        }
2516:                        LayoutDesigner layoutDesigner = getLayoutDesigner();
2517:                        if ((layoutDesigner != null)
2518:                                && formModel.isCompoundEditInProgress()) {
2519:                            getLayoutDesigner().externalSizeChangeHappened();
2520:                        }
2521:                        updateComponentLayer(true);
2522:                    }
2523:                }
2524:
2525:                private void updateConnectedProperties(
2526:                        RADProperty eventProperty, RADComponent eventComponent) {
2527:                    for (RADComponent component : formModel.getAllComponents()) {
2528:                        RADProperty[] properties = component
2529:                                .getKnownBeanProperties();
2530:                        for (int i = 0; i < properties.length; i++) {
2531:                            try {
2532:                                if (properties[i].isChanged()) {
2533:                                    Object value = properties[i].getValue();
2534:                                    if (value instanceof  RADConnectionPropertyEditor.RADConnectionDesignValue) {
2535:                                        RADConnectionPropertyEditor.RADConnectionDesignValue propertyValue = (RADConnectionPropertyEditor.RADConnectionDesignValue) value;
2536:
2537:                                        if (propertyValue.getRADComponent() != null
2538:                                                && propertyValue.getProperty() != null
2539:                                                && eventComponent
2540:                                                        .getName()
2541:                                                        .equals(
2542:                                                                propertyValue
2543:                                                                        .getRADComponent()
2544:                                                                        .getName())
2545:                                                && eventProperty
2546:                                                        .getName()
2547:                                                        .equals(
2548:                                                                propertyValue
2549:                                                                        .getProperty()
2550:                                                                        .getName())) {
2551:
2552:                                            replicator
2553:                                                    .updateComponentProperty(properties[i]);
2554:                                        }
2555:                                    }
2556:                                }
2557:                            } catch (Exception e) {
2558:                                ErrorManager.getDefault().notify(e);
2559:                            }
2560:                        }
2561:                    }
2562:
2563:                }
2564:            }
2565:
2566:            /** Lookup that excludes nodes. */
2567:            private static class NoNodeLookup extends Lookup {
2568:                private final Lookup delegate;
2569:
2570:                public NoNodeLookup(Lookup delegate) {
2571:                    this .delegate = delegate;
2572:                }
2573:
2574:                public <T> T lookup(Class<T> clazz) {
2575:                    return (clazz == Node.class) ? null : delegate
2576:                            .lookup(clazz);
2577:                }
2578:
2579:                public <T> Result<T> lookup(Template<T> template) {
2580:                    if (template.getType() == Node.class) {
2581:                        return Lookup.EMPTY.lookup(new Lookup.Template<T>(
2582:                                template.getType()));
2583:                    } else {
2584:                        return delegate.lookup(template);
2585:                    }
2586:                }
2587:            }
2588:
2589:            /**
2590:             * Action that aligns selected components in the specified direction.
2591:             */
2592:            private class AlignAction extends AbstractAction {
2593:                // PENDING change to icons provided by Dusan
2594:                private static final String ICON_BASE = "org/netbeans/modules/form/resources/align_"; // NOI18N
2595:                /** Dimension to align in. */
2596:                private int dimension;
2597:                /** Requested alignment. */
2598:                private int alignment;
2599:                /** Group/Align action. */
2600:                private boolean closed;
2601:
2602:                /**
2603:                 * Creates action that aligns selected components in the specified direction.
2604:                 *
2605:                 * @param dimension dimension to align in.
2606:                 * @param alignment requested alignment.
2607:                 */
2608:                AlignAction(int dimension, int alignment, boolean closed) {
2609:                    this .dimension = dimension;
2610:                    this .alignment = alignment;
2611:                    this .closed = closed;
2612:                    boolean horizontal = (dimension == LayoutConstants.HORIZONTAL);
2613:                    boolean leading = (alignment == LayoutConstants.LEADING);
2614:                    String code;
2615:                    if (alignment == LayoutConstants.CENTER) {
2616:                        code = (horizontal ? "ch" : "cv"); // NOI18N
2617:                    } else {
2618:                        code = (horizontal ? (leading ? "l" : "r")
2619:                                : (leading ? "u" : "d")); // NOI18N
2620:                    }
2621:                    String iconResource = ICON_BASE + code + ".png"; // NOI18N
2622:                    putValue(Action.SMALL_ICON, new ImageIcon(Utilities
2623:                            .loadImage(iconResource)));
2624:                    putValue(Action.SHORT_DESCRIPTION, FormUtils
2625:                            .getBundleString("CTL_AlignAction_" + code)); // NOI18N
2626:                    setEnabled(false);
2627:                }
2628:
2629:                /**
2630:                 * Performs the alignment of selected components.
2631:                 *
2632:                 * @param e event that invoked the action.
2633:                 */
2634:                public void actionPerformed(ActionEvent e) {
2635:                    align(closed, dimension, alignment);
2636:                }
2637:
2638:                public int getDimension() {
2639:                    return dimension;
2640:                }
2641:
2642:                public int getAlignment() {
2643:                    return alignment;
2644:                }
2645:
2646:            }
2647:
2648:            /**
2649:             * Action that aligns selected components in the specified direction.
2650:             */
2651:            private class ResizabilityAction extends AbstractAction {
2652:                // PENDING change to icons provided by Dusan
2653:                private static final String ICON_BASE = "org/netbeans/modules/form/resources/resize_"; // NOI18N
2654:                /** Dimension of resizability. */
2655:                private int dimension;
2656:
2657:                /**
2658:                 * Creates action that changes the resizability of the component.
2659:                 *
2660:                 * @param dimension dimension of the resizability
2661:                 */
2662:                ResizabilityAction(int dimension) {
2663:                    this .dimension = dimension;
2664:                    String code = (dimension == LayoutConstants.HORIZONTAL) ? "h"
2665:                            : "v"; // NOI18N
2666:                    String iconResource = ICON_BASE + code + ".png"; // NOI18N
2667:                    putValue(Action.SMALL_ICON, new ImageIcon(Utilities
2668:                            .loadImage(iconResource)));
2669:                    putValue(Action.SHORT_DESCRIPTION, FormUtils
2670:                            .getBundleString("CTL_ResizeButton_" + code)); // NOI18N
2671:                    setEnabled(false);
2672:                }
2673:
2674:                /**
2675:                 * Performs the resizability change of selected components.
2676:                 *
2677:                 * @param e event that invoked the action.
2678:                 */
2679:                public void actionPerformed(ActionEvent e) {
2680:                    FormModel formModel = getFormModel();
2681:                    LayoutModel layoutModel = formModel.getLayoutModel();
2682:                    Object layoutUndoMark = layoutModel.getChangeMark();
2683:                    javax.swing.undo.UndoableEdit ue = layoutModel
2684:                            .getUndoableEdit();
2685:                    boolean autoUndo = true;
2686:                    LayoutDesigner layoutDesigner = getLayoutDesigner();
2687:                    Collection componentIds = componentIds();
2688:                    Set<RADVisualContainer> containers = new HashSet<RADVisualContainer>();
2689:                    try {
2690:                        Iterator iter = componentIds.iterator();
2691:                        while (iter.hasNext()) {
2692:                            String compId = (String) iter.next();
2693:                            LayoutComponent layoutComp = layoutModel
2694:                                    .getLayoutComponent(compId);
2695:                            boolean resizing = (getResizabilityButtons()[dimension])
2696:                                    .isSelected();
2697:                            if (layoutDesigner.isComponentResizing(layoutComp,
2698:                                    dimension) != resizing) {
2699:                                layoutDesigner.setComponentResizing(layoutComp,
2700:                                        dimension, resizing);
2701:                                RADVisualComponent comp = (RADVisualComponent) formModel
2702:                                        .getMetaComponent(compId);
2703:                                containers.add(comp.getParentContainer());
2704:                            }
2705:                        }
2706:                        autoUndo = false;
2707:                    } finally {
2708:                        Iterator<RADVisualContainer> iter = containers
2709:                                .iterator();
2710:                        while (iter.hasNext()) {
2711:                            formModel.fireContainerLayoutChanged(iter.next(),
2712:                                    null, null, null);
2713:                        }
2714:                        if (!layoutUndoMark.equals(layoutModel.getChangeMark())) {
2715:                            formModel.addUndoableEdit(ue);
2716:                        }
2717:                        if (autoUndo) {
2718:                            formModel.forceUndoOfCompoundEdit();
2719:                        }
2720:                    }
2721:                }
2722:            }
2723:
2724:            static class FormProxyLookup extends ProxyLookup {
2725:
2726:                FormProxyLookup(Lookup[] lookups) {
2727:                    super (lookups);
2728:                }
2729:
2730:                Lookup[] getSubLookups() {
2731:                    return getLookups();
2732:                }
2733:
2734:                void setSubLookups(Lookup[] lookups) {
2735:                    setLookups(lookups);
2736:                }
2737:
2738:            }
2739:
2740:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.