2086 lines · 78.8 KB · Java
RawDownload
/* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */package javax.swing; import sun.swing.SwingUtilities2;import sun.swing.UIAction; import java.applet.*; import java.awt.*;import java.awt.event.*;import java.awt.dnd.DropTarget; import java.util.Vector;import java.util.Hashtable; import java.lang.reflect.*; import javax.accessibility.*;import javax.swing.event.MenuDragMouseEvent;import javax.swing.plaf.UIResource;import javax.swing.text.View;import java.security.AccessController;import sun.security.action.GetPropertyAction; import sun.awt.AppContext; /** * A collection of utility methods for Swing. * * @author unknown */public class SwingUtilities implements SwingConstants{    // These states are system-wide, rather than AppContext wide.    private static boolean canAccessEventQueue = false;    private static boolean eventQueueTested = false;     /**     * Indicates if we should change the drop target when a     * {@code TransferHandler} is set.     */    private static boolean suppressDropSupport;     /**     * Indiciates if we've checked the system property for suppressing     * drop support.     */    private static boolean checkedSuppressDropSupport;      /**     * Returns true if <code>setTransferHandler</code> should change the     * <code>DropTarget</code>.     */    private static boolean getSuppressDropTarget() {        if (!checkedSuppressDropSupport) {            suppressDropSupport = Boolean.valueOf(                AccessController.doPrivileged(                    new GetPropertyAction("suppressSwingDropSupport")));            checkedSuppressDropSupport = true;        }        return suppressDropSupport;    }     /**     * Installs a {@code DropTarget} on the component as necessary for a     * {@code TransferHandler} change.     */    static void installSwingDropTargetAsNecessary(Component c,                                                         TransferHandler t) {         if (!getSuppressDropTarget()) {            DropTarget dropHandler = c.getDropTarget();            if ((dropHandler == null) || (dropHandler instanceof UIResource)) {                if (t == null) {                    c.setDropTarget(null);                } else if (!GraphicsEnvironment.isHeadless()) {                    c.setDropTarget(new TransferHandler.SwingDropTarget(c));                }            }        }    }     /**     * Return true if <code>a</code> contains <code>b</code>     */    public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) {        return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) &&                b.y >= a.y && (b.y + b.height) <= (a.y + a.height);    }     /**     * Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code>     */    public static Rectangle getLocalBounds(Component aComponent) {        Rectangle b = new Rectangle(aComponent.getBounds());        b.x = b.y = 0;        return b;    }      /**     * Returns the first <code>Window </code> ancestor of <code>c</code>, or     * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.     *     * @param c <code>Component</code> to get <code>Window</code> ancestor     *        of.     * @return the first <code>Window </code> ancestor of <code>c</code>, or     *         {@code null} if <code>c</code> is not contained inside a     *         <code>Window</code>.     * @since 1.3     */    public static Window getWindowAncestor(Component c) {        for(Container p = c.getParent(); p != null; p = p.getParent()) {            if (p instanceof Window) {                return (Window)p;            }        }        return null;    }     /**     * Converts the location <code>x</code> <code>y</code> to the     * parents coordinate system, returning the location.     */    static Point convertScreenLocationToParent(Container parent,int x, int y) {        for (Container p = parent; p != null; p = p.getParent()) {            if (p instanceof Window) {                Point point = new Point(x, y);                 SwingUtilities.convertPointFromScreen(point, parent);                return point;            }        }        throw new Error("convertScreenLocationToParent: no window ancestor");    }     /**     * Convert a <code>aPoint</code> in <code>source</code> coordinate system to     * <code>destination</code> coordinate system.     * If <code>source</code> is {@code null}, <code>aPoint</code> is assumed to be in <code>destination</code>'s     * root component coordinate system.     * If <code>destination</code> is {@code null}, <code>aPoint</code> will be converted to <code>source</code>'s     * root component coordinate system.     * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aPoint</code>     * without any conversion.     */    public static Point convertPoint(Component source,Point aPoint,Component destination) {        Point p;         if(source == null && destination == null)            return aPoint;        if(source == null) {            source = getWindowAncestor(destination);            if(source == null)                throw new Error("Source component not connected to component tree hierarchy");        }        p = new Point(aPoint);        convertPointToScreen(p,source);        if(destination == null) {            destination = getWindowAncestor(source);            if(destination == null)                throw new Error("Destination component not connected to component tree hierarchy");        }        convertPointFromScreen(p,destination);        return p;    }     /**     * Convert the point <code>(x,y)</code> in <code>source</code> coordinate system to     * <code>destination</code> coordinate system.     * If <code>source</code> is {@code null}, <code>(x,y)</code> is assumed to be in <code>destination</code>'s     * root component coordinate system.     * If <code>destination</code> is {@code null}, <code>(x,y)</code> will be converted to <code>source</code>'s     * root component coordinate system.     * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>(x,y)</code>     * without any conversion.     */    public static Point convertPoint(Component source,int x, int y,Component destination) {        Point point = new Point(x,y);        return convertPoint(source,point,destination);    }     /**     * Convert the rectangle <code>aRectangle</code> in <code>source</code> coordinate system to     * <code>destination</code> coordinate system.     * If <code>source</code> is {@code null}, <code>aRectangle</code> is assumed to be in <code>destination</code>'s     * root component coordinate system.     * If <code>destination</code> is {@code null}, <code>aRectangle</code> will be converted to <code>source</code>'s     * root component coordinate system.     * If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aRectangle</code>     * without any conversion.     */    public static Rectangle convertRectangle(Component source,Rectangle aRectangle,Component destination) {        Point point = new Point(aRectangle.x,aRectangle.y);        point =  convertPoint(source,point,destination);        return new Rectangle(point.x,point.y,aRectangle.width,aRectangle.height);    }     /**     * Convenience method for searching above <code>comp</code> in the     * component hierarchy and returns the first object of class <code>c</code> it     * finds. Can return {@code null}, if a class <code>c</code> cannot be found.     */    public static Container getAncestorOfClass(Class<?> c, Component comp)    {        if(comp == null || c == null)            return null;         Container parent = comp.getParent();        while(parent != null && !(c.isInstance(parent)))            parent = parent.getParent();        return parent;    }     /**     * Convenience method for searching above <code>comp</code> in the     * component hierarchy and returns the first object of <code>name</code> it     * finds. Can return {@code null}, if <code>name</code> cannot be found.     */    public static Container getAncestorNamed(String name, Component comp) {        if(comp == null || name == null)            return null;         Container parent = comp.getParent();        while(parent != null && !(name.equals(parent.getName())))            parent = parent.getParent();        return parent;    }     /**     * Returns the deepest visible descendent Component of <code>parent</code>     * that contains the location <code>x</code>, <code>y</code>.     * If <code>parent</code> does not contain the specified location,     * then <code>null</code> is returned.  If <code>parent</code> is not a     * container, or none of <code>parent</code>'s visible descendents     * contain the specified location, <code>parent</code> is returned.     *     * @param parent the root component to begin the search     * @param x the x target location     * @param y the y target location     */    public static Component getDeepestComponentAt(Component parent, int x, int y) {        if (!parent.contains(x, y)) {            return null;        }        if (parent instanceof Container) {            Component components[] = ((Container)parent).getComponents();            for (Component comp : components) {                if (comp != null && comp.isVisible()) {                    Point loc = comp.getLocation();                    if (comp instanceof Container) {                        comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y);                    } else {                        comp = comp.getComponentAt(x - loc.x, y - loc.y);                    }                    if (comp != null && comp.isVisible()) {                        return comp;                    }                }            }        }        return parent;    }      /**     * Returns a MouseEvent similar to <code>sourceEvent</code> except that its x     * and y members have been converted to <code>destination</code>'s coordinate     * system.  If <code>source</code> is {@code null}, <code>sourceEvent</code> x and y members     * are assumed to be into <code>destination</code>'s root component coordinate system.     * If <code>destination</code> is <code>null</code>, the     * returned MouseEvent will be in <code>source</code>'s coordinate system.     * <code>sourceEvent</code> will not be changed. A new event is returned.     * the <code>source</code> field of the returned event will be set     * to <code>destination</code> if destination is non-{@code null}     * use the translateMouseEvent() method to translate a mouse event from     * one component to another without changing the source.     */    public static MouseEvent convertMouseEvent(Component source,                                               MouseEvent sourceEvent,                                               Component destination) {        Point p = convertPoint(source,new Point(sourceEvent.getX(),                                                sourceEvent.getY()),                               destination);        Component newSource;         if(destination != null)            newSource = destination;        else            newSource = source;         MouseEvent newEvent;        if (sourceEvent instanceof MouseWheelEvent) {            MouseWheelEvent sourceWheelEvent = (MouseWheelEvent)sourceEvent;            newEvent = new MouseWheelEvent(newSource,                                           sourceWheelEvent.getID(),                                           sourceWheelEvent.getWhen(),                                           sourceWheelEvent.getModifiers(),                                           p.x,p.y,                                           sourceWheelEvent.getXOnScreen(),                                           sourceWheelEvent.getYOnScreen(),                                           sourceWheelEvent.getClickCount(),                                           sourceWheelEvent.isPopupTrigger(),                                           sourceWheelEvent.getScrollType(),                                           sourceWheelEvent.getScrollAmount(),                                           sourceWheelEvent.getWheelRotation());        }        else if (sourceEvent instanceof MenuDragMouseEvent) {            MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent)sourceEvent;            newEvent = new MenuDragMouseEvent(newSource,                                              sourceMenuDragEvent.getID(),                                              sourceMenuDragEvent.getWhen(),                                              sourceMenuDragEvent.getModifiers(),                                              p.x,p.y,                                              sourceMenuDragEvent.getXOnScreen(),                                              sourceMenuDragEvent.getYOnScreen(),                                              sourceMenuDragEvent.getClickCount(),                                              sourceMenuDragEvent.isPopupTrigger(),                                              sourceMenuDragEvent.getPath(),                                              sourceMenuDragEvent.getMenuSelectionManager());        }        else {            newEvent = new MouseEvent(newSource,                                      sourceEvent.getID(),                                      sourceEvent.getWhen(),                                      sourceEvent.getModifiers(),                                      p.x,p.y,                                      sourceEvent.getXOnScreen(),                                      sourceEvent.getYOnScreen(),                                      sourceEvent.getClickCount(),                                      sourceEvent.isPopupTrigger(),                                      MouseEvent.NOBUTTON );        }        return newEvent;    }      /**     * Convert a point from a component's coordinate system to     * screen coordinates.     *     * @param p  a Point object (converted to the new coordinate system)     * @param c  a Component object     */    public static void convertPointToScreen(Point p,Component c) {            Rectangle b;            int x,y;             do {                if(c instanceof JComponent) {                    x = c.getX();                    y = c.getY();                } else if(c instanceof java.applet.Applet ||                          c instanceof java.awt.Window) {                    try {                        Point pp = c.getLocationOnScreen();                        x = pp.x;                        y = pp.y;                    } catch (IllegalComponentStateException icse) {                        x = c.getX();                        y = c.getY();                    }                } else {                    x = c.getX();                    y = c.getY();                }                 p.x += x;                p.y += y;                 if(c instanceof java.awt.Window || c instanceof java.applet.Applet)                    break;                c = c.getParent();            } while(c != null);        }     /**     * Convert a point from a screen coordinates to a component's     * coordinate system     *     * @param p  a Point object (converted to the new coordinate system)     * @param c  a Component object     */    public static void convertPointFromScreen(Point p,Component c) {        Rectangle b;        int x,y;         do {            if(c instanceof JComponent) {                x = c.getX();                y = c.getY();            }  else if(c instanceof java.applet.Applet ||                       c instanceof java.awt.Window) {                try {                    Point pp = c.getLocationOnScreen();                    x = pp.x;                    y = pp.y;                } catch (IllegalComponentStateException icse) {                    x = c.getX();                    y = c.getY();                }            } else {                x = c.getX();                y = c.getY();            }             p.x -= x;            p.y -= y;             if(c instanceof java.awt.Window || c instanceof java.applet.Applet)                break;            c = c.getParent();        } while(c != null);    }     /**     * Returns the first <code>Window </code> ancestor of <code>c</code>, or     * {@code null} if <code>c</code> is not contained inside a <code>Window</code>.     * <p>     * Note: This method provides the same functionality as     * <code>getWindowAncestor</code>.     *     * @param c <code>Component</code> to get <code>Window</code> ancestor     *        of.     * @return the first <code>Window </code> ancestor of <code>c</code>, or     *         {@code null} if <code>c</code> is not contained inside a     *         <code>Window</code>.     */    public static Window windowForComponent(Component c) {        return getWindowAncestor(c);    }     /**     * Return <code>true</code> if a component <code>a</code> descends from a component <code>b</code>     */    public static boolean isDescendingFrom(Component a,Component b) {        if(a == b)            return true;        for(Container p = a.getParent();p!=null;p=p.getParent())            if(p == b)                return true;        return false;    }      /**     * Convenience to calculate the intersection of two rectangles     * without allocating a new rectangle.     * If the two rectangles don't intersect,     * then the returned rectangle begins at (0,0)     * and has zero width and height.     *     * @param x       the X coordinate of the first rectangle's top-left point     * @param y       the Y coordinate of the first rectangle's top-left point     * @param width   the width of the first rectangle     * @param height  the height of the first rectangle     * @param dest    the second rectangle     *     * @return <code>dest</code>, modified to specify the intersection     */    public static Rectangle computeIntersection(int x,int y,int width,int height,Rectangle dest) {        int x1 = (x > dest.x) ? x : dest.x;        int x2 = ((x+width) < (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width);        int y1 = (y > dest.y) ? y : dest.y;        int y2 = ((y + height) < (dest.y + dest.height) ? (y+height) : (dest.y + dest.height));         dest.x = x1;        dest.y = y1;        dest.width = x2 - x1;        dest.height = y2 - y1;         // If rectangles don't intersect, return zero'd intersection.        if (dest.width < 0 || dest.height < 0) {            dest.x = dest.y = dest.width = dest.height = 0;        } 

Lines 1–500 of 2086.