KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > form > HandleLayer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.form;
21
22 import java.awt.*;
23 import java.awt.datatransfer.*;
24 import java.awt.dnd.*;
25 import java.awt.event.*;
26 import java.awt.geom.Area JavaDoc;
27 import java.io.IOException JavaDoc;
28 import javax.swing.*;
29 import java.util.*;
30 import java.text.MessageFormat JavaDoc;
31 import javax.swing.undo.UndoableEdit JavaDoc;
32 import org.netbeans.spi.palette.PaletteController;
33
34 import org.openide.DialogDisplayer;
35 import org.openide.NotifyDescriptor;
36 import org.openide.awt.StatusDisplayer;
37 import org.openide.cookies.SaveCookie;
38 import org.openide.filesystems.FileObject;
39 import org.openide.nodes.NodeTransfer;
40 import org.openide.windows.TopComponent;
41 import org.openide.nodes.Node;
42 import org.openide.nodes.NodeOp;
43 import org.openide.util.Utilities;
44
45 import org.netbeans.modules.form.palette.PaletteItem;
46 import org.netbeans.modules.form.palette.PaletteUtils;
47 import org.netbeans.modules.form.project.ClassSource;
48 import org.netbeans.modules.form.fakepeer.FakePeerSupport;
49 import org.netbeans.modules.form.layoutsupport.*;
50 import org.netbeans.modules.form.layoutdesign.*;
51 import org.openide.util.Lookup;
52
53 /**
54  * A transparent layer (glass pane) handling user operations in designer (mouse
55  * and keyboard events) and painting selection and drag&drop feedback.
56  * Technically, this is a layer in FormDesigner, placed over ComponentLayer.
57  *
58  * @author Tran Duc Trung, Tomas Pavek
59  */

60
61 class HandleLayer extends JPanel implements MouseListener, MouseMotionListener
62 {
63     // constants for mode parameter of getMetaComponentAt(Point,int) method
64
static final int COMP_DEEPEST = 0; // get the deepest component (at given point)
65
static final int COMP_SELECTED = 1; // get the deepest selected component
66
static final int COMP_ABOVE_SELECTED = 2; // get the component above the deepest selected component
67
static final int COMP_UNDER_SELECTED = 3; // get the component under the deepest selected component
68

69     private static final int DESIGNER_RESIZING = 256; // flag for resizeType
70
private static MessageFormat JavaDoc resizingHintFormat;
71     private static MessageFormat JavaDoc sizeHintFormat;
72
73     private FormDesigner formDesigner;
74     private boolean viewOnly;
75
76     private ComponentDrag draggedComponent;
77     private JPanel dragPanel;
78
79     private Point lastMousePosition;
80     private int lastXPosDiff;
81     private int lastYPosDiff;
82             
83     private Point lastLeftMousePoint;
84     private Point prevLeftMousePoint;
85     private boolean draggingEnded; // prevents dragging from starting inconveniently
86
private int resizeType;
87
88     private SelectionDragger selectionDragger;
89     private Image resizeHandle;
90
91     private DropTarget dropTarget;
92     private NewComponentDropListener dropListener;
93     
94     /** The FormLoaderSettings instance */
95     private static FormLoaderSettings formSettings = FormLoaderSettings.getInstance();
96
97     // -------
98

99     HandleLayer(FormDesigner fd) {
100         formDesigner = fd;
101         addMouseListener(this);
102         addMouseMotionListener(this);
103         setLayout(null);
104         
105         // Hack - the panel is used to ensure correct painting of dragged components
106
dragPanel = new JPanel();
107         dragPanel.setLayout(null);
108         dragPanel.setBounds(-1,-1,0,0);
109         add(dragPanel);
110
111         // set Ctrl+TAB and Ctrl+Shift+TAB as focus traversal keys - to have
112
// TAB and Shift+TAB free for component selection
113
Set keys = new HashSet();
114         keys.add(AWTKeyStroke.getAWTKeyStroke(9,
115                                               InputEvent.CTRL_DOWN_MASK,
116                                               true));
117         setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
118                               keys);
119         keys.clear();
120         keys.add(AWTKeyStroke.getAWTKeyStroke(9,
121                                               InputEvent.CTRL_DOWN_MASK
122                                                  |InputEvent.SHIFT_DOWN_MASK,
123                                               true));
124         setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
125                               keys);
126
127         getAccessibleContext().setAccessibleName(
128             FormUtils.getBundleString("ACSN_HandleLayer")); // NOI18N
129
getAccessibleContext().setAccessibleDescription(
130             FormUtils.getBundleString("ACSD_HandleLayer")); // NOI18N
131

132         dropListener = new NewComponentDropListener();
133         dropTarget = new DropTarget(this, dropListener);
134     }
135
136     void setViewOnly(boolean viewOnly) {
137         if(this.viewOnly == viewOnly) {
138             return;
139         }
140         if(viewOnly) {
141             dropTarget.removeDropTargetListener(dropListener);
142         } else {
143         try {
144         dropTarget.addDropTargetListener(dropListener);
145         } catch (TooManyListenersException ex) {
146         ex.printStackTrace();
147         }
148         }
149         this.viewOnly = viewOnly;
150     }
151
152     private FormModel getFormModel() {
153         return formDesigner.getFormModel();
154     }
155
156     private MetaComponentCreator getComponentCreator() {
157         return formDesigner.getFormModel().getComponentCreator();
158     }
159
160     private LayoutModel getLayoutModel() {
161         return formDesigner.getFormModel().getLayoutModel();
162     }
163
164     // ---------
165

166     protected void paintComponent(Graphics g) {
167         Graphics2D g2 = (Graphics2D) g;
168
169         // paint component in the connection mode (if any)
170
if (formDesigner.getDesignerMode() == FormDesigner.MODE_CONNECT) {
171             RADComponent conSource = formDesigner.getConnectionSource();
172             RADComponent conTarget = formDesigner.getConnectionTarget();
173             if (conSource != null || conTarget != null) {
174                 g2.setColor(formSettings.getConnectionBorderColor());
175                 g2.setStroke(getPaintStroke());
176                 if (conSource != null)
177                     paintSelection(g2, conSource, false);
178                 if (conTarget != null)
179                     paintSelection(g2, conTarget, false);
180             }
181             return; // that's all in connection mode
182
}
183
184         if (draggedComponent != null) {
185             FormLAF.setUseDesignerDefaults(true);
186             draggedComponent.paintFeedback(g2);
187             FormLAF.setUseDesignerDefaults(false);
188         }
189         else { // just paint the selection of selected components
190
g2.setColor(formSettings.getSelectionBorderColor());
191             g2.setStroke(getPaintStroke());
192             boolean painted = false;
193             try {
194                 boolean inLayout = selectedComponentsInSameVisibleContainer();
195                 Iterator metacomps = formDesigner.getSelectedComponents().iterator();
196                 while (metacomps.hasNext()) {
197                     RADComponent metacomp = (RADComponent)metacomps.next();
198                     RADVisualComponent layoutMetacomp = formDesigner.componentToLayoutComponent(metacomp);
199                     if (layoutMetacomp != null)
200                         metacomp = layoutMetacomp;
201                     paintSelection(g2, metacomp, inLayout);
202                 }
203                 painted = true;
204             } finally {
205                 // Make sure that problems in selection painting
206
// doesn't cause endless stream of exceptions.
207
if (!painted) {
208                     formDesigner.clearSelection();
209                 }
210             }
211
212             if (selectionDragger != null)
213                 selectionDragger.paintDragFeedback(g2);
214         }
215     }
216
217     /**
218      * @param inLayout indicates whether to paint layout related decorations
219      * (layout relations in container and resize handles)
220      */

221     private void paintSelection(Graphics2D g, RADComponent metacomp, boolean inLayout) {
222         if (!(metacomp instanceof RADVisualComponent) && !(metacomp instanceof RADMenuItemComponent))
223             return;
224         Object JavaDoc comp = formDesigner.getComponent(metacomp);
225         if (!(comp instanceof Component))
226             return;
227
228         Component component = (Component) comp;
229         Component parent = component.getParent();
230
231         if (parent != null && component.isShowing()) {
232             Rectangle selRect = component.getBounds();
233             RADComponent metacont = metacomp.getParentComponent();
234             convertRectangleFromComponent(selRect, parent);
235             Rectangle visible = new Rectangle(0, 0, parent.getWidth(), parent.getHeight());
236             visible = convertVisibleRectangleFromComponent(visible, parent);
237
238             if (inLayout && formDesigner.isInDesignedTree(metacont)
239                 && metacont instanceof RADVisualContainer
240                 && ((RADVisualContainer)metacont).getLayoutSupport() == null)
241             { // component in free design container - layout designer may want to paint something
242
Container topCont = formDesigner.getTopVisualContainer();
243                 Point convertPoint = convertPointFromComponent(0, 0, topCont);
244                 g.translate(convertPoint.x, convertPoint.y);
245                 LayoutDesigner layoutDesigner = formDesigner.getLayoutDesigner();
246                 Color oldColor = g.getColor();
247                 g.setColor(formSettings.getGuidingLineColor());
248                 Shape clip = g.getClip();
249                 visible.translate(-convertPoint.x, -convertPoint.y);
250                 Area JavaDoc area = new Area JavaDoc(visible);
251                 if (clip != null) {
252                     area.intersect(new Area JavaDoc(clip));
253                 }
254                 g.setClip(area);
255                 layoutDesigner.paintSelection(g, metacomp.getId());
256                 g.setClip(clip);
257                 g.setColor(oldColor);
258                 visible.translate(convertPoint.x, convertPoint.y);
259                 g.translate(-convertPoint.x, -convertPoint.y);
260             }
261             int resizable = 0;
262             if (inLayout) {
263                 resizable = getComponentResizable((RADVisualComponent)metacomp);
264             }
265             if (resizable == 0) {
266                 selRect = selRect.intersection(visible);
267             }
268             int correction = formSettings.getSelectionBorderSize() % 2;
269             int x = selRect.x - correction;
270             int y = selRect.y - correction;
271             int width = selRect.width + correction;
272             int height = selRect.height + correction;
273             g.drawRect(x, y, width, height);
274             if (inLayout) {
275                 Image resizeHandle = resizeHandle();
276                 int iconHeight = resizeHandle.getHeight(null);
277                 int iconWidth = resizeHandle.getWidth(null);
278                 if ((resizable & LayoutSupportManager.RESIZE_LEFT) != 0) {
279                     g.drawImage(resizeHandle, x-iconWidth+1, y+(height-iconHeight)/2, null);
280                     if ((resizable & LayoutSupportManager.RESIZE_UP) != 0) {
281                         g.drawImage(resizeHandle, x-iconWidth+1, y-iconHeight+1, null);
282                     }
283                     if ((resizable & LayoutSupportManager.RESIZE_DOWN) != 0) {
284                         g.drawImage(resizeHandle, x-iconWidth+1, y+height, null);
285                     }
286                 }
287                 if ((resizable & LayoutSupportManager.RESIZE_RIGHT) != 0) {
288                     g.drawImage(resizeHandle, x+width, y+(height-iconHeight)/2, null);
289                     if ((resizable & LayoutSupportManager.RESIZE_UP) != 0) {
290                         g.drawImage(resizeHandle, x+width, y-iconHeight+1, null);
291                     }
292                     if ((resizable & LayoutSupportManager.RESIZE_DOWN) != 0) {
293                         g.drawImage(resizeHandle, x+width, y+height, null);
294                     }
295                 }
296                 if ((resizable & LayoutSupportManager.RESIZE_UP) != 0) {
297                     g.drawImage(resizeHandle, x+(width-iconWidth)/2, y-iconHeight+1, null);
298                 }
299                 if ((resizable & LayoutSupportManager.RESIZE_DOWN) != 0) {
300                     g.drawImage(resizeHandle, x+(width-iconWidth)/2, y+height, null);
301                 }
302             }
303         }
304     }
305     
306     private Image resizeHandle() {
307         if (resizeHandle == null) {
308             resizeHandle = new ImageIcon(Utilities.loadImage(
309                 "org/netbeans/modules/form/resources/resize_handle.png")).getImage(); // NOI18N
310
}
311         return resizeHandle;
312     }
313
314     // paint stroke cached
315
private static int lastPaintWidth = -1;
316     private Stroke paintStroke;
317
318     private Stroke getPaintStroke() {
319         int width = formSettings.getSelectionBorderSize();
320         if (lastPaintWidth != width) {
321             paintStroke = null;
322         }
323         if (paintStroke == null) {
324             paintStroke = new BasicStroke(width);
325             lastPaintWidth = width;
326         }
327         return paintStroke;
328     }
329
330     void maskDraggingComponents() {
331         if (draggedComponent != null) {
332             draggedComponent.maskDraggingComponents();
333         }
334     }
335
336     public boolean isOpaque() {
337         return false;
338     }
339
340     protected void processKeyEvent(KeyEvent e) {
341         int keyCode = e.getKeyCode();
342
343         if (keyCode == KeyEvent.VK_TAB || e.getKeyChar() == '\t') {
344             if (!e.isControlDown()) {
345                 if (e.getID() == KeyEvent.KEY_PRESSED) {
346                     RADComponent nextComp = formDesigner.getNextVisualComponent(
347                                                               !e.isShiftDown());
348                     if (nextComp != null)
349                         formDesigner.setSelectedComponent(nextComp);
350                 }
351                 e.consume();
352                 return;
353             }
354         }
355         else if (keyCode == KeyEvent.VK_SPACE) {
356             if (!viewOnly && e.getID() == KeyEvent.KEY_RELEASED) {
357                 java.util.List JavaDoc selected = formDesigner.getSelectedComponents();
358                 if (selected.size() == 1) { // just one component is selected
359
RADComponent comp = (RADComponent) selected.get(0);
360                     if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT) {
361                         // in selection mode SPACE starts in-place editing
362
formDesigner.startInPlaceEditing(comp);
363                     }
364 // else if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) {
365
// // in add mode SPACE adds selected item as component
366
// PaletteItem item = CPManager.getDefault().getSelectedItem();
367
// if (item != null) {
368
// formDesigner.getModel().getComponentCreator()
369
// .createComponent(item.getComponentClassSource(),
370
// comp,
371
// null);
372
// formDesigner.toggleSelectionMode();
373
// }
374
// }
375
}
376             }
377             e.consume();
378             return;
379         }
380         else if (keyCode == KeyEvent.VK_ESCAPE) {
381             if (formDesigner.getDesignerMode() != FormDesigner.MODE_SELECT) {
382                 formDesigner.toggleSelectionMode(); // also calls endDragging(null)
383
repaint();
384                 e.consume();
385                 return;
386             }
387             if (endDragging(null)) {
388                 repaint();
389                 e.consume();
390                 return;
391             }
392         } else if ((keyCode == 525) // PENDING replace by KeyEvent.VK_CONTEXT_MENU on JDK 5
393
|| ((keyCode == KeyEvent.VK_F10) && e.isShiftDown())) { // Shift F10 invokes context menu
394
Point p = null;
395             java.util.List JavaDoc selected = formDesigner.getSelectedComponents();
396             if (selected.size() > 0) {
397                 RADComponent metacomp = (RADComponent) selected.get(0);
398                 Object JavaDoc sel = (Component) formDesigner.getComponent(metacomp);
399                 if (sel instanceof Component) {
400                     Component comp = (Component) sel;
401                     p = convertPointFromComponent(comp.getLocation(), comp.getParent());
402                 }
403                 else p = new Point(6, 6);
404
405                 showContextMenu(p);
406                 e.consume();
407                 return;
408             }
409         } else if (((keyCode == KeyEvent.VK_D) || (keyCode == KeyEvent.VK_E)) && e.isAltDown() && e.isControlDown() && (e.getID() == KeyEvent.KEY_PRESSED)) {
410             FormModel formModel = formDesigner.getFormModel();
411             LayoutModel layoutModel = formModel.getLayoutModel();
412             if (layoutModel != null) {
413                 Map idToNameMap = new HashMap();
414                 for (RADComponent comp : formModel.getAllComponents()) {
415                     if (comp != formModel.getTopRADComponent())
416                         idToNameMap.put(comp.getId(), comp.getName());
417                 }
418                 System.out.println(layoutModel.dump(idToNameMap));
419             }
420         } else if (((keyCode == KeyEvent.VK_W)) && e.isAltDown() && e.isControlDown() && (e.getID() == KeyEvent.KEY_PRESSED)) {
421             // generate layout test (one checkpoint)
422
if (formDesigner.getLayoutDesigner().logTestCode()) {
423                 FormModel formModel = formDesigner.getFormModel();
424                 LayoutModel layoutModel = formModel.getLayoutModel();
425                 if (layoutModel != null) {
426                     Map idToNameMap = new HashMap();
427                     for (RADComponent comp : formModel.getAllComponents()) {
428                         idToNameMap.put(comp.getId(), comp.getName());
429                     }
430                     FormDataObject formDO = formDesigner.getFormEditor().getFormDataObject();
431                     LayoutTestUtils.writeTest(formDesigner, formDO, idToNameMap, layoutModel);
432                     LayoutDesigner ld = formDesigner.getLayoutDesigner();
433                     ld.setModelCounter(ld.getModelCounter() + 1);
434                 }
435             }
436         } else if (((keyCode == KeyEvent.VK_S)) && e.isAltDown() && e.isControlDown() && (e.getID() == KeyEvent.KEY_PRESSED)) {
437             // start layout test recording
438
if (LayoutDesigner.testMode()) {
439                 FormDataObject formDO = formDesigner.getFormEditor().getFormDataObject();
440                 FileObject formFile = formDO.getFormFile();
441                 SaveCookie saveCookie = (SaveCookie)formDO.getCookie(SaveCookie.class);
442                 try {
443                     if (saveCookie != null)
444                         saveCookie.save();
445                     FileObject copied = formFile.copy(LayoutTestUtils.getTargetFolder(formFile),
446                                 formFile.getName() + "Test-StartingForm", // NOI18N
447
formFile.getExt());
448                     formDesigner.getLayoutDesigner().setModelCounter(0);
449                     formDesigner.resetTopDesignComponent(true);
450                     StatusDisplayer.getDefault().setStatusText("The form was successfully copied to: " + copied.getPath()); // NOI18N
451
} catch (IOException JavaDoc ioe) {
452                     //TODO
453
}
454             }
455         }
456
457         super.processKeyEvent(e);
458     }
459
460     public boolean isFocusable() {
461         return true;
462     }
463
464     // -------
465

