SwingUtilities2.java revision 726
1879N/A * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. Sun designates this 0N/A * particular file as subject to the "Classpath" exception as provided 0N/A * by Sun in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 1472N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A * A collection of utility methods for Swing. 0N/A * <b>WARNING:</b> While this class is public, it should not be treated as 0N/A * public API and its API may change in incompatable ways between dot dot 0N/A * releases and even patch releases. You should not rely on this class even 0N/A * The <code>AppContext</code> key for our one <code>LAFState</code> 0N/A // Most of applications use 10 or less fonts simultaneously 0N/A // Strong cache for the left and right side bearings 0N/A // for STRONG_BEARING_CACHE_SIZE most recently used fonts. 0N/A // Next index to insert an entry into the strong bearing cache 0N/A // Soft cache for the left and right side bearings 0N/A * A JComponent client property is used to determine text aa settings. 0N/A * To avoid having this property persist between look and feels changes 0N/A * the value of the property is set to null in JComponent.setUI 0N/A * Used to tell a text component, being used as an editor for table 0N/A * or tree, how many clicks it took to start editing. 0N/A /* Presently this class assumes default fractional metrics. 0N/A * This may need to change to emulate future platform L&Fs. 0N/A /* These are rarely constructed objects, and only when a complete 0N/A * UI is being updated, so the cost of the tests here is minimal 0N/A * and saves tests elsewhere. 0N/A * Key used in client properties used to indicate that the 0N/A * <code>ComponentUI</code> of the JComponent instance should be returned. 0N/A /** Client Property key for the text maximal offsets for BasicMenuItemUI */ 0N/A "UNTRUSTED_CLIPBOARD_ACCESS_KEY";
0N/A //all access to charsBuffer is to be synchronized on charsBufferLock 0N/A * checks whether TextLayout is required to handle characters. 0N/A * @param text characters to be tested 0N/A * @param start start 0N/A * @param limit limit 0N/A * @return <tt>true</tt> if TextLayout is required 0N/A * <tt>false</tt> if TextLayout is not required 0N/A // WARNING WARNING WARNING WARNING WARNING WARNING 0N/A // Many of the following methods are invoked from older API. 0N/A // As this older API was not passed a Component, a null Component may 0N/A // now be passsed in. For example, SwingUtilities.computeStringWidth 0N/A // is implemented to call SwingUtilities2.stringWidth, the 0N/A // SwingUtilities variant does not take a JComponent, as such 0N/A // SwingUtilities2.stringWidth can be passed a null Component. 0N/A // In other words, if you add new functionality to these methods you 0N/A // need to gracefully handle null. 0N/A * Returns whether or not text should be drawn antialiased. 0N/A * @param c JComponent to test. 0N/A * @return Whether or not text should be drawn antialiased for the 0N/A * specified component. 0N/A /* a non-null property implies some form of AA requested */ 0N/A // No component, assume aa is off 0N/A * Returns the left side bearing of the first character of string. The 0N/A * left side bearing is calculated from the passed in FontMetrics. 0N/A * @param c JComponent that will display the string 0N/A * @param fm FontMetrics used to measure the String width 0N/A * @param string String to get the left side bearing for. 0N/A * Returns the left side bearing of the specified character. The 0N/A * left side bearing is calculated from the passed in FontMetrics. 0N/A * @param c JComponent that will display the string 0N/A * @param fm FontMetrics used to measure the String width 0N/A * @param firstChar Character to get the left side bearing for. 0N/A * Returns the right side bearing of the last character of string. The 0N/A * right side bearing is calculated from the passed in FontMetrics. 0N/A * @param c JComponent that will display the string 0N/A * @param fm FontMetrics used to measure the String width 0N/A * @param string String to get the right side bearing for. 0N/A * Returns the right side bearing of the specified character. The 0N/A * right side bearing is calculated from the passed in FontMetrics. 0N/A * @param c JComponent that will display the string 0N/A * @param fm FontMetrics used to measure the String width 0N/A * @param lastChar Character to get the right side bearing for. 0N/A /* Calculates the left and right side bearing for a character. 0N/A * Strongly caches bearings for STRONG_BEARING_CACHE_SIZE 0N/A * most recently used Fonts and softly caches as many as GC allows. 0N/A // See if we already have an entry in the strong cache 0N/A // See if we already have an entry in the soft cache 113N/A // Remove discarded soft reference from the cache 0N/A // Move the oldest entry from the strong cache into the soft cache 0N/A // Put entry in the strong cache 0N/A * Returns the FontMetrics for the current Font of the passed 0N/A * in Graphics. This method is used when a Graphics 0N/A * is available, typically when painting. If a Graphics is not 0N/A * available the JComponent method of the same name should be used. 113N/A * Callers should pass in a non-null JComponent, the exception 0N/A * to this is if a JComponent is not readily available at the time of 0N/A * This does not necessarily return the FontMetrics from the 0N/A * @param c JComponent requesting FontMetrics, may be null 113N/A * @param g Graphics Graphics 0N/A * Returns the FontMetrics for the specified Font. 0N/A * This method is used when a Graphics is available, typically when 0N/A * painting. If a Graphics is not available the JComponent method of 0N/A * the same name should be used. 0N/A * Callers should pass in a non-null JComonent, the exception 0N/A * to this is if a JComponent is not readily available at the time of 0N/A * This does not necessarily return the FontMetrics from the 0N/A * @param c JComponent requesting FontMetrics, may be null 0N/A * @param c Graphics Graphics 0N/A * @param font Font to get FontMetrics for 858N/A // Note: We assume that we're using the FontMetrics 858N/A // from the widget to layout out text, otherwise we can get 858N/A // mismatches when printing. 0N/A * Returns the width of the passed in String. 0N/A * If the passed String is <code>null</code>, returns zero. 0N/A * @param c JComponent that will display the string, may be null 0N/A * @param fm FontMetrics used to measure the String width 113N/A * @param string String to get the width of 858N/A * Clips the passed in String to the space provided. 858N/A * @param c JComponent that will display the string, may be null 858N/A * @param fm FontMetrics used to measure the String width 858N/A * @param string String to display 858N/A * @param availTextWidth Amount of space that the string can be drawn in 0N/A * @return Clipped string that can fit in the provided space. 858N/A * Clips the passed in String to the space provided. NOTE: this assumes 0N/A * the string does not fit in the available space. 113N/A * @param c JComponent that will display the string, may be null 113N/A * @param fm FontMetrics used to measure the String width 113N/A * @param string String to display 113N/A * @param availTextWidth Amount of space that the string can be drawn in 113N/A * @return Clipped string that can fit in the provided space. 0N/A //can not fit any characters 0N/A * Draws the string at the specified location. 0N/A * @param c JComponent that will display the string, may be null 0N/A * @param g Graphics to draw the text to 0N/A * @param text String to display 0N/A * @param x X coordinate to draw the text at 0N/A * @param y Y coordinate to draw the text at 0N/A // All non-editable widgets that draw strings call into this 0N/A // methods. By non-editable that means widgets like JLabel, JButton 0N/A // but NOT JTextComponents. 0N/A /* The printed text must scale linearly with the UI. 0N/A * Calculate the width on screen, obtain a TextLayout with 0N/A * advances for the printer graphics FRC, and then justify 0N/A * it to fit in the screen width. This distributes the spacing 0N/A * more evenly than directly laying out to the screen advances. 0N/A /* Use alternate print color if specified */ 25N/A // If we get here we're not printing 0N/A * Draws the string at the specified location underlining the specified 0N/A * @param c JComponent that will display the string, may be null 0N/A * @param g Graphics to draw the text to 0N/A * @param text String to display 0N/A * @param underlinedIndex Index of a character in the string to underline 100N/A * @param x X coordinate to draw the text at 0N/A * @param y Y coordinate to draw the text at 0N/A * A variation of locationToIndex() which only returns an index if the 0N/A * Point is within the actual bounds of a list item (not just in the cell) 0N/A * and if the JList has the "List.isFileList" client property set. 0N/A * Otherwise, this method returns -1. 0N/A * This is used to make WindowsL&F JFileChooser act like native dialogs. 0N/A * Returns true if the given point is within the actual bounds of the 0N/A * JList item at index (not just inside the cell). * Returns true if the given point is outside the preferredSize of the * item at the given row of the table. (Column must be 0). * Does not check the "Table.isFileList" property. That should be checked * before calling this method. * This is used to make WindowsL&F JFileChooser act like native dialogs. // See if coords are inside // ASSUME: mouse x,y will never be < cell's x,y * Set the lead and anchor without affecting selection. * Ignore mouse events if the component is null, not enabled, the event * is not associated with the left mouse button, or the event has been * Request focus on the given component if it doesn't already have it * and <code>isRequestFocusEnabled()</code> returns true. * The following draw functions have the same semantic as the * Graphics methods with the same names. * this is used for printing if (
length <=
0 ) {
//no need to paint empty strings /* Use alternate print color if specified */ // Assume we're not printing if we get here, or that we are invoked // via Swing text printing which is laid out for the printer. * see documentation for drawChars /* Use alternate print color if specified */ //matters it should not happen * Checks if two given FontRenderContexts are compatible for printing. * We can't just use equals as we want to exclude from the comparison : * + whether AA is set as irrelevant for printing and shouldn't affect * + any translation component in the transform of either FRC, as it * does not affect metrics. * Compatible means no special handling needed for text painting /* If both are identity, return true */ /* That's the end of the cheap tests, need to get and compare * the transform matrices. We don't care about the translation * components, so return true if they are otherwise identical. double[]
mat1 =
new double[
4];
double[]
mat2 =
new double[
4];
* Tries it best to get Graphics2D out of the given Graphics * returns null if can not derive it. * Returns FontRenderContext associated with Component. * FontRenderContext from Component.getFontMetrics is associated * Uses Component.getFontMetrics to get the FontRenderContext from. * A convenience method to get FontRenderContext. * Returns the FontRenderContext for the passed in FontMetrics or * for the passed in Component if FontMetrics is null * This method is to be used only for JComponent.getFontMetrics. * In all other places to get FontMetrics we need to use * JComponent.getFontMetrics. /* Get any FontRenderContext associated with a JComponent * returns true if the Graphics is print Graphics * Determines whether the SelectedTextColor should be used for painting text * foreground for the specified highlight. * Returns true only if the highlight painter for the specified highlight * is the swing painter (whether inner class of javax.swing.text.DefaultHighlighter * or com.sun.java.swing.plaf.windows.WindowsTextUI) and its background color * is null or equals to the selection color of the text component. * This is a hack for fixing both bugs 4761990 and 5003294 * BearingCacheEntry is used to cache left and right character bearings * for a particular <code>Font</code> and <code>FontRenderContext</code>. // Used for the creation of a GlyphVector private static final char[]
oneChar =
new char[
1];
return ((
0xFF00 &
bearing) >>>
8) -
127;
/* Calculates left and right side bearings for a character. * Makes an assumption that bearing is a value between -127 and +127. * Stores LSB and RSB as single two-byte number (short): * LSB is the high byte, RSB is the low byte. /* HRGB/HBGR LCD glyph images will always have a pixel * on the left and a pixel on the right * used in colour fringe reduction. * Text rendering positions this correctly but here * we are using the glyph image to adjust that position * so must account for it. // Make sure that LSB and RSB are valid (see 6472972) if (
lsb < -
127 ||
lsb >
127) {
if (
rsb < -
127 ||
rsb >
127) {
* here goes the fix for 4856343 [Problem with applet interaction * with system selection clipboard] * NOTE. In case isTrustedContext() no checking * checks the security permissions for accessing system clipboard * for untrusted context (see isTrustedContext) checks the * permissions for the current event being handled * Returns true if EventQueue.getCurrentEvent() has the permissions to * access the system clipboard * Returns true if the given event has permissions to access the * @param e AWTEvent to check * returns canAccessSystemClipboard field from InputEvent * @param ie InputEvent to get the field from * Returns true if the given event is corrent gesture for * @param ie InputEvent to check if (
ie instanceof KeyEvent) {
//we can validate only keyboard gestures * Returns true if e has the permissions to * access the system clipboard and if it is allowed gesture (if * @param e AWTEvent to check * @param checkGesture boolean * Checking event permissions makes sense only for event * Returns true if EventQueue.getCurrentEvent() has the permissions to * access the system clipboard and if it is allowed gesture (if * @param checkGesture boolean * see RFE 5012841 [Per AppContect security permissions] for the * Utility method that creates a <code>UIDefaults.LazyValue</code> that * creates an <code>ImageIcon</code> <code>UIResource</code> for the * specified image file name. The image is loaded using * <code>getResourceAsStream</code>, starting with a call to that method * on the base class parameter. If it cannot be found, searching will * continue through the base class' inheritance hierarchy, up to and * including <code>rootClass</code>. * @param baseClass the first class to use in searching for the resource * @param rootClass an ancestor of <code>baseClass</code> to finish the * @param imageFile the name of the file to be found * @return a lazy value that creates the <code>ImageIcon</code> * <code>UIResource</code> for the image, * or null if it cannot be found /* Copy resource into a byte array. This is * necessary because several browsers consider * Class.getResource a security risk because it * can be used to load additional classes. * Class.getResourceAsStream just returns raw * bytes, which we can convert to an image. byte[]
buffer =
new byte[
1024];
/* Used to help decide if AA text rendering should be used, so * this local display test should be additionally qualified * against whether we have XRender support on both ends of the wire, * as with that support remote performance may be good enough to turn * on by default. An additional complication there is XRender does not * appear capable of performing gamma correction needed for LCD text. // On Windows just return true. Permission to read os.name // is granted to all code but wrapped in try to be safe. // Else probably Solaris or Linux in which case may be remote X11 "isDisplayLocal",
new Class[
0]);
// If we get here we're most likely being run on some other O/S // or we didn't properly detect Windows. * Returns an integer from the defaults table. If <code>key</code> does * not map to a valid <code>Integer</code>, or can not be convered from * a <code>String</code> to an integer, the value 0 is returned. * @param key an <code>Object</code> specifying the int. * Returns an integer from the defaults table that is appropriate * for the given locale. If <code>key</code> does not map to a valid * <code>Integer</code>, or can not be convered from a <code>String</code> * to an integer, the value 0 is returned. * @param key an <code>Object</code> specifying the int. Returned value * is 0 if <code>key</code> is not available, * @param l the <code>Locale</code> for which the int is desired * Returns an integer from the defaults table. If <code>key</code> does * not map to a valid <code>Integer</code>, or can not be convered from * a <code>String</code> to an integer, <code>default</code> is * @param key an <code>Object</code> specifying the int. Returned value * is 0 if <code>key</code> is not available, * @param defaultValue Returned value if <code>key</code> is not available, * Returns an integer from the defaults table that is appropriate * for the given locale. If <code>key</code> does not map to a valid * <code>Integer</code>, or can not be convered from a <code>String</code> * to an integer, <code>default</code> is returned. * @param key an <code>Object</code> specifying the int. Returned value * is 0 if <code>key</code> is not available, * @param l the <code>Locale</code> for which the int is desired * @param defaultValue Returned value if <code>key</code> is not available, // At this point we need this method here. But we assume that there // will be a common method for this purpose in the future releases. * Change focus to the visible component in {@code JTabbedPane}. * This is not a general-purpose method and is here only to permit * Submits a value-returning task for execution on the EDT and * returns a Future representing the pending results of the task. * @param task the task to submit * @return a Future representing pending completion of the task * @throws NullPointerException if the task is null * Submits a Runnable task for execution on the EDT and returns a * Future representing that task. * @param task the task to submit * @param result the result to return upon successful completion * @return a Future representing pending completion of the task, * and whose <tt>get()</tt> method will return the given * result value upon completion * @throws NullPointerException if the task is null * Sends a Runnable to the EDT for the execution. * Sets the {@code SKIP_CLICK_COUNT} client property on the component * if it is an instance of {@code JTextComponent} with a * {@code DefaultCaret}. This property, used for text components acting * as editors in a table or tree, tells {@code DefaultCaret} how many * clicks to skip before starting selection. * Return the MouseEvent's click count, possibly reduced by the value of * the component's {@code SKIP_CLICK_COUNT} client property. Clears * the {@code SKIP_CLICK_COUNT} property if the mouse event's click count * is 1. In order for clearing of the property to work correctly, there * must be a mousePressed implementation on the caller with this * call as the first line. * Used by the {@code liesIn} method to return which section /** The leading section */ /** The middle section */ /** The trailing section */ * This method divides a rectangle into two or three sections along * the specified axis and determines which section the given point * lies in on that axis; used by drag and drop when calculating drop * For two sections, the rectangle is divided equally and the method * returns whether the point lies in {@code Section.LEADING} or * {@code Section.TRAILING}. For horizontal divisions, the calculation * respects component orientation. * For three sections, if the rectangle is greater than or equal to * 30 pixels in length along the axis, the calculation gives 10 pixels * to each of the leading and trailing sections and the remainder to the * middle. For smaller sizes, the rectangle is divided equally into three * Note: This method assumes that the point is within the bounds of * the given rectangle on the specified axis. However, in cases where * it isn't, the results still have meaning: {@code Section.MIDDLE} * remains the same, {@code Section.LEADING} indicates that the point * is in or somewhere before the leading section, and * {@code Section.TRAILING} indicates that the point is in or somewhere * after the trailing section. * @param rect the rectangle * @param p the point the check * @param horizontal {@code true} to use the horizontal axis, * or {@code false} for the vertical axis * @param ltr {@code true} for left to right orientation, * or {@code false} for right to left orientation; * only used for horizontal calculations * @param three {@code true} for three sections, * or {@code false} for two * @return the {@code Section} where the point lies * @throws NullPointerException if {@code rect} or {@code p} are /* beginning of the rectangle on the axis */ /* point on the axis we're interested in */ /* length of the rectangle on the axis */ /* value of ltr if horizontal, else true */ * This method divides a rectangle into two or three sections along * the horizontal axis and determines which section the given point * lies in; used by drag and drop when calculating drop locations. * See the documentation for {@link #liesIn} for more information * on how the section is calculated. * @param rect the rectangle * @param p the point the check * @param ltr {@code true} for left to right orientation, * or {@code false} for right to left orientation * @param three {@code true} for three sections, * or {@code false} for two * @return the {@code Section} where the point lies * @throws NullPointerException if {@code rect} or {@code p} are * This method divides a rectangle into two or three sections along * the vertical axis and determines which section the given point * lies in; used by drag and drop when calculating drop locations. * See the documentation for {@link #liesIn} for more information * on how the section is calculated. * @param rect the rectangle * @param p the point the check * @param three {@code true} for three sections, * or {@code false} for two * @return the {@code Section} where the point lies * @throws NullPointerException if {@code rect} or {@code p} are