|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form; import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import javax.swing.*; import java.util.*; import java.text.MessageFormat; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.awt.StatusDisplayer; import org.openide.windows.TopComponent; import org.openide.nodes.Node; import org.openide.nodes.NodeOp; import org.netbeans.modules.form.palette.CPManager; import org.netbeans.modules.form.palette.PaletteItem; import org.netbeans.modules.form.layoutsupport.*; /** * A transparent layer (glass pane) handling user operations in designer (mouse * and keyboard events) and painting selection and drag&drop feedback. * Technically, this is a layer in FormDesigner, placed over ComponentLayer. * * @author Tran Duc Trung, Tomas Pavek */ class HandleLayer extends JPanel { // constants for mode parameter of getMetaComponentAt(Point,int) method static final int COMP_DEEPEST = 0; // get the deepest component (at given point) static final int COMP_SELECTED = 1; // get the deepest selected component static final int COMP_ABOVE_SELECTED = 2; // get the component above the deepest selected component static final int COMP_UNDER_SELECTED = 3; // get the component under the deepest selected component private static final int DESIGNER_RESIZING = 256; // flag for resizeType private static MessageFormat resizingHintFormat; private FormDesigner formDesigner; private boolean viewOnly; private ComponentDragger componentDragger; private Point lastLeftMousePoint; private Point prevLeftMousePoint; private boolean draggingCanceled = false; private int resizeType; private SelectionDragger selectionDragger; private DesignerResizer designerResizer; /** The FormLoaderSettings instance */ private static FormLoaderSettings formSettings = FormLoaderSettings.getInstance(); HandleLayer(FormDesigner fd) { formDesigner = fd; addMouseListener(new HandleLayerMouseListener()); addMouseMotionListener(new HandleLayerMouseMotionListener()); // setNextFocusableComponent(this); setLayout(null); // set Ctrl+TAB and Ctrl+Shift+TAB as focus traversal keys - to have // TAB and Shift+TAB free for component selection Set keys = new HashSet(); keys.add(AWTKeyStroke.getAWTKeyStroke(9, InputEvent.CTRL_DOWN_MASK, true)); setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys); keys.clear(); keys.add(AWTKeyStroke.getAWTKeyStroke(9, InputEvent.CTRL_DOWN_MASK |InputEvent.SHIFT_DOWN_MASK, true)); setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys); getAccessibleContext().setAccessibleName( FormUtils.getBundleString("ACSN_HandleLayer")); // NOI18N getAccessibleContext().setAccessibleDescription( FormUtils.getBundleString("ACSD_HandleLayer")); // NOI18N } void setViewOnly(boolean viewOnly) { this.viewOnly = viewOnly; } protected void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(formSettings.getSelectionBorderSize())); RADComponent conSource = formDesigner.getConnectionSource(); RADComponent conTarget = formDesigner.getConnectionTarget(); if (conSource != null || conTarget != null) { // paint connection g2.setColor(formSettings.getConnectionBorderColor()); if (conSource != null) paintSelection(g2, conSource); if (conTarget != null) paintSelection(g2, conTarget); } else { // paint selection g2.setColor(formSettings.getSelectionBorderColor()); Iterator metacomps = formDesigner.getSelectedComponents().iterator(); while (metacomps.hasNext()) { paintSelection(g2, (RADComponent) metacomps.next()); } } if (componentDragger != null) componentDragger.paintDragFeedback(g2); if (selectionDragger != null) selectionDragger.paintDragFeedback(g2); } private void paintSelection(Graphics2D g, RADComponent metacomp) { Object comp = formDesigner.getComponent(metacomp); if (!(comp instanceof Component)) return; Component component = (Component) comp; Component parent = component.getParent(); if (parent != null && component.isShowing()) { Rectangle rect = component.getBounds(); rect = SwingUtilities.convertRectangle(parent, rect, this); Rectangle parentRect = new Rectangle(new Point(0,0), parent.getSize()); parentRect = SwingUtilities.convertRectangle(parent, parentRect, this); Rectangle2D selRect = rect.createIntersection(parentRect); int correction = formSettings.getSelectionBorderSize() % 2; g.draw(new Rectangle2D.Double( selRect.getX() - correction, selRect.getY() - correction, selRect.getWidth() + correction, selRect.getHeight() + correction)); } } public boolean isOpaque() { return false; } protected void processKeyEvent(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_TAB || e.getKeyChar() == '\t') { if (!e.isControlDown()) { if (e.getID() == KeyEvent.KEY_PRESSED) { RADComponent nextComp = formDesigner.getNextVisualComponent( !e.isShiftDown()); if (nextComp != null) formDesigner.setSelectedComponent(nextComp); } e.consume(); return; } } else if (keyCode == KeyEvent.VK_SPACE) { if (!viewOnly && e.getID() == KeyEvent.KEY_RELEASED) { Iterator it = formDesigner.getSelectedComponents().iterator(); if (it.hasNext()) { RADComponent comp = (RADComponent)it.next(); if (!it.hasNext()) { // just one component is selected if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT) { // in selection mode SPACE starts in-place editing formDesigner.startInPlaceEditing(comp); } else if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) { // in add mode SPACE adds selected item as component PaletteItem item = CPManager.getDefault().getSelectedItem(); if (item != null) { formDesigner.getModel().getComponentCreator() .createComponent(item.getComponentClassSource(), comp, null); formDesigner.toggleSelectionMode(); } } } } } e.consume(); return; } else if (keyCode == KeyEvent.VK_ESCAPE) { if (endDragging(null)) e.consume(); return; } else if (keyCode == KeyEvent.VK_F10) { if (e.isShiftDown()) { Point p = null; Iterator it = formDesigner.getSelectedComponents().iterator(); if (it.hasNext()) { RADComponent metacomp = (RADComponent)it.next(); Object sel = (Component) formDesigner.getComponent(metacomp); if (sel instanceof Component) { Component comp = (Component) sel; p = SwingUtilities.convertPoint(comp.getParent(), comp.getLocation(), this); } else p = new Point(0,0); showContextMenu(p); e.consume(); return; } } } // else { super.processKeyEvent(e); // } } public boolean isFocusTraversable() { return true; } /** * Returns metacomponent at given position. * @param point - position on component layer * @param mode - what to get: * COMP_DEEPEST - get the deepest component * COMP_SELECTED - get the deepest selected component * COMP_ABOVE_SELECTED - get the component above the deepest selected component * COMP_UNDER_SELECTED - get the component under the deepest selected component * @returns the metacomponent at given point * If no component is currently selected then: * for COMP_SELECTED the deepest component is returned * for COMP_ABOVE_SELECTED the deepest component is returned * for COMP_UNDER_SELETCED the top component is returned */ private RADComponent getMetaComponentAt(Point point, int mode) { Component[] deepComps = getDeepestComponentsAt( formDesigner.getComponentLayer(), point); if (deepComps.length == 0) return null; int dIndex = mode == COMP_DEEPEST ? deepComps.length - 1 : 0; Component comp = deepComps[dIndex]; // find the component satisfying point and mode RADComponent topMetaComp = formDesigner.getTopDesignComponent(); RADComponent firstMetaComp = null; RADComponent currMetaComp; RADComponent prevMetaComp = null; do { currMetaComp = formDesigner.getMetaComponent(comp); if (currMetaComp != null) { if (firstMetaComp == null) firstMetaComp = currMetaComp; switch (mode) { case COMP_DEEPEST: return currMetaComp; case COMP_SELECTED: if (formDesigner.isComponentSelected(currMetaComp)) return currMetaComp; if (currMetaComp == topMetaComp) return firstMetaComp; // nothing selected - return the deepest break; case COMP_ABOVE_SELECTED: if (prevMetaComp != null && formDesigner.isComponentSelected(prevMetaComp)) return currMetaComp; if (currMetaComp == topMetaComp) return firstMetaComp; // nothing selected - return the deepest break; case COMP_UNDER_SELECTED: if (formDesigner.isComponentSelected(currMetaComp)) return prevMetaComp != null ? prevMetaComp : topMetaComp; if (currMetaComp == topMetaComp) return topMetaComp; // nothing selected - return the top break; } prevMetaComp = currMetaComp; } comp = dIndex + 1 < deepComps.length ? deepComps[++dIndex] : comp.getParent(); } while (comp != null); return firstMetaComp; } private static Component[] getDeepestComponentsAt(Container parent, Point point) { Component comp = SwingUtilities.getDeepestComponentAt(parent, point.x, point.y); if (comp == null) return new Component[0]; Container deepestParent = comp.getParent(); Component[] deepestComponents = deepestParent.getComponents(); Point deepestPosition = SwingUtilities.convertPoint(parent, point, deepestParent); // in most cases there will be just one component... Component[] componentsAtPoint = new Component[1]; ArrayList compList = null; for (int i=0; i < deepestComponents.length; i++) { comp = deepestComponents[i]; Point p = comp.getLocation(); if (comp.isVisible() && comp.contains(deepestPosition.x - p.x, deepestPosition.y - p.y)) { if (componentsAtPoint[0] == null) componentsAtPoint[0] = comp; else { if (compList == null) { compList = new ArrayList(); compList.add(componentsAtPoint[0]); } compList.add(comp); } } } if (compList == null) return componentsAtPoint[0] != null ? componentsAtPoint : new Component[0]; componentsAtPoint = new Component[compList.size()]; compList.toArray(componentsAtPoint); return componentsAtPoint; } RADVisualContainer getMetaContainerAt(Point point) { RADComponent metacomp = getMetaComponentAt(point, COMP_DEEPEST); if (metacomp == null) return null; if (metacomp instanceof RADVisualContainer) return (RADVisualContainer) metacomp; if (metacomp instanceof RADVisualComponent) return (RADVisualContainer) metacomp.getParentComponent(); return null; } /** Selects component at the position e.getPoint() on component layer. * What component is selected further depends on whether CTRL or ALT * keys are hold. */ private RADComponent selectComponent(MouseEvent e) { int selMode = !e.isAltDown() ? COMP_DEEPEST : (!e.isShiftDown() ? COMP_ABOVE_SELECTED : COMP_UNDER_SELECTED); RADComponent hitMetaComp = getMetaComponentAt(e.getPoint(), selMode); if (e.isControlDown()) { // Control is pressed - add component to selection if (hitMetaComp != null) if (formDesigner.isComponentSelected(hitMetaComp)) formDesigner.removeComponentFromSelection(hitMetaComp); else formDesigner.addComponentToSelection(hitMetaComp); } else if (e.isShiftDown() && !e.isAltDown()) { // Shift is pressed - select interval if (hitMetaComp != null && !formDesigner.isComponentSelected(hitMetaComp)) { if (formDesigner.getSelectedComponents().size() > 0) { RADComponent[] intervalToSelect = getComponentsIntervalToSelect(hitMetaComp, false); if (intervalToSelect == null) intervalToSelect = getComponentsIntervalToSelect( hitMetaComp, true); if (intervalToSelect != null) formDesigner.setSelectedComponents(intervalToSelect); else formDesigner.setSelectedComponent(hitMetaComp); } else formDesigner.setSelectedComponent(hitMetaComp); } } else { // no reasonable modifier key pressed - select single component if (hitMetaComp != null) { if (!formDesigner.isComponentSelected(hitMetaComp)) formDesigner.setSelectedComponent(hitMetaComp); } else formDesigner.clearSelection(); } return hitMetaComp; } private RADComponent[] getComponentsIntervalToSelect( RADComponent clickedComp, boolean forward) { if (!(clickedComp instanceof RADVisualComponent)) return null; java.util.List toSelect = new LinkedList(); RADVisualComponent comp = (RADVisualComponent) clickedComp; boolean selected = false; do // starting with clickedComp, { // go forward/backward in components until a selected one is reached if (forward) toSelect.add(comp); else toSelect.add(0, comp); comp = formDesigner.getNextVisualComponent(comp, forward); } while (comp != null && comp != clickedComp && !(selected = formDesigner.isComponentSelected(comp)) && comp != formDesigner.getTopDesignComponent()); if (selected) { // selected component found - we can make the interval if (comp == formDesigner.getTopDesignComponent()) { if (!forward) // top component is fine when going backward toSelect.add(0, comp); } else { // add also already selected components in the direction selected = false; do { if (forward) toSelect.add(comp); else toSelect.add(0, comp); comp = formDesigner.getNextVisualComponent(comp, forward); } while (comp != null && (selected = formDesigner.isComponentSelected(comp)) && comp != formDesigner.getTopDesignComponent()); if (selected && !forward) toSelect.add(0, comp); // top comp is fine when going backward } RADComponent[] compArray = new RADComponent[toSelect.size()]; toSelect.toArray(compArray); return compArray; } return null; } private void selectOtherComponentsNode() { FormEditorSupport fes = formDesigner.getFormEditorSupport(); ComponentInspector ci = ComponentInspector.getInstance(); Node[] selectedNode = new Node[] { ((FormRootNode)fes.getFormRootNode()).getOthersNode() }; try { ci.setSelectedNodes(selectedNode, fes); formDesigner.clearSelectionImpl(); formDesigner.repaintSelection(); } catch (java.beans.PropertyVetoException ex) { ex.printStackTrace(); } formDesigner.setActivatedNodes(selectedNode); } private boolean processDoubleClick(MouseEvent e) { if (e.isShiftDown() || e.isControlDown()) return false; RADComponent metacomp = getMetaComponentAt(e.getPoint(), COMP_SELECTED); if (metacomp == null) return true; if (e.isAltDown()) { if (metacomp == formDesigner.getTopDesignComponent()) { metacomp = metacomp.getParentComponent(); if (metacomp == null) return true; } else return false; } Node node = metacomp.getNodeReference(); if (node != null) { Action action = node.getPreferredAction(); if (action != null) {// && action.isEnabled()) { action.actionPerformed(new ActionEvent( node, ActionEvent.ACTION_PERFORMED, "")); // NOI18N } } return true; } private void processMouseClickInLayoutSupport(RADComponent metacomp, MouseEvent e) { if (!(metacomp instanceof RADVisualComponent)) return; RADVisualContainer metacont; if (metacomp instanceof RADVisualContainer) metacont = (RADVisualContainer) metacomp; else { metacont = (RADVisualContainer) metacomp.getParentComponent(); if (metacont == null) return; } Container cont = (Container) formDesigner.getComponent(metacont); Container contDelegate = metacont.getContainerDelegate(cont); Point p = SwingUtilities.convertPoint(HandleLayer.this, e.getPoint(), contDelegate); metacont.getLayoutSupport().processMouseClick(p, cont, contDelegate); } private void showContextMenu(Point popupPos) { ComponentInspector inspector = ComponentInspector.getInstance(); TopComponent activated = TopComponent.getRegistry().getActivated(); if (activated != formDesigner.multiViewObserver.getTopComponent() && activated != inspector) return; formDesigner.componentActivated(); // just for sure... Node[] selectedNodes = inspector.getSelectedNodes(); JPopupMenu popup = NodeOp.findContextMenu(selectedNodes); if (popup != null) { popup.show(HandleLayer.this, popupPos.x, popupPos.y); } } // -------- boolean anyDragger() { return componentDragger != null || selectionDragger != null || designerResizer != null; } private ComponentDragger createComponentDragger(Point hotspot, int modifiers) { java.util.List selectedComponents = formDesigner.getSelectedComponents(); if (selectedComponents.size() == 0) return null; // all selected components must be visible in the designer java.util.List selComps = new ArrayList(selectedComponents.size()); Iterator iter = selectedComponents.iterator(); while (iter.hasNext()) { RADComponent metacomp = (RADComponent) iter.next(); if (metacomp instanceof RADVisualComponent) if (metacomp != formDesigner.getTopDesignComponent()) selComps.add(metacomp); else return null; } // remove selected components contained in another selected components Set children = new HashSet(); iter = selComps.iterator(); while (iter.hasNext()) { RADComponent metacomp = (RADComponent) iter.next(); Iterator iter2 = selComps.iterator(); while (iter2.hasNext()) { RADComponent metacomp2 = (RADComponent) iter2.next(); if (metacomp2 != metacomp && metacomp.isParentComponent(metacomp2)) children.add(metacomp2); } } selComps.removeAll(children); if (selComps.isEmpty()) return null; RADVisualComponent[] comps = new RADVisualComponent[selComps.size()]; selComps.toArray(comps); if (resizeType == 0) { // dragging RADVisualContainer fixedTargetContainer = null; if ((modifiers & InputEvent.ALT_MASK) != 0) { // restricted dragging RADVisualContainer parent = comps[0].getParentContainer(); if ((modifiers & InputEvent.SHIFT_MASK) != 0 || formDesigner.getTopDesignComponent() == parent) { // restrict dragging only to the parent container // (dragging within the same container) for (int i=1; i < comps.length; i++) if (comps[i].getParentContainer() != parent) { parent = null; // not the same parent break; } fixedTargetContainer = parent; } else if ((parent = parent.getParentContainer()) != null) { // restrict dragging only to the parent of the parent // container (dragging one level up) for (int i=1; i < comps.length; i++) if (comps[i].getParentContainer().getParentContainer() != parent) { parent = null; break; } fixedTargetContainer = parent; } } return new ComponentDragger(formDesigner, this, comps, hotspot, fixedTargetContainer); } else // resizing return new ComponentDragger(formDesigner, this, comps, hotspot, resizeType); } private boolean endDragging(Point commitPosition) { if (anyDragger()) { if (resizeType != 0) { resizeType = 0; Cursor cursor = getCursor(); if (cursor != null && cursor.getType() != Cursor.DEFAULT_CURSOR) setCursor(Cursor.getDefaultCursor()); if (getToolTipText() != null) setToolTipText(null); } if (designerResizer != null) { if (commitPosition != null) designerResizer.drop(commitPosition); else { Dimension prevSize = formDesigner.getStoredDesignerSize(); if (!formDesigner.getComponentLayer().getDesignerSize() .equals(prevSize)) { // restore the previous designer size formDesigner.getComponentLayer() .updateDesignerSize(prevSize); } } designerResizer = null; } if (componentDragger != null) { if (commitPosition != null) componentDragger.dropComponents(commitPosition); componentDragger = null; repaint(); } if (selectionDragger != null) { if (commitPosition != null) selectionDragger.drop(commitPosition); selectionDragger = null; repaint(); } draggingCanceled = commitPosition == null; return true; } return false; } // Check the mouse cursor if it is at position where a component or the // designer can be resized. Change mouse cursor accordingly. private void checkResizing(MouseEvent e) { int resizing = checkComponentsResizing(e); if (resizing == 0) { resizing = checkDesignerResizing(e); if (resizing == 0) { if (getToolTipText() != null) setToolTipText(null); } else if (getToolTipText() == null) { Dimension size = formDesigner.getComponentLayer() .getDesignerSize(); if (resizingHintFormat == null) resizingHintFormat = new MessageFormat( FormUtils.getBundleString("FMT_HINT_DesignerResizing")); // NOI18N String hint = resizingHintFormat.format( new Object[] { new Integer(size.width), new Integer(size.height) }); setToolTipText(hint); ToolTipManager.sharedInstance().mouseEntered(e); } } else if (getToolTipText() != null) setToolTipText(null); if (resizing != 0) setResizingCursor(resizing); else { Cursor cursor = getCursor(); if (cursor != null && cursor.getType() != Cursor.DEFAULT_CURSOR) setCursor(Cursor.getDefaultCursor()); } } // Check the mouse cursor if it is at position where designer can be // resized. private int checkDesignerResizing(MouseEvent e) { if (!e.isAltDown() && !e.isControlDown() && !e.isShiftDown()) { ComponentLayer compLayer = formDesigner.getComponentLayer(); int resizing = getSelectionResizable( e.getPoint(), compLayer.getComponentContainer(), compLayer.getDesignerOutsets().right + 2); resizeType = validDesignerResizing(resizing) ? resizing | DESIGNER_RESIZING : 0; } else resizeType = 0; return resizeType; } // Check whether given resize type is valid for designer. private boolean validDesignerResizing(int resizing) { return resizing == (LayoutSupportManager.RESIZE_DOWN | LayoutSupportManager.RESIZE_RIGHT) || resizing == LayoutSupportManager.RESIZE_DOWN || resizing == LayoutSupportManager.RESIZE_RIGHT; } // Check the mouse cursor if it is at position where a component (or more // components) can be resized. private int checkComponentsResizing(MouseEvent e) { if (e.isAltDown() || e.isControlDown() || e.isShiftDown()) { resizeType = 0; return resizeType; } // check whether all selected components are in the same container RADComponent parent = null; Iterator selected = formDesigner.getSelectedComponents().iterator(); while (selected.hasNext()) { RADComponent comp = (RADComponent) selected.next(); if (comp instanceof RADVisualComponent) { if (parent == null) { parent = comp.getParentComponent(); if (parent == null) return 0; // component without a parent cannot be resized } else if (comp.getParentComponent() != parent) return 0; // selected components are not in the same container } } Point p = e.getPoint(); RADComponent compAtPoint = getMetaComponentAt(p, COMP_SELECTED); if (compAtPoint instanceof RADVisualComponent) { RADVisualComponent metacomp = (RADVisualComponent) compAtPoint; if (!formDesigner.isComponentSelected(metacomp)) { int resizing = 0; RADVisualComponent[] otherComps; if (metacomp instanceof RADVisualContainer) otherComps = ((RADVisualContainer)metacomp).getSubComponents(); else { RADVisualContainer metacont = metacomp.getParentContainer(); if (metacont != null) otherComps = metacont.getSubComponents(); else return 0; // component without a parent } for (int i=0; i < otherComps.length; i++) { metacomp = otherComps[i]; resizing = getComponentResizable(p, metacomp); if (resizing != 0) break; } resizeType = resizing; } else resizeType = getComponentResizable(p, metacomp); } else resizeType = 0; return resizeType; } // Check how possible component resizing (obtained from layout support) // matches with mouse position on component selection border. private int getComponentResizable(Point p, RADVisualComponent metacomp) { if (!formDesigner.isComponentSelected(metacomp)) return 0; RADVisualContainer metacont = (RADVisualContainer) metacomp.getParentComponent(); if (metacont == null || metacomp == formDesigner.getTopDesignComponent()) return 0; LayoutSupportManager laySup = metacont.getLayoutSupport(); if (laySup == null) return 0; Container cont = (Container) formDesigner.getComponent(metacont); Container contDel = metacont.getContainerDelegate(cont); Component comp = (Component) formDesigner.getComponent(metacomp); int resizable = laySup.getResizableDirections( cont, contDel, comp, metacont.getIndexOf(metacomp)); if (resizable != 0) resizable &= getSelectionResizable(p, comp, 2); return resizable; } // Compute possible resizing directions according to mouse position on // component selection border. private int getSelectionResizable(Point p, Component comp, int borderWidth) { if (comp == null) return 0; Rectangle bounds = comp.getBounds(); bounds.x = 0; bounds.y = 0; bounds = SwingUtilities.convertRectangle(comp, bounds, this); Rectangle r1 = new Rectangle(bounds); Rectangle r2 = new Rectangle(bounds); r1.grow(borderWidth, borderWidth); r2.grow(-3, -3); if (r2.width < 0) r2.width = 0; if (r2.height < 0) r2.height = 0; int resizable = 0; if (r1.contains(p)) { if (p.y >= r2.y + r2.height) resizable |= LayoutSupportManager.RESIZE_DOWN; else if (p.y < r2.y) resizable |= LayoutSupportManager.RESIZE_UP; if (p.x >= r2.x + r2.width) resizable |= LayoutSupportManager.RESIZE_RIGHT; else if (p.x < r2.x) resizable |= LayoutSupportManager.RESIZE_LEFT; } return resizable; } private void setResizingCursor(int resizeType) { Cursor cursor = null; if ((resizeType & LayoutSupportManager.RESIZE_UP) != 0) { if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR); else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR); else cursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR); } else if ((resizeType & LayoutSupportManager.RESIZE_DOWN) != 0) { if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR); else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR); else cursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR); } else if ((resizeType & LayoutSupportManager.RESIZE_LEFT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); else if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0) cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); if (cursor == null) cursor = Cursor.getDefaultCursor(); setCursor(cursor); } private void setUserDesignerSize() { NotifyDescriptor.InputLine input = new NotifyDescriptor.InputLine( FormUtils.getBundleString("CTL_SetDesignerSize_Label"), // NOI18N FormUtils.getBundleString("CTL_SetDesignerSize_Title")); // NOI18N Dimension size = formDesigner.getComponentLayer().getDesignerSize(); input.setInputText(Integer.toString(size.width) + ", " // NOI18N + Integer.toString(size.height)); if (DialogDisplayer.getDefault().notify(input) == NotifyDescriptor.OK_OPTION) { String txt = input.getInputText(); int i = txt.indexOf(','); if (i > 0) { int n = txt.length(); try { int w = Integer.parseInt(txt.substring(0, i)); while (++i < n && txt.charAt(i) == ' '); int h = Integer.parseInt(txt.substring(i, n)); if (w >= 0 && h >= 0) { size = new Dimension(w ,h); formDesigner.setStoredDesignerSize(size); // update must be done immediately because of a weird // mouse move event occurring after closing the input // dialog but before updating the designer through // synthetic property change processing formDesigner.getComponentLayer().updateDesignerSize(size); setToolTipText(null); setCursor(Cursor.getDefaultCursor()); } } catch (NumberFormatException ex) {} // silently ignore, do nothing } } } private LayoutConstraints getConstraintsAtPoint(RADComponent metacomp, Point point) { if (!(metacomp instanceof RADVisualComponent)) return null; RADVisualContainer metacont = metacomp instanceof RADVisualContainer ? (RADVisualContainer) metacomp : (RADVisualContainer) metacomp.getParentComponent(); if (metacont == null) return null; Container cont = (Container) formDesigner.getComponent(metacont); Container contDel = metacont.getContainerDelegate(cont); Point p = SwingUtilities.convertPoint(this, point, contDel); return metacont.getLayoutSupport().getNewConstraints(cont, contDel, null, -1, p, null); } private void showAddHint(RADComponent metacomp, Point p, PaletteItem item) { if ((!(metacomp instanceof RADVisualComponent) && metacomp != null) || item == null) { StatusDisplayer.getDefault().setStatusText(""); // NOI18N return; } if (metacomp == null) { setStatusText("FMT_MSG_AddToOthers", // NOI18N new Object[] { item.getNode().getDisplayName() }); return; } String displayName = item.getNode().getDisplayName(); RADVisualContainer metacont = metacomp instanceof RADVisualContainer ? (RADVisualContainer) metacomp : (RADVisualContainer) metacomp.getParentComponent(); if (item.isLayout()) { if (metacont != null) { if (!metacont.getLayoutSupport().isDedicated()) setStatusText("FMT_MSG_SetLayout", // NOI18N new Object[] { displayName, metacont.getName() }); else setStatusText("FMT_MSG_CannotSetLayout", // NOI18N new Object[] { metacont.getName() }); } else setStatusText("FMT_MSG_CannotSetLayout", // NOI18N new Object[] { metacomp.getName() }); } else if (item.isBorder()) { if (JComponent.class.isAssignableFrom(metacomp.getBeanClass())) setStatusText("FMT_MSG_SetBorder", // NOI18N new Object[] { displayName, metacomp.getName() }); else setStatusText("FMT_MSG_CannotSetBorder", // NOI18N new Object[] { metacomp.getName() }); } else if (metacont != null && ((item.isMenu() && metacont.getContainerMenu() == null && metacont.canHaveMenu(item.getComponentClass())) || (item.isVisual() && !item.isMenu()))) { setStatusText("FMT_MSG_AddComponent", // NOI18N new Object[] { displayName, metacont.getName() }); } else { setStatusText("FMT_MSG_AddToOthers", // NOI18N new Object[] { displayName }); } } private static void setStatusText(String formatId, Object[] args) { StatusDisplayer.getDefault().setStatusText( FormUtils.getFormattedBundleString(formatId, args)); } boolean mouseOnVisual(Point p) { Rectangle r = formDesigner.getComponentLayer().getDesignerOuterBounds(); return r.contains(p); } // --------- private class HandleLayerMouseListener implements MouseListener { public void mouseClicked(MouseEvent e) { if (SwingUtilities.isRightMouseButton(e) && !anyDragger()) if (!draggingCanceled) showContextMenu(e.getPoint()); else draggingCanceled = false; e.consume(); } public void mouseReleased(MouseEvent e) { if (!HandleLayer.this.isVisible()) return; if (SwingUtilities.isLeftMouseButton(e)) { if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT && !endDragging(e.getPoint())) { if (draggingCanceled) { draggingCanceled = false; } else if ((resizeType & DESIGNER_RESIZING) != 0 && e.getClickCount() == 2 && !e.isShiftDown() && !e.isControlDown() && !e.isAltDown()) { // doubleclick on designer's resizing border setUserDesignerSize(); } else if (prevLeftMousePoint != null && e.getClickCount() == 1 && prevLeftMousePoint.distance(e.getPoint()) <= 2 && !e.isShiftDown() && !e.isControlDown() && !e.isAltDown()) { // second click on the same place in a component formDesigner.startInPlaceEditing( getMetaComponentAt(e.getPoint(), COMP_SELECTED)); } else if (e.getClickCount() == 1 && !e.isAltDown() && !e.isControlDown() && e.isShiftDown()) { // Shift + mouse release - interval selection selectComponent(e); } } prevLeftMousePoint = lastLeftMousePoint; lastLeftMousePoint = null; } e.consume(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { StatusDisplayer.getDefault().setStatusText(""); // NOI18N } public void mousePressed(MouseEvent e) { formDesigner.componentActivated(); if (!HandleLayer.this.isVisible()) return; if (SwingUtilities.isRightMouseButton(e)) { if (!anyDragger()) { if (!mouseOnVisual(e.getPoint())) selectOtherComponentsNode(); else { RADComponent hitMetaComp = getMetaComponentAt(e.getPoint(), COMP_SELECTED); if (hitMetaComp != null && !formDesigner.isComponentSelected(hitMetaComp)) { formDesigner.setSelectedComponent(hitMetaComp); } } } else endDragging(null); e.consume(); } else if (SwingUtilities.isLeftMouseButton(e)) { lastLeftMousePoint = e.getPoint(); boolean modifier = e.isControlDown() || e.isAltDown() || e.isShiftDown(); if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT) { checkResizing(e); if (!e.isShiftDown() || e.isAltDown() || e.isControlDown()) { // mouse not pressed with Shift only (reserved for // interval or area selection, applied on mouse release // or mouse dragged) if (designerResizer == null && !modifier && (resizeType & DESIGNER_RESIZING) != 0) { // start designer resizing if (e.getClickCount() != 2) designerResizer = new DesignerResizer(); } else if (!mouseOnVisual(lastLeftMousePoint)) { if (resizeType == 0) selectOtherComponentsNode(); } else if (resizeType == 0 && (e.getClickCount() != 2 || !processDoubleClick(e))) { // no resizing, no doubleclick - select component RADComponent hitMetaComp = selectComponent(e); if (hitMetaComp != null && !modifier) // plain single click processMouseClickInLayoutSupport(hitMetaComp, e); } } draggingCanceled = false; } else if (!viewOnly) { if (formDesigner.getDesignerMode() == FormDesigner.MODE_CONNECT) { selectComponent(e); } else if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) { RADComponent hitMetaComp = getMetaComponentAt( lastLeftMousePoint, e.isAltDown() ? COMP_SELECTED : COMP_DEEPEST); PaletteItem item = CPManager.getDefault().getSelectedItem(); if (item != null) { Object constraints; if (!item.isMenu() && item.isVisual()) { constraints = getConstraintsAtPoint( hitMetaComp, lastLeftMousePoint); } else constraints = null; if (!mouseOnVisual(lastLeftMousePoint)) { formDesigner.getModel().getComponentCreator() .createComponent(item.getComponentClassSource(), null, null); } else { formDesigner.getModel().getComponentCreator() .createComponent(item.getComponentClassSource(), hitMetaComp, constraints); } } if (!e.isShiftDown()) { formDesigner.toggleSelectionMode(); draggingCanceled = true; } } } e.consume(); } } } // --------- private class HandleLayerMouseMotionListener implements MouseMotionListener { public void mouseDragged(MouseEvent e) { Point p = e.getPoint(); if (designerResizer != null) { designerResizer.drag(e.getPoint()); } else if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT && !anyDragger() && !draggingCanceled) { if (!viewOnly && !e.isControlDown() && (!e.isShiftDown() || e.isAltDown()) && lastLeftMousePoint != null && (resizeType != 0 || lastLeftMousePoint.distance(p) > 8)) { // start components dragging componentDragger = createComponentDragger( lastLeftMousePoint, e.getModifiers()); } else if (formDesigner.getTopDesignComponent() instanceof RADVisualContainer && !e.isAltDown() && !e.isControlDown() && e.isShiftDown() && lastLeftMousePoint != null && lastLeftMousePoint.distance(p) > 4) { // start selection dragging selectionDragger = new SelectionDragger(lastLeftMousePoint); } } if (componentDragger != null) { componentDragger.drag(p); repaint(); } if (selectionDragger != null) { selectionDragger.drag(p); repaint(); } e.consume(); } public void mouseMoved(MouseEvent e) { if (formDesigner.getDesignerMode() == FormDesigner.MODE_ADD) { RADComponent hitMetaComp = getMetaComponentAt(e.getPoint(), e.isControlDown() || e.isAltDown() ? COMP_SELECTED : COMP_DEEPEST); showAddHint(hitMetaComp, e.getPoint(), CPManager.getDefault().getSelectedItem()); } else if (formDesigner.getDesignerMode() == FormDesigner.MODE_SELECT) checkResizing(e); } } // ---------- private class DesignerResizer { boolean dragged = false; public void drag(Point p) { Dimension size = computeDesignerSize(p); formDesigner.getComponentLayer().updateDesignerSize(size); if (!size.equals(formDesigner.getStoredDesignerSize())) dragged = true; } public void drop(Point p) { if (dragged) { Dimension size = computeDesignerSize(p); formDesigner.setStoredDesignerSize(size); // designer size in ComponentLayer will be updated // automatically through synthetic property change processing } } private Dimension computeDesignerSize(Point p) { Rectangle r = formDesigner.getComponentLayer().getDesignerInnerBounds(); int w = r.width; int h = r.height; if ((resizeType & LayoutSupportManager.RESIZE_DOWN) != 0) { h = p.y - r.y; if (h < 0) h = 0; } if ((resizeType & LayoutSupportManager.RESIZE_RIGHT) != 0) { w = p.x - r.x; if (w < 0) w = 0; } return new Dimension(w, h); } } // ---------- private class SelectionDragger { private Point startPoint; private Point lastPoint; public SelectionDragger(Point startPoint) { this.startPoint = startPoint; } public void paintDragFeedback(Graphics g) { if (startPoint != null && lastPoint != null) { Rectangle r = getRectangle(); g.drawRect(r.x, r.y, r.width, r.height); } } public void drag(Point p) { lastPoint = p; } public void drop(Point endPoint) { if (startPoint != null && endPoint != null) { lastPoint = endPoint; ArrayList toSelect = new ArrayList(); collectSelectedComponents( getRectangle(), formDesigner.getComponentLayer().getComponentContainer(), toSelect); RADComponent[] selected = new RADComponent[toSelect.size()]; toSelect.toArray(selected); formDesigner.setSelectedComponents(selected); } } private Rectangle getRectangle() { int x = startPoint.x <= lastPoint.x ? startPoint.x : lastPoint.x; int y = startPoint.y <= lastPoint.y ? startPoint.y : lastPoint.y; int w = lastPoint.x - startPoint.x; if (w < 0) w = -w; int h = lastPoint.y - startPoint.y; if (h < 0) h = -h; return new Rectangle(x, y, w, h); } private boolean collectSelectedComponents(Rectangle selRect, Container cont, java.util.List toSelect) { ArrayList subContainers = new ArrayList(); Component[] comps = cont.getComponents(); for (int i=0; i < comps.length; i++) { Component comp = comps[i]; Rectangle bounds = SwingUtilities.convertRectangle( cont, comps[i].getBounds(), HandleLayer.this); boolean intersects = selRect.intersects(bounds); RADComponent metacomp = formDesigner.getMetaComponent(comp); if (metacomp instanceof RADComponent) { if (intersects) toSelect.add(metacomp); if (!(metacomp instanceof ComponentContainer)) continue; } if (intersects && comp instanceof Container) subContainers.add(comp); } if (toSelect.size() > 1 || (toSelect.size() == 1 && subContainers.size() == 0)) return true; Object theOnlyOne = toSelect.size() == 1 ? toSelect.get(0) : null; for (int i=0; i < subContainers.size(); i++) { toSelect.clear(); if (collectSelectedComponents(selRect, (Container)subContainers.get(i), toSelect)) return true; } if (theOnlyOne != null) { toSelect.add(theOnlyOne); return true; } return false; } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.