466     /**
467      * Returns metacomponent at given position.
468      * @param point - position on component layer
469      * @param mode - what to get:
470      * COMP_DEEPEST - get the deepest component
471      * COMP_SELECTED - get the deepest selected component
472      * COMP_ABOVE_SELECTED - get the component above the deepest selected component
473      * COMP_UNDER_SELECTED - get the component under the deepest selected component
474      * @returns the metacomponent at given point
475      * If no component is currently selected then:
476      * for COMP_SELECTED the deepest component is returned
477      * for COMP_ABOVE_SELECTED the deepest component is returned
478      * for COMP_UNDER_SELETCED the top component is returned
479      */

480     private RADComponent getMetaComponentAt(Point point, int mode) {
481         Component[] deepComps = getDeepestComponentsAt(
482                                     formDesigner.getComponentLayer(), point);
483         if (deepComps.length == 0)
484             return null;
485
486         int dIndex = mode == COMP_DEEPEST ? deepComps.length - 1 : 0;
487         Component comp = deepComps[dIndex];
488
489         // find the component satisfying point and mode
490
RADComponent topMetaComp = formDesigner.getTopDesignComponent();
491         RADComponent firstMetaComp = null;
492         RADComponent currMetaComp;
493         RADComponent prevMetaComp = null;
494
495         do {
496             currMetaComp = formDesigner.getMetaComponent(comp);
497             if (currMetaComp != null && !isDraggedComponent(currMetaComp)) {
498                 if (firstMetaComp == null)
499                     firstMetaComp = currMetaComp;
500
501                 switch (mode) {
502                     case COMP_DEEPEST:
503                         return currMetaComp;
504
505                     case COMP_SELECTED:
506                         if (formDesigner.isComponentSelected(currMetaComp))
507                             return currMetaComp;
508                         if (currMetaComp == topMetaComp)
509                             return firstMetaComp; // nothing selected - return the deepest
510
break;
511
512                     case COMP_ABOVE_SELECTED:
513                         if (prevMetaComp != null
514                                 && formDesigner.isComponentSelected(prevMetaComp))
515                             return currMetaComp;
516                         if (currMetaComp == topMetaComp)
517                             return firstMetaComp; // nothing selected - return the deepest
518
break;
519
520                     case COMP_UNDER_SELECTED:
521                         if (formDesigner.isComponentSelected(currMetaComp))
522                             return prevMetaComp != null ?
523                                      prevMetaComp : topMetaComp;
524                         if (currMetaComp == topMetaComp)
525                             return topMetaComp; // nothing selected - return the top
526
break;
527                 }
528
529                 prevMetaComp = currMetaComp;
530             }
531
532             comp = dIndex + 1 < deepComps.length ?
533                    deepComps[++dIndex] : comp.getParent();
534         }
535         while (comp != null);
536
537         return firstMetaComp;
538     }
539
540     // [TODO would be nice to rewrite this method not to produce garbage, it is
541
// called for each mouse move several times]
542
private static Component[] getDeepestComponentsAt(Container parent,
543                                                       Point point)
544     {
545         Component comp = SwingUtilities.getDeepestComponentAt(parent,
546                                                               point.x,
547                                                               point.y);
548         if (comp == null)
549             return new Component[0];
550
551         Container deepestParent = comp.getParent();
552         Component[] deepestComponents = deepestParent.getComponents();
553         Point deepestPosition =
554             SwingUtilities.convertPoint(parent, point, deepestParent);
555
556         // in most cases there will be just one component...
557
Component[] componentsAtPoint = new Component[1];
558         ArrayList compList = null;
559
560         for (int i=0; i < deepestComponents.length; i++) {
561             comp = deepestComponents[i];
562             Point p = comp.getLocation();
563             if (comp.isVisible()
564                 && comp.contains(deepestPosition.x - p.x,
565                                  deepestPosition.y - p.y))
566             {
567                 if (componentsAtPoint[0] == null)
568                     componentsAtPoint[0] = comp;
569                 else {
570                     if (compList == null) {
571                         compList = new ArrayList();
572                         compList.add(componentsAtPoint[0]);
573                     }
574                     compList.add(comp);
575                 }
576             }
577         }
578
579         if (compList == null)
580             return componentsAtPoint[0] != null ?
581                      componentsAtPoint : new Component[0];
582
583         componentsAtPoint = new Component[compList.size()];
584         compList.toArray(componentsAtPoint);
585         return componentsAtPoint;
586     }
587
588     RADVisualContainer getMetaContainerAt(Point point, int mode) {
589         RADComponent metacomp = getMetaComponentAt(point, mode);
590         if (metacomp == null)
591             return null;
592         if (metacomp instanceof RADVisualContainer)
593             return (RADVisualContainer) metacomp;
594         if (metacomp instanceof RADVisualComponent)
595             return (RADVisualContainer) metacomp.getParentComponent();
596         return null;
597     }
598
599     /** Selects component at the position e.getPoint() on component layer.
600      * What component is selected further depends on whether CTRL or ALT
601      * keys are hold. */

602     private RADComponent selectComponent(MouseEvent e) {
603         int selMode = !e.isAltDown() ? COMP_DEEPEST :
604                 (!e.isShiftDown() ? COMP_ABOVE_SELECTED : COMP_UNDER_SELECTED);
605
606         RADComponent hitMetaComp = getMetaComponentAt(e.getPoint(), selMode);
607
608         if ((e.isControlDown() || e.isShiftDown()) && !e.isAltDown()) {
609             // Control is pressed - add component to selection
610
if (hitMetaComp != null)
611                 if (formDesigner.isComponentSelected(hitMetaComp))
612                     formDesigner.removeComponentFromSelection(hitMetaComp);
613                 else
614                     formDesigner.addComponentToSelection(hitMetaComp);
615         }
616         // [interval selection commented out - is confusing if following just
617
// the creation order of components and not the visual appearance]
618
/* else if (e.isShiftDown() && !e.isAltDown()) {
619             // Shift is pressed - select interval
620             if (hitMetaComp != null
621                 && !formDesigner.isComponentSelected(hitMetaComp))
622             {
623                 if (formDesigner.getSelectedComponents().size() > 0) {
624                     RADComponent[] intervalToSelect =
625                         getComponentsIntervalToSelect(hitMetaComp, false);
626                     if (intervalToSelect == null)
627                         intervalToSelect = getComponentsIntervalToSelect(
628                                                        hitMetaComp, true);
629                     if (intervalToSelect != null)
630                         formDesigner.setSelectedComponents(intervalToSelect);
631                     else
632                         formDesigner.setSelectedComponent(hitMetaComp);
633                 }
634                 else
635                     formDesigner.setSelectedComponent(hitMetaComp);
636             }
637         } */

638         else { // no reasonable modifier key pressed - select single component
639
if (hitMetaComp != null) {
640                 if (!formDesigner.isComponentSelected(hitMetaComp))
641                     formDesigner.setSelectedComponent(hitMetaComp);
642             }
643             else formDesigner.clearSelection();
644         }
645
646         return hitMetaComp;
647     }
648
649 /* private RADComponent[] getComponentsIntervalToSelect(
650                              RADComponent clickedComp,
651                              boolean forward)
652     {
653         if (!(clickedComp instanceof RADVisualComponent))
654             return null;
655
656         java.util.List toSelect = new LinkedList();
657         RADVisualComponent comp = (RADVisualComponent) clickedComp;
658         boolean selected = false;
659
660         do // starting with clickedComp,
661         { // go forward/backward in components until a selected one is reached
662             if (forward)
663                 toSelect.add(comp);
664             else
665                 toSelect.add(0, comp);
666
667             comp = formDesigner.getNextVisualComponent(comp, forward);
668         }
669         while (comp != null && comp != clickedComp
670                && !(selected = formDesigner.isComponentSelected(comp))
671                && comp != formDesigner.getTopDesignComponent());
672
673         if (selected) { // selected component found - we can make the interval
674             if (comp == formDesigner.getTopDesignComponent()) {
675                 if (!forward) // top component is fine when going backward
676                     toSelect.add(0, comp);
677             }
678             else { // add also already selected components in the direction
679                 selected = false;
680                 do {
681                     if (forward)
682                         toSelect.add(comp);
683                     else
684                         toSelect.add(0, comp);
685
686                     comp = formDesigner.getNextVisualComponent(comp, forward);
687                 }
688                 while (comp != null
689                        && (selected = formDesigner.isComponentSelected(comp))
690                        && comp != formDesigner.getTopDesignComponent());
691
692                 if (selected && !forward)
693                     toSelect.add(0, comp); // top comp is fine when going backward
694             }
695
696             RADComponent[] compArray = new RADComponent[toSelect.size()];
697             toSelect.toArray(compArray);
698             return compArray;
699         }
700
701         return null;
702     } */

703
704     private void selectOtherComponentsNode() {
705         FormEditor formEditor = formDesigner.getFormEditor();
706         ComponentInspector ci = ComponentInspector.getInstance();
707         Node[] selectedNode = new Node[] {
708             ((FormRootNode)formEditor.getFormRootNode()).getOthersNode() };
709         
710         try {
711             ci.setSelectedNodes(selectedNode, formEditor);
712             formDesigner.clearSelectionImpl();
713             formDesigner.repaintSelection();
714         }
715         catch (java.beans.PropertyVetoException JavaDoc ex) {
716             org.openide.ErrorManager.getDefault().notify(
717                 org.openide.ErrorManager.INFORMATIONAL, ex);
718         }
719
720         formDesigner.setActivatedNodes(selectedNode);
721     }
722
723     private boolean processDoubleClick(MouseEvent e) {
724         if (e.isShiftDown() || e.isControlDown())
725             return false;
726
727         RADComponent metacomp = getMetaComponentAt(e.getPoint(), COMP_SELECTED);
728         if (metacomp == null)
729             return true;
730
731         if (e.isAltDown()) {
732              if (metacomp == formDesigner.getTopDesignComponent()) {
733                 metacomp = metacomp.getParentComponent();
734                 if (metacomp == null)
735                     return true;
736             }
737              else return false;
738         }
739
740         formDesigner.startInPlaceEditing(metacomp);
741
742         // [perhaps we should remove the default action from node completely]
743
// Node node = metacomp.getNodeReference();
744
// if (node != null) {
745
// Action action = node.getPreferredAction();
746
// if (action != null) {// && action.isEnabled()) {
747
// action.actionPerformed(new ActionEvent(
748
// node, ActionEvent.ACTION_PERFORMED, "")); // NOI18N
749
// }
750
// }
751

752         return true;
753     }
754
755     private void processMouseClickInLayoutSupport(RADComponent metacomp,
756                                                   MouseEvent e)
757     {
758         if (!(metacomp instanceof RADVisualComponent))
759             return;
760
761         RADVisualContainer metacont = metacomp instanceof RADVisualContainer ?
762             (RADVisualContainer) metacomp :
763             (RADVisualContainer) metacomp.getParentComponent();
764         LayoutSupportManager laysup = metacont != null ?
765                                       metacont.getLayoutSupport() : null;
766         if (laysup == null)
767             return;
768
769         Container cont = (Container) formDesigner.getComponent(metacont);
770         Container contDelegate = metacont.getContainerDelegate(cont);
771         Point p = convertPointToComponent(e.getPoint(), contDelegate);
772         laysup.processMouseClick(p, cont, contDelegate);
773     }
774
775     private void showContextMenu(Point popupPos) {
776         ComponentInspector inspector = ComponentInspector.getInstance();
777         TopComponent activated = TopComponent.getRegistry().getActivated();
778         if (activated != formDesigner.multiViewObserver.getTopComponent()
779                 && activated != inspector)
780             return;
781
782         formDesigner.componentActivated(); // just for sure...
783

784         Node[] selectedNodes = inspector.getSelectedNodes();
785         JPopupMenu popup = NodeOp.findContextMenu(selectedNodes);
786         if (popup != null) {
787             popup.show(HandleLayer.this, popupPos.x, popupPos.y);
788         }
789     }
790
791     // --------
792

793     private boolean anyDragger() {
794         return draggedComponent != null || selectionDragger != null;
795     }
796
797     private RADVisualComponent[] getComponentsToDrag() {
798         // all selected components must be visible in the designer and have the
799
// same parent; redundant sub-contained components must be filtered out
800
java.util.List JavaDoc selectedComps = formDesigner.getSelectedComponents();
801         java.util.List JavaDoc workingComps = new ArrayList(selectedComps.size());
802         RADVisualContainer parent = null;
803
804         for (Iterator it = selectedComps.iterator(); it.hasNext(); ) {
805             RADComponent metacomp = (RADComponent) it.next();
806             if (!(metacomp instanceof RADVisualComponent)) continue;
807             boolean subcontained = false;
808             for (Iterator it2 = selectedComps.iterator(); it2.hasNext(); ) {
809                 RADComponent metacomp2 = (RADComponent) it2.next();
810                 if (metacomp2 != metacomp && metacomp2.isParentComponent(metacomp)) {
811                     subcontained = true;
812                     break;
813                 }
814             }
815             if (!subcontained) {
816                 RADVisualContainer metacont =
817                     (RADVisualContainer) metacomp.getParentComponent();
818                 
819                 if (substituteForContainer(metacont)) {
820                     // hack: if trying to drag something in scrollpane,
821
// drag the whole scrollpane instead
822
metacomp = metacont;
823                     metacont = (RADVisualContainer) metacomp.getParentComponent();
824                 }
825
826                 if (parent != null) {
827                     if (parent != metacont)
828                         return null; // components in different containers
829
}
830                 else {
831                     if (metacont == null
832                         || !formDesigner.getTopDesignComponent().isParentComponent(metacomp))
833                     { // out of visible tree
834
return null;
835                     }
836                     parent = metacont;
837                 }
838                 workingComps.add(metacomp);
839             }
840         }
841
842         return workingComps.isEmpty() ? null : (RADVisualComponent[])
843             workingComps.toArray(new RADVisualComponent[workingComps.size()]);
844     }
845
846     boolean endDragging(MouseEvent e) {
847         if (!anyDragger())
848             return false;
849
850         if (resizeType != 0) {
851             resizeType = 0;
852             Cursor cursor = getCursor();
853             if (cursor != null && cursor.getType() != Cursor.DEFAULT_CURSOR)
854                 setCursor(Cursor.getDefaultCursor());
855             if (getToolTipText() != null)
856                 setToolTipText(null);
857         }
858
859         boolean done = true;
860
861         if (draggedComponent != null) {
862             boolean retVal = true;
863             try {
864                 retVal = draggedComponent.end(e);
865             } finally {
866                 if (retVal) {
867                     draggedComponent = null;
868                     draggingEnded = true;
869                 } else {
870                     done = false;
871                 }
872             }
873         }
874         else if (selectionDragger != null) {
875             if (e != null)
876                 selectionDragger.drop(e.getPoint());
877             selectionDragger = null;
878 // repaint();
879
}
880
881         if (done) {
882             draggingEnded = true;
883             StatusDisplayer.getDefault().setStatusText(""); // NOI18N
884
}
885
886         FormEditor.getAssistantModel(getFormModel()).setContext("select"); // NOI18N
887
return done;
888     }
889
890     private boolean isDraggedComponent(RADComponent metacomp) {
891         if (draggedComponent != null && draggedComponent.movingComponents != null) {
892             for (RADComponent c : draggedComponent.movingComponents) {
893                 if (c == metacomp || c.isParentComponent(metacomp))
894                     return true;
895             }
896         }
897         return false;
898     }
899
900     // Highlighted panel
901
private JPanel darkerPanel = null;
902     private static class HighlightBorder extends javax.swing.border.LineBorder JavaDoc {
903         HighlightBorder(Color color, int thickness) {
904             super(color, thickness);
905         }
906
907         public Insets getBorderInsets(Component c) {
908             // Hack - don't affect component's content
909
return new Insets(0, 0, 0, 0);
910         }
911     }
912     
913     // Highlights panel below mouse cursor.
914
private void highlightPanel(MouseEvent e, boolean recheck) {
915         Component[] comps = getDeepestComponentsAt(formDesigner.getComponentLayer(), e.getPoint());
916         if (comps.length == 0)
917             return;
918         Component comp = comps[comps.length-1];
919         RADComponent radcomp = formDesigner.getMetaComponent(comp);
920         if ((radcomp != null) && !(radcomp instanceof RADVisualContainer)) {
921             radcomp = radcomp.getParentComponent();
922             comp = radcomp != null ? (Component)formDesigner.getComponent(radcomp) : null;
923         }
924         if ((radcomp == null) || (radcomp == formDesigner.getTopDesignComponent())
925             || (!(comp instanceof JPanel))) {
926             comp = null;
927         }
928         JPanel panel = (JPanel)comp;
929         if ((darkerPanel != panel) || (recheck && !shouldHighlightPanel(panel, radcomp))) {
930             if (darkerPanel != null) {
931                 // Reset only HighlightBorder border
932
if (darkerPanel.getBorder() instanceof HighlightBorder) {
933                     darkerPanel.setBorder(null);
934                 }
935                 darkerPanel = null;
936             }
937             if (shouldHighlightPanel(panel, radcomp)) {
938                 panel.setBorder(new HighlightBorder(darkerPanelColor(panel.getBackground()), 1));
939                 darkerPanel = panel;
940             }
941         }
942     }
943     
944     private boolean shouldHighlightPanel(JPanel panel, RADComponent radPanel) {
945         if (panel != null) {
946             if (panel.getBorder() != null) { // Maybe we should highlight also panels with EmptyBorder
947
return false;
948             }
949             if (!(panel.getBackground() instanceof javax.swing.plaf.UIResource JavaDoc)) {
950                 return false;
951             }
952             if (radPanel == formDesigner.getTopDesignComponent()) {
953                 return false;
954             }
955             if ((formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT)
956                 && formDesigner.getSelectedLayoutComponents().contains(radPanel)) {
957                 return false;
958             }
959             if (radPanel instanceof RADVisualContainer) {
960                 RADVisualContainer metacont = (RADVisualContainer)radPanel;
961                 RADVisualContainer parent = metacont.getParentContainer();
962                 if (parent != null) {
963                     LayoutSupportManager manager = parent.getLayoutSupport();
964                     if ((manager != null) && manager.isDedicated()) {
965                         return false;
966                     }
967                     JPanel realPanel = (JPanel)formDesigner.getComponent(radPanel);
968                     Component parentBean = (Component)parent.getBeanInstance();
969                     Component realParent = (Component)formDesigner.getComponent(parent);
970                     if (realParent.getSize().equals(realPanel.getSize()) && realPanel.getLocation().equals(new Point(0,0))) {
971                         if (parentBean instanceof JPanel) {
972                             return shouldHighlightPanel((JPanel)parentBean, parent);
973                         } else {
974                             return false;
975                         }
976                     }
977                 }
978             }
979         }
980         return (panel != null);
981     }
982     
983     private static Color darkerPanelColor(Color color) {
984         double factor = 0.9;
985     return new Color((int)(color.getRed()*factor),
986              (int)(color.getGreen()*factor),
987              (int)(color.getBlue()*factor));
988     }
989
990     // Check the mouse cursor if it is at position where a component or the
991
// designer can be resized. Change mouse cursor accordingly.
992
private void checkResizing(MouseEvent e) {
993         if (formDesigner.getTopDesignComponent() == null) return; // bean forms
994
int resizing = checkComponentsResizing(e);
995         if (resizing == 0) {
996             resizing = checkDesignerResizing(e);
997             if (resizing == 0) {
998                 if (getToolTipText() != null)
999                     setToolTipText(null);
1000            }
1001            else if (getToolTipText() == null) {
1002                Dimension size = formDesigner.getComponentLayer()
1003                                               .getDesignerSize();
1004                
1005                MessageFormat JavaDoc mf;
1006                if(viewOnly) {
1007                    if (sizeHintFormat == null){
1008                        sizeHintFormat = new MessageFormat JavaDoc(
1009                            FormUtils.getBundleString("FMT_HINT_DesignerSize")); // NOI18N
1010
}
1011                    mf = sizeHintFormat;
1012                } else {
1013                    if (resizingHintFormat == null){
1014                        resizingHintFormat = new MessageFormat JavaDoc(
1015                            FormUtils.getBundleString("FMT_HINT_DesignerResizing")); // NOI18N
1016
}
1017                    mf = resizingHintFormat;
1018                }
1019                   
1020                String JavaDoc hint = mf.format(
1021                                new Object JavaDoc[] { new Integer JavaDoc(size.width),
1022                                               new Integer JavaDoc(size.height) });
1023                setToolTipText(hint);
1024                ToolTipManager.sharedInstance().mouseEntered(e);
1025            }
1026        }
1027        else if (getToolTipText() != null)
1028            setToolTipText(null);
1029
1030        if (resizing != 0 && !viewOnly)
1031            setResizingCursor(resizing);
1032        else {
1033            Cursor cursor = getCursor();
1034            if (cursor != null && cursor.getType() != Cursor.DEFAULT_CURSOR)
1035                setCursor(Cursor.getDefaultCursor());
1036        }
1037    }
1038
1039    // Check the mouse cursor if it is at position where designer can be
1040
// resized.
1041
private int checkDesignerResizing(MouseEvent e) {
1042        if (!e.isAltDown() && !e.isControlDown() && !e.isShiftDown()) {
1043            ComponentLayer compLayer = formDesigner.getComponentLayer();
1044            int resizing = getSelectionResizable(
1045                             e.getPoint(),
1046                             compLayer.getComponentContainer(),
1047                             compLayer.getDesignerOutsets().right + 2);
1048
1049            resizeType = validDesignerResizing(resizing) ?
1050                         resizing | DESIGNER_RESIZING : 0;
1051        }
1052        else resizeType = 0;
1053
1054        return resizeType;
1055    }
1056
1057    // Check whether given resize type is valid for designer.
1058
private boolean validDesignerResizing(int resizing) {
1059        return resizing == (LayoutSupportManager.RESIZE_DOWN
1060                            | LayoutSupportManager.RESIZE_RIGHT)
1061            || resizing == LayoutSupportManager.RESIZE_DOWN
1062            || resizing == LayoutSupportManager.RESIZE_RIGHT;
1063    }
1064
1065    // Check the mouse cursor if it is at position where a component (or more
1066
// components) can be resized.
1067
private int checkComponentsResizing(MouseEvent e) {
1068        resizeType = 0;
1069        if (e.isAltDown() || e.isControlDown() || e.isShiftDown()) {
1070            return 0;
1071        }
1072
1073        // check selected components whether they are in the same container
1074
if (!selectedComponentsInSameVisibleContainer())
1075            return 0;
1076
1077        Point p = e.getPoint();
1078        RADComponent compAtPoint = selectedComponentAt(p, 6);
1079
1080        if (!(compAtPoint instanceof RADVisualComponent))
1081            return 0;
1082
1083/* if (!formDesigner.isComponentSelected(compAtPoint)) {
1084            // not on a selected component, but some might be near
1085            RADVisualComponent[] otherComps;
1086            if (compAtPoint instanceof RADVisualContainer) {
1087                otherComps = ((RADVisualContainer)compAtPoint).getSubComponents();
1088            }
1089            else {
1090                RADVisualContainer metacont = (RADVisualContainer)
1091                                              compAtPoint.getParentComponent();
1092                if (metacont != null)
1093                    otherComps = metacont.getSubComponents();
1094                else
1095                    return 0; // component without a parent
1096            }
1097
1098            for (int i=0; i < otherComps.length; i++) {
1099                if (formDesigner.isComponentSelected(otherComps[i])) {
1100                    resizeType = getComponentResizable(p, otherComps[i]);
1101                    if (resizeType != 0)
1102                        break;
1103                }
1104            }
1105        }
1106        else { // mouse on selected component */

1107            resizeType = getComponentResizable(p, (RADVisualComponent)compAtPoint);
1108// }
1109

1110        return resizeType;
1111    }
1112
1113    private boolean selectedComponentsInSameVisibleContainer() {
1114        RADComponent parent = null;
1115        Iterator selected = formDesigner.getSelectedComponents().iterator();
1116        while (selected.hasNext()) {
1117            RADComponent comp = formDesigner.componentToLayoutComponent((RADComponent)selected.next());
1118            if (comp == null)
1119                return false; // not visible in designer
1120
if (parent == null) {
1121                parent = comp.getParentComponent();
1122                if (!formDesigner.isInDesignedTree(parent))
1123                    return false; // not visible in designer
1124
}
1125            else if (comp.getParentComponent() != parent) {
1126                return false; // different parent
1127
}
1128        }
1129        return true;
1130    }
1131
1132    // Returns selected component at the given point (even outside the designer area).
1133
private RADComponent selectedComponentAt(Point p, int borderSize) {
1134        RADComponent compAtPoint = null;
1135        Iterator selected = formDesigner.getSelectedLayoutComponents().iterator();
1136        while (selected.hasNext()) {
1137            RADComponent metacomp = (RADComponent) selected.next();
1138            Component comp = (Component)formDesigner.getComponent(metacomp);
1139            if (comp == null || comp.getParent() == null)
1140                continue; // might be not added yet after move operation
1141
Rectangle rect = new Rectangle(-borderSize, -borderSize, comp.getWidth()+2*borderSize, comp.getHeight()+2*borderSize);
1142            convertRectangleFromComponent(rect, comp);
1143            if (rect.contains(p)) {
1144                compAtPoint = metacomp;
1145            }
1146        }
1147        return compAtPoint;
1148    }
1149
1150    // Check how possible component resizing (obtained from layout support)
1151
// matches with mouse position on component selection border.
1152
private int getComponentResizable(Point p, RADVisualComponent metacomp) {
1153// RADVisualContainer metacont = metacomp.getParentContainer();
1154
// if (substituteForContainer(metacont)) {
1155
// metacomp = metacont;
1156
// metacont = metacomp.getParentContainer();
1157
// }
1158

1159        int resizable = getComponentResizable(metacomp);
1160        if (resizable != 0) {
1161            Component comp = (Component) formDesigner.getComponent(metacomp);
1162            resizable &= getSelectionResizable(p, comp, 6);
1163        }
1164
1165        return resizable;
1166    }
1167    
1168    private int getComponentResizable(RADVisualComponent metacomp) {
1169        RADVisualContainer metacont = metacomp.getParentContainer();
1170        if (metacont == null || metacomp == formDesigner.getTopDesignComponent()) {
1171            return 0;
1172        }
1173        Component comp = (Component) formDesigner.getComponent(metacomp);
1174        int resizable;
1175        LayoutSupportManager laySup = metacont.getLayoutSupport();
1176        if (laySup == null) { // new layout support
1177
java.util.List JavaDoc selectedComps = formDesigner.getSelectedComponents();
1178            if (selectedComps.size() == 1) {
1179                // [real resizability spec TBD]
1180
resizable = LayoutSupportManager.RESIZE_LEFT
1181                            | LayoutSupportManager.RESIZE_RIGHT
1182                            | LayoutSupportManager.RESIZE_UP
1183                            | LayoutSupportManager.RESIZE_DOWN;
1184            }
1185            else resizable = 0;
1186        }
1187        else { // old layout support
1188
Container cont = (Container) formDesigner.getComponent(metacont);
1189            Container contDel = metacont.getContainerDelegate(cont);
1190
1191            resizable = laySup.getResizableDirections(
1192                                       cont, contDel,
1193                                       comp, metacont.getIndexOf(metacomp));
1194        }
1195        return resizable;
1196    }
1197
1198    // Compute possible resizing directions according to mouse position on
1199
// component selection border.
1200
private int getSelectionResizable(Point p, Component comp, int borderWidth) {
1201        if (comp == null)
1202            return 0;
1203
1204        int resizable = 0;
1205
1206        Rectangle r = new Rectangle(0, 0, comp.getWidth(), comp.getHeight());
1207        convertRectangleFromComponent(r, comp);
1208        r.grow(borderWidth, borderWidth);
1209        if (r.contains(p)) {
1210            r.grow(-borderWidth, -borderWidth);
1211            r.grow(-3, -3);
1212            if (r.width < 0)
1213                r.width = 0;
1214            if (r.height < 0)
1215                r.height = 0;
1216
1217            if (p.y >= r.y + r.height)
1218                resizable |= LayoutSupportManager.RESIZE_DOWN;
1219            else if (p.y < r.y)
1220                resizable |= LayoutSupportManager.RESIZE_UP;
1221            if (p.x >= r.x + r.width)
1222                resizable |= LayoutSupportManager.RESIZE_RIGHT;
1223            else if (p.x < r.x)
1224                resizable |= LayoutSupportManager.RESIZE_LEFT;
1225        }
1226
1227        return resizable;
1228    }
1229
1230    private void setResizingCursor(int resizeType) {
1231        Cursor cursor = null;
1232        if ((resizeType & LayoutSupportManager.RESIZE_UP) != 0) {
1233            if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0)
1234                cursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
1235            else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0)
1236                cursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
1237            else
1238                cursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
1239        }
1240        else if ((resizeType & LayoutSupportManager.RESIZE_DOWN) != 0) {
1241            if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0)
1242                cursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
1243            else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0)
1244                cursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
1245            else
1246                cursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
1247        }
1248        else if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0)
1249            cursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
1250        else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0)
1251            cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
1252
1253        if (cursor == null)
1254            cursor = Cursor.getDefaultCursor();
1255
1256        setCursor(cursor);
1257    }
1258
1259    private void setUserDesignerSize() {
1260        NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine(
1261            FormUtils.getBundleString("CTL_SetDesignerSize_Label"), // NOI18N
1262
FormUtils.getBundleString("CTL_SetDesignerSize_Title")); // NOI18N
1263
Dimension size = formDesigner.getComponentLayer().getDesignerSize();
1264        input.setInputText(Integer.toString(size.width) + ", " // NOI18N
1265
+ Integer.toString(size.height));
1266
1267        if (DialogDisplayer.getDefault().notify(input) == NotifyDescriptor.OK_OPTION) {
1268            String JavaDoc txt = input.getInputText();
1269            int i = txt.indexOf(',');
1270            if (i > 0) {
1271                int n = txt.length();
1272                try {
1273                    int w = Integer.parseInt(txt.substring(0, i));
1274                    while (++i < n && txt.charAt(i) == ' ');
1275                    int h = Integer.parseInt(txt.substring(i, n));
1276                    if (w >= 0 && h >= 0) {
1277                        size = new Dimension(w ,h);
1278                        formDesigner.setDesignerSize(size, null);
1279                        setToolTipText(null);
1280                        setCursor(Cursor.getDefaultCursor());
1281                    }
1282                }
1283                catch (NumberFormatException JavaDoc ex) {} // silently ignore, do nothing
1284
}
1285        }
1286    }
1287
1288    private Object JavaDoc getConstraintsAtPoint(RADComponent metacomp, Point point, Point hotSpot) {
1289        if (!(metacomp instanceof RADVisualComponent))
1290            return null;
1291
1292        RADVisualContainer metacont = metacomp instanceof RADVisualContainer ?
1293            (RADVisualContainer) metacomp :
1294            (RADVisualContainer) metacomp.getParentComponent();
1295        LayoutSupportManager laysup = metacont != null ?
1296                                      metacont.getLayoutSupport() : null;
1297
1298            Container cont = (Container) formDesigner.getComponent(metacont);
1299            Container contDel = metacont.getContainerDelegate(cont);
1300            Point p = convertPointToComponent(point.x, point.y, contDel);
1301            Object JavaDoc constraints = laysup.getNewConstraints(cont, contDel, null, -1, p, hotSpot);
1302            if ((constraints == null) && metacomp.getBeanInstance() instanceof Component) {
1303                int index = laysup.getNewIndex(cont, contDel, (Component)metacomp.getBeanInstance(), -1, p, hotSpot);
1304                if (index != -1) {
1305                    constraints = new Integer JavaDoc(index);
1306                }
1307            }
1308            return constraints;
1309    }
1310
1311    private static boolean substituteForContainer(RADVisualContainer metacont) {
1312        return metacont != null
1313               && metacont.getBeanClass().isAssignableFrom(JScrollPane.class)
1314               && metacont.getSubComponents().length > 0;
1315    }
1316
1317    // ------
1318

1319    boolean mouseOnVisual(Point p) {
1320        Rectangle r = formDesigner.getComponentLayer().getDesignerOuterBounds();
1321        return r.contains(p);
1322    }
1323    
1324    /**
1325     * Determines whether the passed point is above the non-visual tray.
1326     *
1327     * @return <code>true</code> if the point is above the non-visual tray,
1328     * returns <code>false</code> otherwise.
1329     */

1330    boolean mouseOnNonVisualTray(Point p) {
1331        Component tray = formDesigner.getNonVisualTray();
1332        return tray != null ? tray.getBounds().contains(p) : false;
1333    }
1334
1335    // NOTE: does not create a new Point instance
1336
private Point convertPointFromComponent(Point p, Component sourceComp) {
1337        return formDesigner.pointFromComponentToHandleLayer(p, sourceComp);
1338    }
1339
1340    private Point convertPointFromComponent(int x, int y, Component sourceComp) {
1341        return formDesigner.pointFromComponentToHandleLayer(new Point(x, y), sourceComp);
1342    }
1343
1344    // NOTE: does not create a new Point instance
1345
private Point convertPointToComponent(Point p, Component targetComp) {
1346        return formDesigner.pointFromHandleToComponentLayer(p, targetComp);
1347    }
1348
1349    private Point convertPointToComponent(int x, int y, Component targetComp) {
1350        return formDesigner.pointFromHandleToComponentLayer(new Point(x, y), targetComp);
1351    }
1352
1353    // NOTE: does not create a new Rectangle instance
1354
private Rectangle convertRectangleFromComponent(Rectangle rect,
1355                                                    Component sourceComp)
1356    {
1357        Point p = convertPointFromComponent(rect.x, rect.y, sourceComp);
1358        rect.x = p.x;
1359        rect.y = p.y;
1360        return rect;
1361    }
1362
1363    // NOTE: does not create a new Rectangle instance
1364
Rectangle convertRectangleToComponent(Rectangle rect,
1365                                                  Component targetComp)
1366    {
1367        Point p = convertPointToComponent(rect.x, rect.y, targetComp);
1368        rect.x = p.x;
1369        rect.y = p.y;
1370        return rect;
1371    }
1372
1373    Rectangle convertVisibleRectangleFromComponent(Rectangle rect, Component comp) {
1374        Component parent;
1375        while (!formDesigner.isCoordinatesRoot(comp)) {
1376            parent = comp.getParent();
1377            Rectangle size = new Rectangle(0, 0, parent.getWidth(), parent.getHeight());
1378            rect.translate(comp.getX(), comp.getY());
1379            rect = rect.intersection(size);
1380            comp = parent;
1381        }
1382        comp = this;
1383        while (!formDesigner.isCoordinatesRoot(comp)) {
1384            rect.translate(-comp.getX(), -comp.getY());
1385            comp = comp.getParent();
1386        }
1387        return rect;
1388    }
1389    
1390    
1391    // ---------
1392
// MouseListener implementation
1393

1394    public void mouseClicked(MouseEvent e) {
1395        if (SwingUtilities.isRightMouseButton(e)
1396            && !draggingEnded && !endDragging(null))
1397        {
1398            if (mouseOnNonVisualTray(e.getPoint())) {
1399                dispatchToNonVisualTray(e);
1400            } else {
1401                showContextMenu(e.getPoint());
1402            }
1403        }
1404        highlightPanel(e, true);
1405        e.consume();
1406    }
1407
1408    public void mouseReleased(MouseEvent e) {
1409        if (!HandleLayer.this.isVisible())
1410            return;
1411
1412        if (SwingUtilities.isLeftMouseButton(e)) {
1413            if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT
1414                && !draggingEnded && !endDragging(e))
1415            { // there was no dragging, so mouse release may have other meaning
1416
boolean modifier = e.isControlDown() || e.isAltDown() || e.isShiftDown();
1417                if ((resizeType & DESIGNER_RESIZING) != 0
1418                    && e.getClickCount() == 2
1419                    && !modifier
1420                    && !viewOnly)
1421                { // doubleclick on designer's resizing border
1422
setUserDesignerSize();
1423                } else if (mouseOnNonVisualTray(e.getPoint())) {
1424                    dispatchToNonVisualTray(e);
1425                }
1426                else if (prevLeftMousePoint != null
1427                         && e.getClickCount() == 1
1428                         && prevLeftMousePoint.distance(e.getPoint()) <= 2
1429                         && !modifier)
1430                { // second click on the same place in a component
1431
RADComponent metacomp = getMetaComponentAt(e.getPoint(), COMP_SELECTED);
1432                    if (metacomp != null) {
1433                        formDesigner.startInPlaceEditing(metacomp);
1434                    }
1435                }
1436                else if (e.getClickCount() == 1
1437                         && e.isShiftDown()
1438                         && !e.isAltDown()
1439                         && !e.isControlDown())
1440                { // Shift + mouse release - interval selection
1441
selectComponent(e);
1442                }
1443            }
1444
1445            prevLeftMousePoint = lastLeftMousePoint;
1446            lastLeftMousePoint = null;
1447        } else if (mouseOnNonVisualTray(e.getPoint())) {
1448            dispatchToNonVisualTray(e);
1449        }
1450
1451        e.consume();
1452    }
1453
1454    public void mouseEntered(MouseEvent e) {
1455        if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) {
1456            formDesigner.requestActive();
1457            PaletteItem item = PaletteUtils.getSelectedItem();
1458            if( null != item ) {
1459                StatusDisplayer.getDefault().setStatusText(
1460                    FormUtils.getFormattedBundleString(
1461                        "FMT_MSG_AddingComponent", // NOI18N
1462
new String JavaDoc[] { item.getNode().getDisplayName() }));
1463            }
1464        }
1465    }
1466
1467    public void mouseExited(MouseEvent e) {
1468        if (draggedComponent != null && formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) {
1469            draggedComponent.move(null);
1470            repaint();
1471            StatusDisplayer.getDefault().setStatusText(""); // NOI18N
1472
}
1473    }
1474
1475    public void mousePressed(MouseEvent e) {
1476        formDesigner.componentActivated();
1477        if (!HandleLayer.this.isVisible())
1478            return;
1479
1480        if (SwingUtilities.isRightMouseButton(e)) {
1481            if (formDesigner.getDesignerMode() != FormDesigner.MODE_SELECT) {
1482                formDesigner.toggleSelectionMode(); // calls endDragging(null)
1483
repaint();
1484            }
1485            else if (endDragging(null)) { // there was dragging, now canceled
1486
repaint();
1487            }
1488            else if (!SwingUtilities.isLeftMouseButton(e)) {
1489                // no dragging, ensure a component is selected for conext menu
1490
if (mouseOnNonVisualTray(e.getPoint())) {
1491                    dispatchToNonVisualTray(e);
1492                } else if (!mouseOnVisual(e.getPoint())) {
1493                    selectOtherComponentsNode();
1494                }
1495                else { // select component only if there is nothing selected on current position
1496
RADComponent hitMetaComp =
1497                        getMetaComponentAt(e.getPoint(), COMP_SELECTED);
1498                    if (!formDesigner.isComponentSelected(hitMetaComp)) {
1499                        formDesigner.setSelectedComponent(hitMetaComp);
1500                    }
1501                    processMouseClickInLayoutSupport(hitMetaComp, e);
1502                }
1503                draggingEnded = false; // reset flag preventing dragging from start
1504
}
1505            e.consume();
1506        }
1507        else if (SwingUtilities.isLeftMouseButton(e)) {
1508            lastLeftMousePoint = e.getPoint();
1509
1510            boolean modifier = e.isControlDown() || e.isAltDown() || e.isShiftDown();
1511
1512            if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT) {
1513                if (mouseOnNonVisualTray(e.getPoint())) {
1514                    dispatchToNonVisualTray(e);
1515                } else {
1516                checkResizing(e);
1517                if (!(e.isShiftDown() && e.isAltDown() && e.isControlDown())) {
1518                    // mouse not pressed with Shift only (which is reserved for
1519
// interval or area selection - applied on mouse release or
1520
// mouse dragged)
1521
if (!mouseOnVisual(lastLeftMousePoint)) {
1522                        if ((resizeType == 0) && (selectedComponentAt(lastLeftMousePoint, 0) == null))
1523                            selectOtherComponentsNode();
1524                    }
1525                    else if (resizeType == 0
1526                             && (e.getClickCount() != 2
1527                                 || !processDoubleClick(e))
1528                             && (!e.isShiftDown() || e.isAltDown())) // selection with shift only on mouse release
1529
{ // no resizing, no doubleclick - select component
1530
RADComponent hitMetaComp = selectComponent(e);
1531                        if (hitMetaComp != null && !modifier) // plain single click
1532
processMouseClickInLayoutSupport(hitMetaComp, e);
1533                    }
1534                }
1535                }
1536// endDragging(null); // for sure
1537
draggingEnded = false; // reset flag preventing dragging from start
1538
}
1539            else if (!viewOnly) { // form can be modified
1540
if (formDesigner.getDesignerMode() == FormDesigner.MODE_CONNECT) {
1541                    selectComponent(e);
1542                }
1543                else if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) {
1544                    endDragging(e);
1545                    if (!e.isShiftDown()) {
1546                        formDesigner.toggleSelectionMode();
1547                    }
1548                    // otherwise stay in adding mode
1549
}
1550            }
1551            e.consume();
1552        }
1553    }
1554
1555    // ---------
1556
// MouseMotionListener implementation
1557

1558    public void mouseDragged(MouseEvent e) {
1559        if (formDesigner.getDesignerMode() != FormDesigner.MODE_SELECT)
1560            return; // dragging makes sense only selection mode
1561

1562        Point p = e.getPoint();
1563        if (lastMousePosition != null) {
1564            lastXPosDiff = p.x - lastMousePosition.x;
1565            lastYPosDiff = p.y - lastMousePosition.y;
1566        }
1567
1568        if (!draggingEnded && !anyDragger() && lastLeftMousePoint != null) { // no dragging yet
1569
if (!viewOnly
1570                 && !e.isControlDown() && (!e.isShiftDown() || e.isAltDown())
1571                 && (resizeType != 0 || lastLeftMousePoint.distance(p) > 6))
1572            { // start component dragging
1573
RADVisualComponent[] draggedComps =
1574                    (resizeType & DESIGNER_RESIZING) == 0 ? getComponentsToDrag() :
1575                    new RADVisualComponent[] { formDesigner.getTopDesignComponent() };
1576                if (draggedComps != null) {
1577                    if (resizeType == 0) {
1578                        draggedComponent = new ExistingComponentDrag(
1579                            draggedComps, lastLeftMousePoint, e.getModifiers());
1580                    }
1581                    else {
1582                        draggedComponent = new ResizeComponentDrag(
1583                            draggedComps, lastLeftMousePoint, resizeType&~DESIGNER_RESIZING);
1584                    }
1585                }
1586            }
1587            if (draggedComponent == null // component dragging has not started
1588
&& formDesigner.getTopDesignComponent() instanceof RADVisualContainer
1589                && lastLeftMousePoint.distance(p) > 4
1590                && !e.isAltDown() && !e.isControlDown()
1591                && (e.isShiftDown() || getMetaComponentAt(lastLeftMousePoint, COMP_DEEPEST)
1592                                       == formDesigner.getTopDesignComponent()))
1593            { // start selection dragging
1594
selectionDragger = new SelectionDragger(lastLeftMousePoint);
1595            }
1596        }
1597
1598        if (draggedComponent != null) {
1599            draggedComponent.move(e);
1600            highlightPanel(e, false);
1601            repaint();
1602        }
1603        else if (selectionDragger != null) {
1604            selectionDragger.drag(p);
1605            repaint();
1606        }
1607
1608        lastMousePosition = p;
1609        e.consume();
1610    }
1611
1612    public void mouseMoved(MouseEvent e) {
1613        Point p = e.getPoint();
1614        if (lastMousePosition != null) {
1615            lastXPosDiff = p.x - lastMousePosition.x;
1616            lastYPosDiff = p.y - lastMousePosition.y;
1617        }
1618        if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) {
1619            PaletteItem item = PaletteUtils.getSelectedItem();
1620            if( null == item ) {
1621                if( null != draggedComponent ) {
1622                    endDragging( e );
1623                }
1624                return;
1625            }
1626            if (draggedComponent == null) {
1627                // first move event, pre-create visual component to be added
1628
if ((item.getComponentClassName().indexOf('.') == -1) // Issue 79573
1629
&& (!FormJavaSource.isInDefaultPackage(getFormModel()))) {
1630                    String JavaDoc message = FormUtils.getBundleString("MSG_DefaultPackageBean"); // NOI18N
1631
NotifyDescriptor nd = new NotifyDescriptor.Message(message, NotifyDescriptor.WARNING_MESSAGE);
1632                    DialogDisplayer.getDefault().notify(nd);
1633                    formDesigner.toggleSelectionMode();
1634                    return;
1635                }
1636                draggedComponent = new NewComponentDrag( item );
1637            }
1638            draggedComponent.move(e);
1639            repaint();
1640        }
1641        else if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT
1642                 && !anyDragger())
1643        {
1644            checkResizing(e);
1645        }
1646        highlightPanel(e, false);
1647        lastMousePosition = p;
1648    }
1649
1650    /**
1651     * Dispatches the mouse event to the non-visual tray.
1652     *
1653     * @param e the event to dispatch.
1654     */

1655    private void dispatchToNonVisualTray(final MouseEvent e) {
1656        NonVisualTray tray = formDesigner.getNonVisualTray();
1657        if (tray == null) {
1658            return;
1659        }
1660        Point point = SwingUtilities.convertPoint(this, e.getPoint(), tray);
1661        Component component = SwingUtilities.getDeepestComponentAt(tray, point.x, point.y);
1662        point = SwingUtilities.convertPoint(tray, point, component);
1663        component.dispatchEvent(new MouseEvent(
1664            component,
1665            e.getID(),
1666            e.getWhen(),
1667            e.getModifiers(),
1668            point.x,
1669            point.y,
1670            e.getClickCount(),
1671            e.isPopupTrigger()));
1672    }
1673
1674    public String JavaDoc getToolTipText(MouseEvent e) {
1675        if (mouseOnNonVisualTray(e.getPoint())) {
1676            NonVisualTray tray = formDesigner.getNonVisualTray();
1677            Point point = SwingUtilities.convertPoint(this, e.getPoint(), tray);
1678            JComponent component = (JComponent)SwingUtilities.getDeepestComponentAt(tray, point.x, point.y);
1679            point = SwingUtilities.convertPoint(tray, point, component);
1680            return component.getToolTipText(new MouseEvent(
1681                tray,
1682                e.getID(),
1683                e.getWhen(),
1684                e.getModifiers(),
1685                point.x,
1686                point.y,
1687                e.getClickCount(),
1688                e.isPopupTrigger()));
1689        } else {
1690            return super.getToolTipText(e);
1691        }
1692    }
1693
1694    // ----------
1695

1696    private class SelectionDragger {
1697        private Point startPoint;
1698        private Point lastPoint;
1699
1700        public SelectionDragger(Point startPoint) {
1701            this.startPoint = startPoint;
1702        }
1703
1704        public void paintDragFeedback(Graphics g) {
1705            if (startPoint != null && lastPoint != null) {
1706                Rectangle r = getRectangle();
1707                g.drawRect(r.x, r.y, r.width, r.height);
1708            }
1709        }
1710
1711        public void drag(Point p) {
1712            lastPoint = p;
1713        }
1714
1715        public void drop(Point endPoint) {
1716            if (startPoint != null && endPoint != null) {
1717                lastPoint = endPoint;
1718                ArrayList toSelect = new ArrayList();
1719                collectSelectedComponents(
1720                    getRectangle(),
1721                    formDesigner.getComponentLayer().getComponentContainer(),
1722                    toSelect);
1723
1724                RADComponent[] selected = new RADComponent[toSelect.size()];
1725                toSelect.toArray(selected);
1726                formDesigner.setSelectedComponents(selected);
1727            }
1728        }
1729
1730        private Rectangle getRectangle() {
1731            int x = startPoint.x <= lastPoint.x ? startPoint.x : lastPoint.x;
1732            int y = startPoint.y <= lastPoint.y ? startPoint.y : lastPoint.y;
1733            int w = lastPoint.x - startPoint.x;
1734            if (w < 0)
1735                w = -w;
1736            int h = lastPoint.y - startPoint.y;
1737            if (h < 0)
1738                h = -h;
1739
1740            return new Rectangle(x, y, w, h);
1741        }
1742
1743        private boolean collectSelectedComponents(Rectangle selRect,
1744                                                  Container cont,
1745                                                  java.util.List JavaDoc toSelect)
1746        {
1747            ArrayList subContainers = new ArrayList();
1748
1749            Component[] comps = cont.getComponents();
1750            for (int i=0; i < comps.length; i++) {
1751                Component comp = comps[i];
1752                Rectangle bounds = convertRectangleFromComponent(
1753                                       comps[i].getBounds(), cont);
1754                boolean intersects = selRect.intersects(bounds);
1755
1756                RADComponent metacomp = formDesigner.getMetaComponent(comp);
1757                if (metacomp != null) {
1758                    if (intersects)
1759                        toSelect.add(metacomp);
1760                    if (!(metacomp instanceof ComponentContainer))
1761                        continue;
1762                }
1763
1764                if (intersects && comp instanceof Container)
1765                    subContainers.add(comp);
1766            }
1767
1768            if (toSelect.size() > 1
1769                    || (toSelect.size() == 1 && subContainers.size() == 0))
1770                return true;
1771
1772            Object JavaDoc theOnlyOne = toSelect.size() == 1 ? toSelect.get(0) : null;
1773
1774            for (int i=0; i < subContainers.size(); i++) {
1775                toSelect.clear();
1776                if (collectSelectedComponents(selRect,
1777                                              (Container)subContainers.get(i),
1778                                              toSelect))
1779                    return true;
1780            }
1781
1782            if (theOnlyOne != null) {
1783                toSelect.add(theOnlyOne);
1784                return true;
1785            }
1786            
1787            return false;
1788        }
1789    }
1790
1791    // -------
1792

1793    private abstract class ComponentDrag {
1794        RADVisualComponent[] movingComponents;
1795        RADVisualContainer targetContainer;
1796        RADVisualContainer fixedTarget;
1797        Component[] showingComponents;
1798        Rectangle[] originalBounds; // in coordinates of HandleLayer
1799
Rectangle compoundBounds; // compound from original bounds
1800
Rectangle[] movingBounds; // in coordinates of ComponentLayer
1801
Point hotSpot; // in coordinates of ComponentLayer
1802
Point convertPoint; // from HandleLayer to ComponentLayer (top visual component)
1803
boolean newDrag;
1804        boolean oldDrag;
1805        Object JavaDoc layoutUndoMark;
1806        UndoableEdit JavaDoc layoutUndoEdit;
1807
1808        // ctor for adding new
1809
ComponentDrag() {
1810            if (formDesigner.getTopVisualContainer() == null) {
1811                convertPoint = new Point(0,0);
1812            } else {
1813                convertPoint = convertPointFromComponent(0, 0, formDesigner.getTopVisualContainer());
1814            }
1815        }
1816
1817        // ctor for moving and resizing
1818
ComponentDrag(RADVisualComponent[] components, Point hotspot) {
1819            this();
1820            this.movingComponents = components;
1821
1822            int count = components.length;
1823            showingComponents = new Component[count]; // [provisional - just one component can be moved]
1824
originalBounds = new Rectangle[count];
1825            movingBounds = new Rectangle[count];
1826            for (int i=0; i < count; i++) {
1827                showingComponents[i] = (Component) formDesigner.getComponent(movingComponents[i]);
1828                originalBounds[i] = showingComponents[i].getBounds();
1829                convertRectangleFromComponent(originalBounds[i], showingComponents[i].getParent());
1830                compoundBounds = compoundBounds != null ?
1831                                 compoundBounds.union(originalBounds[i]) : originalBounds[i];
1832                movingBounds[i] = new Rectangle();
1833                movingBounds[i].width = originalBounds[i].width;
1834                movingBounds[i].height = originalBounds[i].height;
1835            }
1836
1837            this.hotSpot = hotspot == null ?
1838                new Point(4, 4) :
1839                new Point(hotspot.x - convertPoint.x, hotspot.y - convertPoint.y);
1840        }
1841
1842        final RADVisualContainer getSourceContainer() {
1843            return movingComponents != null && formDesigner.getTopDesignComponent() != movingComponents[0] ?
1844                   movingComponents[0].getParentContainer() : null;
1845        }
1846
1847        final boolean isTopComponent() {
1848            return movingComponents != null && formDesigner.getTopDesignComponent() == movingComponents[0];
1849        }
1850                
1851        final RADVisualContainer getTargetContainer(Point p, int modifiers) {
1852            if (fixedTarget != null) {
1853                return fixedTarget;
1854            }
1855            int mode = ((modifiers & InputEvent.ALT_MASK) != 0) ? COMP_SELECTED : COMP_DEEPEST;
1856            RADVisualContainer metacont = HandleLayer.this.getMetaContainerAt(p, mode);
1857            if ((metacont != null) && (metacont.getLayoutSupport() == null)) {
1858                RADVisualContainer dirMetacont = HandleLayer.this.getMetaContainerAt(
1859                        getMoveDirectionSensitivePoint(p, modifiers), mode);
1860                if ((dirMetacont != null) && (dirMetacont.getLayoutSupport() == null)) {
1861                    metacont = dirMetacont;
1862                }
1863            }
1864            if (movingComponents != null) {
1865                java.util.List JavaDoc comps = Arrays.asList(movingComponents);
1866                while (comps.contains(metacont)) {
1867                    metacont = metacont.getParentContainer();
1868                }
1869            }
1870            if (substituteForContainer(metacont)) {
1871                metacont = metacont.getParentContainer();
1872            }
1873            return metacont;
1874        }
1875
1876        private Point getMoveDirectionSensitivePoint(Point p, int modifiers) {
1877            if (lastMousePosition != null
1878                && compoundBounds != null
1879                && (modifiers & (InputEvent.ALT_MASK|InputEvent.CTRL_MASK|InputEvent.SHIFT_MASK)) == 0)
1880            {
1881                if (compoundBounds.width <= 0 || compoundBounds.height <= 0) {
1882                    return p;
1883                }
1884                int x;
1885                int y;
1886                if (lastXPosDiff != 0 && lastYPosDiff != 0) {
1887                    double dx = lastXPosDiff;
1888                    double dy = lastYPosDiff;
1889                    double d = Math.abs(dy/dx);
1890                    double r = compoundBounds.getHeight() / compoundBounds.getWidth();
1891                    if (d > r) {
1892                        x = p.x + (int)Math.round(compoundBounds.getHeight() / d / 2.0) * (lastXPosDiff > 0 ? 1 : -1);
1893                        y = p.y - convertPoint.y - hotSpot.y + compoundBounds.y + (lastYPosDiff > 0 ? compoundBounds.height : 0);
1894                    }
1895                    else {
1896                        x = p.x - convertPoint.x - hotSpot.x + compoundBounds.x + (lastXPosDiff > 0 ? compoundBounds.width : 0);
1897                        y = p.y + (int)Math.round(compoundBounds.getWidth() * d / 2.0) * (lastYPosDiff > 0 ? 1 : -1);
1898                    }
1899                }
1900                else {
1901                    x = lastXPosDiff == 0 ? p.x :
1902                        p.x - convertPoint.x - hotSpot.x + compoundBounds.x + (lastXPosDiff > 0 ? compoundBounds.width : 0);
1903                    y = lastYPosDiff == 0 ? p.y :
1904                        p.y - convertPoint.y - hotSpot.y + compoundBounds.y + (lastYPosDiff > 0 ? compoundBounds.height : 0);
1905                }
1906                Rectangle boundaries = formDesigner.getComponentLayer().getDesignerInnerBounds();
1907                // don't let the component component fall into non-visual area easily
1908
if (x < boundaries.x && x + 8 >= boundaries.x) {
1909                    x = boundaries.x;
1910                }
1911                else if (x > boundaries.x + boundaries.width && x - 8 < boundaries.x + boundaries.width) {
1912                    x = boundaries.x + boundaries.width - 1;
1913                }
1914                if (y < boundaries.y && y + 8 >= boundaries.y) {
1915                    y = boundaries.y;
1916                }
1917                else if (y > boundaries.y + boundaries.height && y - 8 < boundaries.y + boundaries.height) {
1918                    y = boundaries.y + boundaries.height - 1;
1919                }
1920                return new Point(x, y);
1921            }
1922            else return p;
1923        }
1924
1925        final void move(MouseEvent e) {
1926            if (e == null) {
1927                move(null, 0);
1928            } else {
1929                move(e.getPoint(), e.getModifiers());
1930            }
1931        }
1932        
1933        void move(Point p, int modifiers) {
1934            if (p == null) {
1935                for (int i=0; i<movingBounds.length; i++) {
1936                    movingBounds[i].x = Integer.MIN_VALUE;
1937                }
1938                return;
1939            }
1940
1941            targetContainer = getTargetContainer(p, modifiers);
1942
1943            if (newDrag && targetContainer != null && targetContainer.getLayoutSupport() == null) {
1944                p.x -= convertPoint.x;
1945                p.y -= convertPoint.y;
1946                formDesigner.getLayoutDesigner().move(p,
1947                                                      targetContainer.getId(),
1948                                                      ((modifiers & InputEvent.ALT_MASK) == 0),
1949                                                      ((modifiers & InputEvent.CTRL_MASK) != 0),
1950                                                      movingBounds);
1951                String JavaDoc[] position = formDesigner.getLayoutDesigner().positionCode();
1952                FormEditor.getAssistantModel(getFormModel()).setContext(position[0], position[1]);
1953            }
1954            else if (oldDrag && targetContainer != null && targetContainer.getLayoutSupport() != null) {
1955                oldMove(p);
1956                for (int i=0; i<movingBounds.length; i++) {
1957                    movingBounds[i].x = p.x - convertPoint.x - hotSpot.x + originalBounds[i].x - convertPoint.x;
1958                    movingBounds[i].y = p.y - convertPoint.y - hotSpot.y + originalBounds[i].y - convertPoint.y;
1959                }
1960            }
1961            else {
1962                FormEditor.getAssistantModel(getFormModel()).setContext("generalPosition"); // NOI18N
1963
for (int i=0; i<movingBounds.length; i++) {
1964                    movingBounds[i].x = p.x - convertPoint.x - hotSpot.x + originalBounds[i].x - convertPoint.x;
1965                    movingBounds[i].y = p.y - convertPoint.y - hotSpot.y + originalBounds[i].y - convertPoint.y;
1966                }
1967            }
1968        }
1969
1970        final void maskDraggingComponents() {
1971            if (!isTopComponent() && showingComponents != null) {
1972                for (int i=0; i < showingComponents.length; i++) {
1973                    Rectangle r = movingBounds[i];
1974                    showingComponents[i].setBounds(r.x + Short.MIN_VALUE, r.y + Short.MIN_VALUE, r.width, r.height);
1975                }
1976            }
1977        }
1978
1979        final void paintFeedback(Graphics2D g) {
1980            if ((movingBounds.length < 1) || (movingBounds[0].x == Integer.MIN_VALUE))
1981                return;
1982
1983            for (int i=0; i<showingComponents.length; i++) {
1984                Graphics gg = g.create(movingBounds[i].x + convertPoint.x,
1985                                       movingBounds[i].y + convertPoint.y,
1986                                       movingBounds[i].width + 1,
1987                                       movingBounds[i].height + 1);
1988
1989                if (newDrag
1990                    && ((targetContainer != null && targetContainer.getLayoutSupport() == null)
1991                        || (targetContainer == null && isTopComponent())))
1992                { // new layout support
1993
// paint the component being moved
1994
if (!isTopComponent()) {
1995                        doLayout(showingComponents[i]);
1996                        paintDraggedComponent(showingComponents[i], gg);
1997                    } // resized top design component is painted automatically
1998

1999                    // paint the selection rectangle
2000
gg.setColor(formSettings.getSelectionBorderColor());
2001                    gg.drawRect(0, 0, movingBounds[i].width, movingBounds[i].height);
2002
2003                    // paint the layout designer feedback
2004
g.translate(convertPoint.x, convertPoint.y);
2005                    g.setColor(formSettings.getGuidingLineColor());
2006                    formDesigner.getLayoutDesigner().paintMoveFeedback(g);
2007                    g.translate(-convertPoint.x, -convertPoint.y);
2008                }
2009                else if (oldDrag && ((targetContainer != null && targetContainer.getLayoutSupport() != null)
2010                        || (targetContainer == null && isTopComponent()))) {
2011                    if (!isTopComponent()) {
2012                        doLayout(showingComponents[i]);
2013                        oldPaintFeedback(g, gg, i);
2014                    }
2015                }
2016                else { // non-visual area
2017
doLayout(showingComponents[i]);
2018                    paintDraggedComponent(showingComponents[i], gg);
2019                }
2020            }
2021        }
2022
2023        final boolean end(final MouseEvent e) {
2024            dragPanel.removeAll();
2025
2026            boolean retVal;
2027            if (e == null) {
2028                retVal = end(null, 0);
2029            }
2030            else {
2031                retVal = end(e.getPoint(), e.getModifiers());
2032            }
2033            if (retVal) {
2034                movingComponents = null;
2035                targetContainer = null;
2036                fixedTarget = null;
2037                showingComponents = null;
2038            }
2039            else {
2040                // re-init in next AWT round - to have the designer updated
2041
EventQueue.invokeLater(new Runnable JavaDoc() {
2042                    public void run() {
2043                        init();
2044                        move(e);
2045                    }
2046                });
2047            }
2048            return retVal;
2049        }
2050
2051        // methods to extend/override ---
2052

2053        void init() {
2054            if (showingComponents != null) {
2055                // showing components need to be in a container to paint
2056
// correctly (relates to newly added components);
2057
// components in old layout need to be hidden
2058
RADVisualContainer sourceCont = getSourceContainer();
2059                boolean oldSource = sourceCont != null && sourceCont.getLayoutSupport() != null;
2060                dragPanel.removeAll();
2061                for (int i=0; i < showingComponents.length; i++) {
2062                    Component comp = showingComponents[i];
2063                    if (comp.getParent() == null) {
2064                        dragPanel.add(comp);
2065                    }
2066                    else if (oldSource) {
2067                        comp.setVisible(false);
2068                        // VisualReplicator makes it visible again...
2069
}
2070                    avoidDoubleBuffering(comp);
2071                }
2072            }
2073        }
2074
2075        private void avoidDoubleBuffering(Component comp) {
2076            if (comp instanceof JComponent) {
2077                ((JComponent)comp).setDoubleBuffered(false);
2078            }
2079            if (comp instanceof Container) {
2080                Container cont = (Container)comp;
2081                for (int i=0; i<cont.getComponentCount(); i++) {
2082                    avoidDoubleBuffering(cont.getComponent(i));
2083                }
2084            }
2085        }
2086
2087        boolean end(Point p, int modifiers) {
2088            return true;
2089        }
2090
2091        void oldMove(Point p) {
2092        }
2093
2094        void oldPaintFeedback(Graphics2D g, Graphics gg, int index) {
2095        }
2096
2097        // layout model undo/redo ---
2098

2099        final void createLayoutUndoableEdit() {
2100            layoutUndoMark = getLayoutModel().getChangeMark();
2101            layoutUndoEdit = getLayoutModel().getUndoableEdit();
2102        }
2103
2104        final void placeLayoutUndoableEdit(boolean autoUndo) {
2105            if (!layoutUndoMark.equals(getLayoutModel().getChangeMark())) {
2106                getFormModel().addUndoableEdit(layoutUndoEdit);
2107            }
2108            if (autoUndo) {
2109                getFormModel().forceUndoOfCompoundEdit();
2110            }
2111            layoutUndoMark = null;
2112            layoutUndoEdit = null;
2113        }
2114    }
2115
2116    private static void doLayout(Component component) {
2117        if (component instanceof Container) {
2118            Container cont = (Container) component;
2119            cont.doLayout();
2120            for (int i=0, n=cont.getComponentCount(); i < n; i++) {
2121                doLayout(cont.getComponent(i));
2122            }
2123        }
2124    }
2125
2126    private static void paintDraggedComponent(Component comp, Graphics g) {
2127        try {
2128            if (comp instanceof JComponent)
2129                comp.paint(g);
2130            else
2131                comp.getPeer().paint(g);
2132        }
2133        catch (RuntimeException JavaDoc ex) { // inspired by bug #62041 (JProgressBar bug #5035852)
2134
org.openide.ErrorManager.getDefault().notify(
2135                org.openide.ErrorManager.INFORMATIONAL, ex);
2136        }
2137    }
2138
2139    // for moving existing components
2140
private class ExistingComponentDrag extends ComponentDrag {
2141        private int modifiers; // for the old layout support
2142
private ComponentDragger oldDragger; // drags components in the old layout support
2143

2144        ExistingComponentDrag(RADVisualComponent[] comps,
2145                              Point hotspot, // in HandleLayer coordinates
2146
int modifiers)
2147        {
2148            super(comps, hotspot);
2149            this.modifiers = modifiers;
2150            init();
2151        }
2152
2153        void init() {
2154            RADVisualContainer metacont = getSourceContainer();
2155            String JavaDoc[] compIds = new String JavaDoc[showingComponents.length];
2156            for (int i=0; i < showingComponents.length; i++) {
2157                compIds[i] = movingComponents[i].getId();
2158                originalBounds[i].x -= convertPoint.x;
2159                originalBounds[i].y -= convertPoint.y;
2160            }
2161
2162            if (metacont.getLayoutSupport() == null) { // new layout support
2163
formDesigner.getLayoutDesigner().startMoving(
2164                    compIds, originalBounds, hotSpot);
2165            }
2166            else { // dragging started in the old layout support
2167
LayoutComponent[] layoutComps = new LayoutComponent[compIds.length];
2168                for (int i=0; i < compIds.length; i++) {
2169                    layoutComps[i] = getLayoutModel().getLayoutComponent(compIds[i]);
2170                    if (layoutComps[i] == null) {
2171                        layoutComps[i] = new LayoutComponent(compIds[i], false);
2172                    }
2173                }
2174                formDesigner.getLayoutDesigner().startAdding(
2175                    layoutComps, originalBounds, hotSpot, null);
2176            }
2177
2178            if ((modifiers & InputEvent.ALT_MASK) != 0) {
2179                // restricted dragging - within the same container, or one level up
2180
fixedTarget = (modifiers & InputEvent.SHIFT_MASK) != 0
2181                           || formDesigner.getTopDesignComponent() == metacont ?
2182                    metacont : metacont.getParentContainer();
2183            }
2184
2185            // old layout component dragger requires coordinates related to HandleLayer
2186
for (int i=0; i < originalBounds.length; i++) {
2187                originalBounds[i].x += convertPoint.x;
2188                originalBounds[i].y += convertPoint.y;
2189            }
2190            oldDragger = new ComponentDragger(
2191                formDesigner,
2192                HandleLayer.this,
2193                movingComponents,
2194                originalBounds,
2195                new Point(hotSpot.x + convertPoint.x, hotSpot.y + convertPoint.y),
2196                fixedTarget);
2197
2198            newDrag = oldDrag = true;
2199
2200            super.init();
2201        }
2202
2203        boolean end(Point p, int modifiers) {
2204            RADVisualContainer originalCont = getSourceContainer();
2205            if (p != null) {
2206                if (targetContainer == null || targetContainer.getLayoutSupport() != null) {
2207                    // dropped in old layout support, or on non-visual area
2208
createLayoutUndoableEdit();
2209                    boolean autoUndo = true;
2210                    try {
2211                        formDesigner.getLayoutDesigner().removeDraggedComponents();
2212                        oldDragger.dropComponents(p, targetContainer);
2213                        autoUndo = false;
2214                    } finally {
2215                        placeLayoutUndoableEdit(autoUndo);
2216                    }
2217                }
2218                else { // dropped in new layout support
2219
if (targetContainer != originalCont) {
2220                        for (int i=0; i < movingComponents.length; i++) {
2221                            getFormModel().removeComponent(movingComponents[i], false);
2222                        }
2223                        // Issue 69410 (don't mix remove/add chnages)
2224
for (int i=0; i < movingComponents.length; i++) {
2225                            getFormModel().addVisualComponent(movingComponents[i], targetContainer, null, false);
2226                        }
2227                    }
2228                    createLayoutUndoableEdit();
2229                    boolean autoUndo = true;
2230                    try {
2231                        formDesigner.getLayoutDesigner().endMoving(true);
2232                        autoUndo = false;
2233                    } finally {
2234                        getFormModel().fireContainerLayoutChanged(targetContainer, null, null, null);
2235                        placeLayoutUndoableEdit(autoUndo);
2236                    }
2237                }
2238            }
2239            else { // canceled
2240
formDesigner.getLayoutDesigner().endMoving(false);
2241                formDesigner.updateContainerLayout(originalCont); //, false);
2242
}
2243
2244            return true;
2245        }
2246
2247        void oldMove(Point p) {
2248            oldDragger.drag(p, targetContainer);
2249        }
2250
2251        void oldPaintFeedback(Graphics2D g, Graphics gg, int index) {
2252            oldDragger.paintDragFeedback(g);
2253
2254            // don't paint if component dragged from old layout (may have strange size)
2255
Component comp = showingComponents[index];
2256            paintDraggedComponent(comp, gg);
2257        }
2258    }
2259
2260    // for resizing existing components
2261
private class ResizeComponentDrag extends ComponentDrag {
2262        private int resizeType;
2263        private Dimension originalSize;
2264
2265        private ComponentDragger oldDragger; // drags components in the old layout support
2266

2267        ResizeComponentDrag(RADVisualComponent[] comps,
2268                            Point hotspot, // in HandleLayer coordinates
2269
int resizeType)
2270        {
2271            super(comps, hotspot);
2272            this.resizeType = resizeType;
2273            init();
2274        }
2275
2276        void init() {
2277            RADVisualContainer sourceCont = getSourceContainer();
2278            if (isTopComponent()) {
2279                LayoutModel layoutModel = getLayoutModel();
2280                newDrag = layoutModel != null
2281                          && layoutModel.getLayoutComponent(movingComponents[0].getId()) != null;
2282                oldDrag = !newDrag;
2283                fixedTarget = null;
2284                originalSize = formDesigner.getComponentLayer().getDesignerSize();
2285            }
2286            else if (sourceCont != null) {
2287                if (sourceCont.getLayoutSupport() == null) {
2288                    newDrag = true;
2289                }
2290                else {
2291                    oldDrag = true;
2292                }
2293                fixedTarget = sourceCont;
2294            }
2295
2296            if (newDrag) { // new layout support
2297
String JavaDoc[] compIds = new String JavaDoc[showingComponents.length];
2298                for (int i=0; i < showingComponents.length; i++) {
2299                    compIds[i] = movingComponents[i].getId();
2300                    originalBounds[i].x -= convertPoint.x;
2301                    originalBounds[i].y -= convertPoint.y;
2302                }
2303
2304                int[] res = new int[2];
2305                int horiz = resizeType & (LayoutSupportManager.RESIZE_LEFT
2306                                          | LayoutSupportManager.RESIZE_RIGHT);
2307                if (horiz == LayoutSupportManager.RESIZE_LEFT) {
2308                    res[LayoutConstants.HORIZONTAL] = LayoutConstants.LEADING;
2309                }
2310                else if (horiz == LayoutSupportManager.RESIZE_RIGHT) {
2311                    res[LayoutConstants.HORIZONTAL] = LayoutConstants.TRAILING;
2312                }
2313                else {
2314                    res[LayoutConstants.HORIZONTAL] = LayoutConstants.DEFAULT;
2315                }
2316                int vert = resizeType & (LayoutSupportManager.RESIZE_UP
2317                                          | LayoutSupportManager.RESIZE_DOWN);
2318                if (vert == LayoutSupportManager.RESIZE_UP) {
2319                    res[LayoutConstants.VERTICAL] = LayoutConstants.LEADING;
2320                }
2321                else if (vert == LayoutSupportManager.RESIZE_DOWN) {
2322                    res[LayoutConstants.VERTICAL] = LayoutConstants.TRAILING;
2323                }
2324                else {
2325                    res[LayoutConstants.VERTICAL] = LayoutConstants.DEFAULT;
2326                }
2327
2328                formDesigner.getLayoutDesigner().startResizing(
2329                    compIds, originalBounds, hotSpot, res, sourceCont != null);
2330
2331                // convert back to HandleLayer
2332
for (int i=0; i < originalBounds.length; i++) {
2333                    originalBounds[i].x += convertPoint.x;
2334                    originalBounds[i].y += convertPoint.y;
2335                }
2336            }
2337            else if (oldDrag) { // old layout support
2338
oldDragger = new ComponentDragger(
2339                    formDesigner,
2340                    HandleLayer.this,
2341                    movingComponents,
2342                    originalBounds,
2343                    new Point(hotSpot.x + convertPoint.x, hotSpot.y + convertPoint.y),
2344                    resizeType);
2345            }
2346
2347            super.init();
2348        }
2349
2350        boolean end(Point p, int modifiers) {
2351            if (p != null) {
2352                if (newDrag) { // new layout support
2353
// make sure the visual component has the current size set
2354
// (as still being in its container the layout manager tries to
2355
// restore the original size)
2356
showingComponents[0].setSize(movingBounds[0].width, movingBounds[0].height);
2357                    doLayout(showingComponents[0]);
2358
2359                    createLayoutUndoableEdit();
2360                    boolean autoUndo = true;
2361                    try {
2362                        formDesigner.getLayoutDesigner().endMoving(true);
2363                        for (int i=0; i < movingComponents.length; i++) {
2364                            RADVisualComponent metacomp = movingComponents[i];
2365                            if (metacomp instanceof RADVisualContainer) {
2366                                RADVisualContainer visCont = (RADVisualContainer) metacomp;
2367                                if (visCont.getLayoutSupport() == null) {
2368                                    getFormModel().fireContainerLayoutChanged(
2369                                        visCont, null, null, null);
2370                                }
2371                            }
2372                        }
2373                        autoUndo = false;
2374                    } finally {
2375                        if (targetContainer != null) {
2376                            getFormModel().fireContainerLayoutChanged(targetContainer, null, null, null);
2377                        }
2378                        placeLayoutUndoableEdit(autoUndo);
2379                    }
2380                }
2381                else { // old layout support
2382
if (targetContainer != null) {
2383                        oldDragger.dropComponents(p, targetContainer);
2384                    }
2385                }
2386                if (isTopComponent()) {
2387                    formDesigner.setDesignerSize(new Dimension(movingBounds[0].width, movingBounds[0].height),
2388                                                 originalSize);
2389                }
2390            }
2391            else { // resizing canceled
2392
formDesigner.getLayoutDesigner().endMoving(false);
2393
2394                if (isTopComponent()) {
2395                    // just revert ComponentLayer's designer size (don't need to go through FormDesigner)
2396
ComponentLayer compLayer = formDesigner.getComponentLayer();
2397                    if (!compLayer.getDesignerSize().equals(originalSize)) {
2398                        compLayer.setDesignerSize(originalSize);
2399                        compLayer.revalidate();
2400                    }
2401                    compLayer.repaint();
2402                }
2403                else { // add resized component back
2404
formDesigner.updateContainerLayout(getSourceContainer()); //, false);
2405
}
2406            }
2407            return true;
2408        }
2409
2410        void move(Point p, int modifiers) {
2411            if (isTopComponent()) {
2412                if (newDrag) {
2413                    p.x -= convertPoint.x;
2414                    p.y -= convertPoint.y;
2415                    formDesigner.getLayoutDesigner().move(p,
2416                                                          null,
2417                                                          ((modifiers & InputEvent.ALT_MASK) == 0),
2418                                                          ((modifiers & InputEvent.CTRL_MASK) != 0),
2419                                                          movingBounds);
2420                    showingComponents[0].setSize(movingBounds[0].width, movingBounds[0].height);
2421                }
2422                else {
2423                    Rectangle r = formDesigner.getComponentLayer().getDesignerInnerBounds();
2424                    int w = r.width;
2425                    int h = r.height;
2426                    if ((resizeType & LayoutSupportManager.RESIZE_DOWN) != 0) {
2427                        h = p.y - r.y;
2428                        if (h < 0)
2429                            h = 0;
2430                    }
2431                    if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0) {
2432                        w = p.x - r.x;
2433                        if (w < 0)
2434                            w = 0;
2435                    }
2436                    movingBounds[0].width = w;
2437                    movingBounds[0].height = h;
2438                }
2439                Dimension size = new Dimension(movingBounds[0].width, movingBounds[0].height);
2440                formDesigner.getComponentLayer().setDesignerSize(size);
2441                doLayout(formDesigner.getComponentLayer());
2442            } else if (oldDrag && (targetContainer = getTargetContainer(p, modifiers)) != null && targetContainer.getLayoutSupport() != null) {
2443                oldMove(p);
2444                for (int i=0; i<movingBounds.length; i++) {
2445                    int xchange = p.x - convertPoint.x - hotSpot.x;
2446                    if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0) {
2447                        movingBounds[i].x = originalBounds[i].x - convertPoint.x + xchange;
2448                        xchange = -xchange;
2449                    } else {
2450                        movingBounds[i].x = originalBounds[i].x - convertPoint.x;
2451                    }
2452                    if ((resizeType & (LayoutSupportManager.RESIZE_RIGHT | LayoutSupportManager.RESIZE_LEFT)) != 0) {
2453                        movingBounds[i].width = originalBounds[i].width + xchange;
2454                    }
2455                    int ychange = p.y - convertPoint.y - hotSpot.y;
2456                    if ((resizeType & LayoutSupportManager.RESIZE_UP) != 0) {
2457                        movingBounds[i].y = originalBounds[i].y - convertPoint.y + ychange;
2458                        ychange = -ychange;
2459                    } else {
2460                        movingBounds[i].y = originalBounds[i].y - convertPoint.y;
2461                    }
2462                    if ((resizeType & (LayoutSupportManager.RESIZE_DOWN | LayoutSupportManager.RESIZE_UP)) != 0) {
2463                        movingBounds[i].height = originalBounds[i].height + ychange;
2464                    }
2465                }
2466            } else {
2467                super.move(p, modifiers);
2468            }
2469        }
2470
2471        void oldMove(Point p) {
2472            oldDragger.drag(p, targetContainer);
2473            FormEditor.getAssistantModel(getFormModel()).setContext("generalResizing"); // NOI18N
2474
}
2475
2476        void oldPaintFeedback(Graphics2D g, Graphics gg, int index) {
2477            paintDraggedComponent(showingComponents[index], gg);
2478            oldDragger.paintDragFeedback(g);
2479        }
2480    }
2481
2482    // for moving a component being newly added
2483
private class NewComponentDrag extends ComponentDrag {
2484        private PaletteItem paletteItem;
2485        RADComponent addedComponent;
2486
2487        private int index = - 1; // for the old layout support
2488
private LayoutConstraints constraints; // for the old layout support
2489

2490        NewComponentDrag(PaletteItem paletteItem) {
2491            super();
2492            this.paletteItem = paletteItem;
2493            showingComponents = new Component[1];
2494            init();
2495        }
2496
2497        void init() { // can be re-inited
2498
RADVisualComponent precreated =
2499                getComponentCreator().precreateVisualComponent(
2500                    paletteItem.getComponentClassSource());
2501
2502            if (precreated != null) {
2503                if (movingComponents == null) {
2504                    movingComponents = new RADVisualComponent[1];
2505                }
2506                movingComponents[0] = precreated;
2507                LayoutComponent precreatedLC = getComponentCreator().getPrecreatedLayoutComponent();
2508                LayoutComponent[] layoutComponents = new LayoutComponent[] { precreatedLC };
2509                 
2510                showingComponents[0] = (Component) precreated.getBeanInstance();
2511                // Force creation of peer - AWT components don't have preferred size otherwise
2512
if (!(showingComponents[0] instanceof JComponent)) {
2513                    FakePeerSupport.attachFakePeer(showingComponents[0]);
2514                    if (showingComponents[0] instanceof Container) {
2515                        FakePeerSupport.attachFakePeerRecursively((Container)showingComponents[0]);
2516                    }
2517                }
2518
2519                Dimension size = showingComponents[0].getPreferredSize();
2520                if (originalBounds == null) { // new adding
2521
hotSpot = new Point();
2522                    originalBounds = new Rectangle[] { new Rectangle(convertPoint.x, convertPoint.y, size.width, size.height) };
2523                    movingBounds = new Rectangle[] { new Rectangle(0, 0, size.width, size.height) };
2524                }
2525                else { // repeated adding of the same component type, reuse last bounds
2526
movingBounds[0].width = size.width;
2527                    movingBounds[0].height = size.height;
2528                    originalBounds[0] = movingBounds[0];
2529                    movingBounds[0] = new Rectangle(movingBounds[0]);
2530                    originalBounds[0].x += convertPoint.x;
2531                    originalBounds[0].y += convertPoint.y;
2532                }
2533                compoundBounds = originalBounds[0];
2534                hotSpot.x = movingBounds[0].x + size.width/2 - 4;
2535                hotSpot.y = movingBounds[0].y + size.height/2;
2536                if (hotSpot.x < movingBounds[0].x)
2537                    hotSpot.x = movingBounds[0].x;
2538
2539                if (formDesigner.getLayoutDesigner() != null) {
2540                    formDesigner.getLayoutDesigner().startAdding(
2541                            layoutComponents, movingBounds, hotSpot,
2542                            targetContainer != null ? targetContainer.getId() : null);
2543                }
2544
2545                newDrag = oldDrag = true;
2546            }
2547            else {
2548                if (paletteItem.getComponentClass() != null) {
2549                    // non-visual component - present it as icon
2550
Node node = paletteItem.getNode();
2551                    Image icon = (node == null) ?
2552                        Utilities.loadImage("org/netbeans/modules/form/resources/form.gif") // NOI18N
2553
: node.getIcon(java.beans.BeanInfo.ICON_COLOR_16x16);
2554                    showingComponents[0] = new JLabel(new ImageIcon(icon));
2555                    Dimension dim = showingComponents[0].getPreferredSize();
2556                    hotSpot = new Point(dim.width/2, dim.height/2);
2557                    if (hotSpot.x < 0) {
2558                        hotSpot.x = 0;
2559                    }
2560                    originalBounds = new Rectangle[] { new Rectangle(convertPoint.x, convertPoint.y, dim.width, dim.height) };
2561                    showingComponents[0].setBounds(originalBounds[0]);
2562                    movingBounds = new Rectangle[] { showingComponents[0].getBounds() };
2563
2564                    newDrag = oldDrag = false;
2565                } else {
2566                    // The corresponding class cannot be loaded - cancel the drag.
2567
showingComponents = null;
2568                    movingBounds = new Rectangle[0];
2569                    EventQueue.invokeLater(new Runnable JavaDoc() {
2570                        public void run() {
2571                            endDragging(null);
2572                        }
2573                    });
2574                }
2575            }
2576
2577            super.init();
2578        }
2579
2580        boolean end(Point p, int modifiers) {
2581            if (p != null) {
2582                targetContainer = getTargetContainer(p, modifiers);
2583
2584                boolean newLayout;
2585                boolean oldLayout;
2586                if (targetContainer != null && movingComponents != null) {
2587                    newLayout = targetContainer.getLayoutSupport() == null;
2588                    oldLayout = !newLayout;
2589                }
2590                else newLayout = oldLayout = false;
2591
2592                Object JavaDoc constraints;
2593                if (oldLayout) {
2594                    constraints = !paletteItem.isMenu() && paletteItem.isVisual() ?
2595                        getConstraintsAtPoint(targetContainer, p, hotSpot) : null;
2596                }
2597                else constraints = null;
2598
2599                if (movingComponents != null) { // there is a precreated visual component
2600
addedComponent = movingComponents[0];
2601                    LayoutComponent layoutComponent = getComponentCreator().getPrecreatedLayoutComponent();
2602                    boolean added = getComponentCreator().addPrecreatedComponent(targetContainer, constraints);
2603                    if (getLayoutModel() != null) { // Some beans don't have layout
2604
createLayoutUndoableEdit();
2605                        boolean autoUndo = true;
2606                        try {
2607                            formDesigner.getLayoutDesigner().endMoving(added && newLayout);
2608                            if (added) {
2609                                if (layoutComponent.isLayoutContainer()) {
2610                                    if (!newLayout) { // always add layout container to the model
2611
getLayoutModel().addRootComponent(layoutComponent);
2612                                    }
2613                                }
2614                            } else {
2615                                repaint();
2616                            }
2617                            autoUndo = false;
2618                        } finally {
2619                            placeLayoutUndoableEdit(autoUndo);
2620                        }
2621                    }
2622                }
2623                else { // component not precreated ...
2624
RADComponent targetComponent = targetContainer;
2625                    if (javax.swing.border.Border JavaDoc.class.isAssignableFrom(paletteItem.getComponentClass())) {
2626                        int mode = ((modifiers & InputEvent.ALT_MASK) != 0) ? COMP_SELECTED : COMP_DEEPEST;
2627                        targetComponent = HandleLayer.this.getMetaComponentAt(p, mode);
2628                    }
2629                    addedComponent = getComponentCreator().createComponent(
2630                            paletteItem.getComponentClassSource(),
2631                            targetComponent,
2632                            constraints);
2633                    if (addedComponent == null) {
2634                        repaint();
2635                    }
2636                }
2637
2638                if (addedComponent != null) {
2639                    java.beans.BeanDescriptor JavaDoc bDesc = addedComponent.getBeanInfo().getBeanDescriptor();
2640                    if ((bDesc != null) && (bDesc.getValue("customizeOnCreation") != null)) { // NOI18N
2641
modifiers &= ~InputEvent.SHIFT_MASK;
2642                        EventQueue.invokeLater(new Runnable JavaDoc() {
2643                            public void run() {
2644                                RADComponentNode node = addedComponent.getNodeReference();
2645                                if (node.hasCustomizer()) {
2646                                    org.openide.nodes.NodeOperation.getDefault().customize(node);
2647                                }
2648                            }
2649                        });
2650                    }
2651                }
2652                if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
2653// init();
2654
return false;
2655                }
2656            }
2657            else {
2658                if (formDesigner.getLayoutDesigner() != null) {
2659                    formDesigner.getLayoutDesigner().endMoving(false);
2660                }
2661                getComponentCreator().releasePrecreatedComponent();
2662            }
2663            formDesigner.toggleSelectionMode();
2664            return true;
2665        }
2666
2667        void oldMove(Point p) {
2668            LayoutSupportManager laysup = targetContainer.getLayoutSupport();
2669            Container cont = (Container) formDesigner.getComponent(targetContainer);
2670            Container contDel = targetContainer.getContainerDelegate(cont);
2671            Point posInCont = convertPointToComponent(p.x, p.y, contDel);
2672            Point posInComp = hotSpot;
2673            index = laysup.getNewIndex(cont, contDel,
2674                                       showingComponents[0], -1,
2675                                       posInCont, posInComp);
2676            constraints = laysup.getNewConstraints(cont, contDel,
2677                                                   showingComponents[0], -1,
2678                                                   posInCont, posInComp);
2679        }
2680
2681        void oldPaintFeedback(Graphics2D g, Graphics gg, int index) {
2682            LayoutSupportManager laysup = targetContainer.getLayoutSupport();
2683            Container cont = (Container) formDesigner.getComponent(targetContainer);
2684            Container contDel = targetContainer.getContainerDelegate(cont);
2685            Point contPos = convertPointFromComponent(0, 0, contDel);
2686            g.setColor(formSettings.getSelectionBorderColor());
2687            g.setStroke(ComponentDragger.dashedStroke1);
2688            g.translate(contPos.x, contPos.y);
2689            laysup.paintDragFeedback(cont, contDel,
2690                                     showingComponents[0],
2691                                     constraints, this.index,
2692                                     g);
2693            g.translate(-contPos.x, -contPos.y);
2694// g.setStroke(stroke);
2695
paintDraggedComponent(showingComponents[0], gg);
2696        }
2697    }
2698    
2699    private class NewComponentDropListener implements DropTargetListener {
2700        
2701        public void dragEnter(DropTargetDragEvent dtde) {
2702            try {
2703                Transferable transferable = dtde.getTransferable();
2704                PaletteItem item = null;
2705                if (dtde.isDataFlavorSupported(PaletteController.ITEM_DATA_FLAVOR)) {
2706                    Lookup itemLookup = (Lookup)transferable.getTransferData(PaletteController.ITEM_DATA_FLAVOR);
2707                    item = (PaletteItem)itemLookup.lookup(PaletteItem.class);
2708                } else {
2709                    ClassSource classSource = CopySupport.getCopiedBeanClassSource(transferable);
2710                    if (classSource != null) {
2711                        item = new PaletteItem(classSource);
2712                    } else {
2713                        Node node = NodeTransfer.node(transferable, NodeTransfer.DND_COPY);
2714                        if(node != null) {
2715                            NewComponentDrop newComponentDrop = (NewComponentDrop)node.getCookie(NewComponentDrop.class);
2716                            if (newComponentDrop != null) {
2717                                item = newComponentDrop.getPaletteItem();
2718                            }
2719                        }
2720                    }
2721                }
2722                if (item != null) {
2723                    if ((item.getComponentClassName().indexOf('.') != -1) // Issue 79573
2724
|| FormJavaSource.isInDefaultPackage(getFormModel())) {
2725                        draggedComponent = new NewComponentDrag(item);
2726                        draggedComponent.move(dtde.getLocation(), 0);
2727                        repaint();
2728                    } else {
2729                        dtde.rejectDrag();
2730                    }
2731                }
2732            } catch (Exception JavaDoc ex) {
2733                ex.printStackTrace();
2734            }
2735        }
2736        
2737        public void dragOver(java.awt.dnd.DropTargetDragEvent JavaDoc dtde) {
2738            if (draggedComponent != null) {
2739                draggedComponent.move(dtde.getLocation(), 0);
2740                repaint();
2741            }
2742        }
2743        
2744        public void dropActionChanged(java.awt.dnd.DropTargetDragEvent JavaDoc dtde) {
2745        }
2746        
2747        public void dragExit(java.awt.dnd.DropTargetEvent JavaDoc dte) {
2748            if (draggedComponent != null) {
2749                endDragging(null);
2750                repaint();
2751            }
2752        }
2753        
2754        public void drop(java.awt.dnd.DropTargetDropEvent JavaDoc dtde) {
2755            if (draggedComponent != null) {
2756                NewComponentDrag newComponentDrag = ((NewComponentDrag)draggedComponent);
2757                try {
2758                    newComponentDrag.end(dtde.getLocation(), 0);
2759                } finally {
2760                    draggedComponent = null;
2761                    draggingEnded = true;
2762                }
2763                if (newComponentDrag.addedComponent != null) {
2764                    String JavaDoc id = newComponentDrag.addedComponent.getId();
2765                    Node node = NodeTransfer.node(dtde.getTransferable(), NodeTransfer.DND_COPY);
2766                    if (node != null) {
2767                        NewComponentDrop newComponentDrop = (NewComponentDrop)node.getCookie(NewComponentDrop.class);
2768                        if (newComponentDrop != null) {
2769                            newComponentDrop.componentAdded(getFormModel(), id);
2770                        }
2771                    }
2772                }
2773                formDesigner.toggleSelectionMode();
2774                formDesigner.requestActive();
2775            }
2776        }
2777
2778    }
2779    
2780}
2781
Popular Tags