1.1 --- a/openide.util/src/org/openide/util/Utilities.java Wed Jan 27 17:46:23 2010 -0500
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,3115 +0,0 @@
1.4 -/*
1.5 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
1.6 - *
1.7 - * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
1.8 - *
1.9 - * The contents of this file are subject to the terms of either the GNU
1.10 - * General Public License Version 2 only ("GPL") or the Common
1.11 - * Development and Distribution License("CDDL") (collectively, the
1.12 - * "License"). You may not use this file except in compliance with the
1.13 - * License. You can obtain a copy of the License at
1.14 - * http://www.netbeans.org/cddl-gplv2.html
1.15 - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
1.16 - * specific language governing permissions and limitations under the
1.17 - * License. When distributing the software, include this License Header
1.18 - * Notice in each file and include the License file at
1.19 - * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
1.20 - * particular file as subject to the "Classpath" exception as provided
1.21 - * by Sun in the GPL Version 2 section of the License file that
1.22 - * accompanied this code. If applicable, add the following below the
1.23 - * License Header, with the fields enclosed by brackets [] replaced by
1.24 - * your own identifying information:
1.25 - * "Portions Copyrighted [year] [name of copyright owner]"
1.26 - *
1.27 - * Contributor(s):
1.28 - *
1.29 - * The Original Software is NetBeans. The Initial Developer of the Original
1.30 - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
1.31 - * Microsystems, Inc. All Rights Reserved.
1.32 - *
1.33 - * If you wish your version of this file to be governed by only the CDDL
1.34 - * or only the GPL Version 2, indicate your decision by adding
1.35 - * "[Contributor] elects to include this software in this distribution
1.36 - * under the [CDDL or GPL Version 2] license." If you do not indicate a
1.37 - * single choice of license, a recipient has the option to distribute
1.38 - * your version of this file under either the CDDL, the GPL Version 2 or
1.39 - * to extend the choice of license to its licensees as provided above.
1.40 - * However, if you add GPL Version 2 code and therefore, elected the GPL
1.41 - * Version 2 license, then the option applies only if the new code is
1.42 - * made subject to such option by the copyright holder.
1.43 - */
1.44 -
1.45 -package org.openide.util;
1.46 -
1.47 -import java.awt.BorderLayout;
1.48 -import java.awt.Component;
1.49 -import java.awt.Container;
1.50 -import java.awt.Cursor;
1.51 -import java.awt.Dialog;
1.52 -import java.awt.Dimension;
1.53 -import java.awt.Event;
1.54 -import java.awt.Frame;
1.55 -import java.awt.GraphicsConfiguration;
1.56 -import java.awt.GraphicsEnvironment;
1.57 -import java.awt.Image;
1.58 -import java.awt.Insets;
1.59 -import java.awt.KeyboardFocusManager;
1.60 -import java.awt.Point;
1.61 -import java.awt.Rectangle;
1.62 -import java.awt.Toolkit;
1.63 -import java.awt.Window;
1.64 -import java.awt.event.ActionEvent;
1.65 -import java.awt.event.ActionListener;
1.66 -import java.awt.event.KeyEvent;
1.67 -import java.io.BufferedReader;
1.68 -import java.io.File;
1.69 -import java.io.IOException;
1.70 -import java.io.InputStreamReader;
1.71 -import java.lang.ref.Reference;
1.72 -import java.lang.ref.ReferenceQueue;
1.73 -import java.lang.ref.SoftReference;
1.74 -import java.lang.reflect.Field;
1.75 -import java.lang.reflect.Method;
1.76 -import java.lang.reflect.Modifier;
1.77 -import java.net.MalformedURLException;
1.78 -import java.net.URI;
1.79 -import java.net.URISyntaxException;
1.80 -import java.net.URL;
1.81 -import java.text.BreakIterator;
1.82 -import java.util.ArrayList;
1.83 -import java.util.Arrays;
1.84 -import java.util.Collection;
1.85 -import java.util.Collections;
1.86 -import java.util.Comparator;
1.87 -import java.util.Enumeration;
1.88 -import java.util.HashMap;
1.89 -import java.util.HashSet;
1.90 -import java.util.Iterator;
1.91 -import java.util.LinkedList;
1.92 -import java.util.List;
1.93 -import java.util.Locale;
1.94 -import java.util.Map;
1.95 -import java.util.NoSuchElementException;
1.96 -import java.util.Set;
1.97 -import java.util.StringTokenizer;
1.98 -import java.util.TreeSet;
1.99 -import java.util.Vector;
1.100 -import java.util.logging.Level;
1.101 -import java.util.logging.Logger;
1.102 -import javax.swing.Action;
1.103 -import javax.swing.Icon;
1.104 -import javax.swing.JMenuItem;
1.105 -import javax.swing.JPopupMenu;
1.106 -import javax.swing.JSeparator;
1.107 -import javax.swing.KeyStroke;
1.108 -import javax.swing.SwingUtilities;
1.109 -import javax.swing.Timer;
1.110 -import org.openide.util.actions.Presenter;
1.111 -import org.openide.util.lookup.Lookups;
1.112 -import org.openide.util.lookup.implspi.ActiveQueue;
1.113 -import org.openide.util.actions.ActionPresenterProvider;
1.114 -
1.115 -/** Otherwise uncategorized useful static methods.
1.116 -*
1.117 -* @author Jan Palka, Ian Formanek, Jaroslav Tulach
1.118 -*/
1.119 -public final class Utilities {
1.120 -
1.121 - private static final Logger LOG = Logger.getLogger(Utilities.class.getName());
1.122 -
1.123 - /** Operating system is Windows NT. */
1.124 - public static final int OS_WINNT = 1 << 0;
1.125 -
1.126 - /** Operating system is Windows 95. */
1.127 - public static final int OS_WIN95 = OS_WINNT << 1;
1.128 -
1.129 - /** Operating system is Windows 98. */
1.130 - public static final int OS_WIN98 = OS_WIN95 << 1;
1.131 -
1.132 - /** Operating system is Solaris. */
1.133 - public static final int OS_SOLARIS = OS_WIN98 << 1;
1.134 -
1.135 - /** Operating system is Linux. */
1.136 - public static final int OS_LINUX = OS_SOLARIS << 1;
1.137 -
1.138 - /** Operating system is HP-UX. */
1.139 - public static final int OS_HP = OS_LINUX << 1;
1.140 -
1.141 - /** Operating system is IBM AIX. */
1.142 - public static final int OS_AIX = OS_HP << 1;
1.143 -
1.144 - /** Operating system is SGI IRIX. */
1.145 - public static final int OS_IRIX = OS_AIX << 1;
1.146 -
1.147 - /** Operating system is Sun OS. */
1.148 - public static final int OS_SUNOS = OS_IRIX << 1;
1.149 -
1.150 - /** Operating system is Compaq TRU64 Unix */
1.151 - public static final int OS_TRU64 = OS_SUNOS << 1;
1.152 -
1.153 - /** @deprecated please use OS_TRU64 instead */
1.154 - @Deprecated
1.155 - public static final int OS_DEC = OS_TRU64 << 1;
1.156 -
1.157 - /** Operating system is OS/2. */
1.158 - public static final int OS_OS2 = OS_DEC << 1;
1.159 -
1.160 - /** Operating system is Mac. */
1.161 - public static final int OS_MAC = OS_OS2 << 1;
1.162 -
1.163 - /** Operating system is Windows 2000. */
1.164 - public static final int OS_WIN2000 = OS_MAC << 1;
1.165 -
1.166 - /** Operating system is Compaq OpenVMS */
1.167 - public static final int OS_VMS = OS_WIN2000 << 1;
1.168 -
1.169 - /**
1.170 - *Operating system is one of the Windows variants but we don't know which
1.171 - *one it is
1.172 - */
1.173 - public static final int OS_WIN_OTHER = OS_VMS << 1;
1.174 -
1.175 - /** Operating system is unknown. */
1.176 - public static final int OS_OTHER = OS_WIN_OTHER << 1;
1.177 -
1.178 - /** Operating system is FreeBSD
1.179 - * @since 4.50
1.180 - */
1.181 - public static final int OS_FREEBSD = OS_OTHER << 1;
1.182 -
1.183 - /** Operating system is Windows Vista.
1.184 - * @since 7.17
1.185 - */
1.186 - public static final int OS_WINVISTA = OS_FREEBSD << 1;
1.187 -
1.188 - /** Operating system is one of the Unix variants but we don't know which
1.189 - * one it is.
1.190 - * @since 7.18
1.191 - */
1.192 - public static final int OS_UNIX_OTHER = OS_WINVISTA << 1;
1.193 -
1.194 - /** Operating system is OpenBSD.
1.195 - * @since 7.18
1.196 - */
1.197 - public static final int OS_OPENBSD = OS_UNIX_OTHER << 1;
1.198 -
1.199 - /** A mask for Windows platforms.
1.200 - * @deprecated Use {@link #isWindows()} instead.
1.201 - */
1.202 - @Deprecated
1.203 - public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WINVISTA | OS_WIN_OTHER;
1.204 -
1.205 - /** A mask for Unix platforms.
1.206 - * @deprecated Use {@link #isUnix()} instead.
1.207 - */
1.208 - @Deprecated
1.209 - public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 |
1.210 - OS_MAC | OS_FREEBSD | OS_OPENBSD | OS_UNIX_OTHER;
1.211 -
1.212 - /** A height of the windows's taskbar */
1.213 - public static final int TYPICAL_WINDOWS_TASKBAR_HEIGHT = 27;
1.214 -
1.215 - /** A height of the Mac OS X's menu */
1.216 - private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24;
1.217 -
1.218 - /** The operating system on which NetBeans runs*/
1.219 - private static int operatingSystem = -1;
1.220 - private static final String[] keywords = new String[] {
1.221 -
1.222 - //If adding to this, insert in alphabetical order!
1.223 - "abstract", "assert", "boolean", "break", "byte", "case", //NOI18N
1.224 - "catch", "char", "class", "const", "continue", "default", //NOI18N
1.225 - "do", "double", "else", "enum", "extends", "false", "final", //NOI18N
1.226 - "finally", "float", "for", "goto", "if", "implements", //NOI18N
1.227 - "import", "instanceof", "int", "interface", "long", //NOI18N
1.228 - "native", "new", "null", "package", "private", //NOI18N
1.229 - "protected", "public", "return", "short", "static", //NOI18N
1.230 - "strictfp", "super", "switch", "synchronized", "this", //NOI18N
1.231 - "throw", "throws", "transient", "true", "try", "void", //NOI18N
1.232 - "volatile", "while" //NOI18N
1.233 - };
1.234 - private static Timer clearIntrospector;
1.235 - private static ActionListener doClear;
1.236 - private static final int CTRL_WILDCARD_MASK = 32768;
1.237 - private static final int ALT_WILDCARD_MASK = CTRL_WILDCARD_MASK * 2;
1.238 -
1.239 - // Package retranslation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.240 - private static final String TRANS_LOCK = "TRANS_LOCK";
1.241 -
1.242 - /** last used classloader or if run in test mode the TRANS_LOCK */
1.243 - private static Object transLoader;
1.244 -
1.245 - /** regular expression to with all changes */
1.246 - private static RE transExp;
1.247 -
1.248 - //
1.249 - // Support for work with actions
1.250 - //
1.251 -
1.252 - /** the found actionsGlobalContext */
1.253 - private static Lookup global;
1.254 -
1.255 - private Utilities() {
1.256 - }
1.257 -
1.258 - /**
1.259 - * Useful queue for all parts of system that use <code>java.lang.ref.Reference</code>s
1.260 - * together with some <code>ReferenceQueue</code> and need to do some clean up
1.261 - * when the reference is enqueued. Usually, in order to be notified about that, one
1.262 - * needs to either create a dedicated thread that blocks on the queue and is
1.263 - * <code>Object.notify</code>-ed, which is the right approach but consumes
1.264 - * valuable system resources (threads) or one can periodically check the content
1.265 - * of the queue by <code>RequestProcessor.Task.schedule</code> which is
1.266 - * completely wrong, because it wakes up the system every (say) 15 seconds.
1.267 - * In order to provide useful support for this problem, this queue has been
1.268 - * provided.
1.269 - * <P>
1.270 - * If you have a reference that needs cleanup, make it implement <link>Runnable</link>
1.271 - * and register it with the queue:
1.272 - * <PRE>
1.273 - * class MyReference extends WeakReference<Thing> implements Runnable {
1.274 - * private final OtherInfo dataToCleanUp;
1.275 - * public MyReference(Thing ref, OtherInfo data) {
1.276 - * super(ref, Utilities.queue());
1.277 - * dataToCleanUp = data;
1.278 - * }
1.279 - * public void run() {
1.280 - * dataToCleanUp.releaseOrWhateverYouNeed();
1.281 - * }
1.282 - * }
1.283 - * </PRE>
1.284 - * When the <code>ref</code> object is garbage collected, your run method
1.285 - * will be invoked by calling
1.286 - * <code>((Runnable) reference).run()</code>
1.287 - * and you can perform whatever cleanup is necessary. Be sure not to block
1.288 - * in such cleanup for a long time as this prevents other waiting references
1.289 - * from cleaning themselves up.
1.290 - * <P>
1.291 - * Do not call any <code>ReferenceQueue</code> methods. They
1.292 - * will throw exceptions. You may only enqueue a reference.
1.293 - * <p>
1.294 - * Be sure to call this method anew for each reference.
1.295 - * Do not attempt to cache the return value.
1.296 - * @since 3.11
1.297 - */
1.298 - public static ReferenceQueue<Object> activeReferenceQueue() {
1.299 - return ActiveQueue.queue();
1.300 - }
1.301 -
1.302 - /** Get the operating system on which NetBeans is running.
1.303 - * @return one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
1.304 - */
1.305 - public static final int getOperatingSystem() {
1.306 - if (operatingSystem == -1) {
1.307 - String osName = System.getProperty("os.name");
1.308 -
1.309 - if ("Windows NT".equals(osName)) { // NOI18N
1.310 - operatingSystem = OS_WINNT;
1.311 - } else if ("Windows 95".equals(osName)) { // NOI18N
1.312 - operatingSystem = OS_WIN95;
1.313 - } else if ("Windows 98".equals(osName)) { // NOI18N
1.314 - operatingSystem = OS_WIN98;
1.315 - } else if ("Windows 2000".equals(osName)) { // NOI18N
1.316 - operatingSystem = OS_WIN2000;
1.317 - } else if ("Windows Vista".equals(osName)) { // NOI18N
1.318 - operatingSystem = OS_WINVISTA;
1.319 - } else if (osName.startsWith("Windows ")) { // NOI18N
1.320 - operatingSystem = OS_WIN_OTHER;
1.321 - } else if ("Solaris".equals(osName)) { // NOI18N
1.322 - operatingSystem = OS_SOLARIS;
1.323 - } else if (osName.startsWith("SunOS")) { // NOI18N
1.324 - operatingSystem = OS_SOLARIS;
1.325 - }
1.326 - // JDK 1.4 b2 defines os.name for me as "Redhat Linux" -jglick
1.327 - else if (osName.endsWith("Linux")) { // NOI18N
1.328 - operatingSystem = OS_LINUX;
1.329 - } else if ("HP-UX".equals(osName)) { // NOI18N
1.330 - operatingSystem = OS_HP;
1.331 - } else if ("AIX".equals(osName)) { // NOI18N
1.332 - operatingSystem = OS_AIX;
1.333 - } else if ("Irix".equals(osName)) { // NOI18N
1.334 - operatingSystem = OS_IRIX;
1.335 - } else if ("SunOS".equals(osName)) { // NOI18N
1.336 - operatingSystem = OS_SUNOS;
1.337 - } else if ("Digital UNIX".equals(osName)) { // NOI18N
1.338 - operatingSystem = OS_TRU64;
1.339 - } else if ("OS/2".equals(osName)) { // NOI18N
1.340 - operatingSystem = OS_OS2;
1.341 - } else if ("OpenVMS".equals(osName)) { // NOI18N
1.342 - operatingSystem = OS_VMS;
1.343 - } else if (osName.equals("Mac OS X")) { // NOI18N
1.344 - operatingSystem = OS_MAC;
1.345 - } else if (osName.startsWith("Darwin")) { // NOI18N
1.346 - operatingSystem = OS_MAC;
1.347 - } else if (osName.toLowerCase(Locale.US).startsWith("freebsd")) { // NOI18N
1.348 - operatingSystem = OS_FREEBSD;
1.349 - } else if ("OpenBSD".equals(osName)) { // NOI18N
1.350 - operatingSystem = OS_OPENBSD;
1.351 - } else if (File.pathSeparatorChar == ':') { // NOI18N
1.352 - operatingSystem = OS_UNIX_OTHER;
1.353 - } else {
1.354 - operatingSystem = OS_OTHER;
1.355 - }
1.356 - }
1.357 -
1.358 - return operatingSystem;
1.359 - }
1.360 -
1.361 - /** Test whether NetBeans is running on some variant of Windows.
1.362 - * @return <code>true</code> if Windows, <code>false</code> if some other manner of operating system
1.363 - */
1.364 - public static final boolean isWindows() {
1.365 - return (getOperatingSystem() & OS_WINDOWS_MASK) != 0;
1.366 - }
1.367 -
1.368 - /** Test whether NetBeans is running on MacOS.
1.369 - * @since 7.7
1.370 - * @return <code>true</code> if Mac, <code>false</code> if some other manner of operating system
1.371 - */
1.372 - public static final boolean isMac() {
1.373 - return (getOperatingSystem() & OS_MAC) != 0;
1.374 - }
1.375 -
1.376 - /** Test whether NetBeans is running on some variant of Unix.
1.377 - * Linux is included as well as the commercial vendors.
1.378 - * @return <code>true</code> some sort of Unix, <code>false</code> if some other manner of operating system
1.379 - */
1.380 - public static final boolean isUnix() {
1.381 - return (getOperatingSystem() & OS_UNIX_MASK) != 0;
1.382 - }
1.383 -
1.384 - // only for UtilitiesTest purposes
1.385 - final static void resetOperatingSystem() {
1.386 - operatingSystem = -1;
1.387 - }
1.388 -
1.389 - /** Test whether a given string is a valid Java identifier.
1.390 - * @param id string which should be checked
1.391 - * @return <code>true</code> if a valid identifier
1.392 - */
1.393 - public static final boolean isJavaIdentifier(String id) {
1.394 - if (id == null) {
1.395 - return false;
1.396 - }
1.397 -
1.398 - if (id.equals("")) {
1.399 - return false;
1.400 - }
1.401 -
1.402 - if (!(java.lang.Character.isJavaIdentifierStart(id.charAt(0)))) {
1.403 - return false;
1.404 - }
1.405 -
1.406 - for (int i = 1; i < id.length(); i++) {
1.407 - if (!(java.lang.Character.isJavaIdentifierPart(id.charAt(i)))) {
1.408 - return false;
1.409 - }
1.410 - }
1.411 -
1.412 - return Arrays.binarySearch(keywords, id) < 0;
1.413 - }
1.414 -
1.415 - /** Central method for obtaining <code>BeanInfo</code> for potential JavaBean classes.
1.416 - * @param clazz class of the bean to provide the <code>BeanInfo</code> for
1.417 - * @return the bean info
1.418 - * @throws java.beans.IntrospectionException for the usual reasons
1.419 - * @see java.beans.Introspector#getBeanInfo(Class)
1.420 - */
1.421 - public static java.beans.BeanInfo getBeanInfo(Class clazz)
1.422 - throws java.beans.IntrospectionException {
1.423 - java.beans.BeanInfo bi;
1.424 -
1.425 - try {
1.426 - bi = java.beans.Introspector.getBeanInfo(clazz);
1.427 - } catch (java.beans.IntrospectionException ie) {
1.428 - Exceptions.attachMessage(ie,
1.429 - "Encountered while introspecting " +
1.430 - clazz.getName()); // NOI18N
1.431 - throw ie;
1.432 - } catch (Error e) {
1.433 - // Could be a bug in Introspector triggered by NB code.
1.434 - Exceptions.attachMessage(e,
1.435 - "Encountered while introspecting " +
1.436 - clazz.getName()); // NOI18N
1.437 - throw e;
1.438 - }
1.439 -
1.440 - if (java.awt.Component.class.isAssignableFrom(clazz)) {
1.441 - java.beans.PropertyDescriptor[] pds = bi.getPropertyDescriptors();
1.442 -
1.443 - for (int i = 0; i < pds.length; i++) {
1.444 - if (pds[i].getName().equals("cursor")) { // NOI18N
1.445 -
1.446 - try {
1.447 - Method getter = Component.class.getDeclaredMethod("getCursor", new Class[0]); // NOI18N
1.448 - Method setter = Component.class.getDeclaredMethod("setCursor", new Class[] { Cursor.class }); // NOI18N
1.449 - pds[i] = new java.beans.PropertyDescriptor("cursor", getter, setter); // NOI18N
1.450 - } catch (NoSuchMethodException e) {
1.451 - e.printStackTrace();
1.452 - }
1.453 -
1.454 - break;
1.455 - }
1.456 - }
1.457 - }
1.458 -
1.459 - // clears about 1000 instances of Method
1.460 - if (bi != null) {
1.461 - if (clearIntrospector == null) {
1.462 - doClear = new ActionListener() {
1.463 - public void actionPerformed(ActionEvent ev) {
1.464 - java.beans.Introspector.flushCaches();
1.465 - }
1.466 - };
1.467 - clearIntrospector = new Timer(15000, doClear);
1.468 - clearIntrospector.setRepeats(false);
1.469 - }
1.470 -
1.471 - clearIntrospector.restart();
1.472 - }
1.473 -
1.474 - return bi;
1.475 - }
1.476 -
1.477 - /** Central method for obtaining <code>BeanInfo</code> for potential JavaBean classes, with a stop class.
1.478 - * @param clazz class of the bean to provide the <code>BeanInfo</code> for
1.479 - * @param stopClass the stop class
1.480 - * @return the bean info
1.481 - * @throws java.beans.IntrospectionException for the usual reasons
1.482 - * @see java.beans.Introspector#getBeanInfo(Class, Class)
1.483 - */
1.484 - public static java.beans.BeanInfo getBeanInfo(Class clazz, Class stopClass)
1.485 - throws java.beans.IntrospectionException {
1.486 - return java.beans.Introspector.getBeanInfo(clazz, stopClass);
1.487 - }
1.488 -
1.489 - /** Wrap multi-line strings (and get the individual lines).
1.490 - * @param original the original string to wrap
1.491 - * @param width the maximum width of lines
1.492 - * @param wrapWords if <code>true</code>, the lines are wrapped on word boundaries (if possible);
1.493 - * if <code>false</code>, character boundaries are used
1.494 - * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
1.495 - * @return the lines after wrapping
1.496 - * @deprecated use {@link #wrapStringToArray(String, int, BreakIterator, boolean)} since it is better for I18N
1.497 - */
1.498 - @Deprecated
1.499 - public static String[] wrapStringToArray(String original, int width, boolean wrapWords, boolean removeNewLines) {
1.500 - BreakIterator bi = (wrapWords ? BreakIterator.getWordInstance() : BreakIterator.getCharacterInstance());
1.501 -
1.502 - return wrapStringToArray(original, width, bi, removeNewLines);
1.503 - }
1.504 -
1.505 - /** Wrap multi-line strings (and get the individual lines).
1.506 - * @param original the original string to wrap
1.507 - * @param width the maximum width of lines
1.508 - * @param breakIterator breaks original to chars, words, sentences, depending on what instance you provide.
1.509 - * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
1.510 - * @return the lines after wrapping
1.511 - */
1.512 - public static String[] wrapStringToArray(
1.513 - String original, int width, BreakIterator breakIterator, boolean removeNewLines
1.514 - ) {
1.515 - if (original.length() == 0) {
1.516 - return new String[] { original };
1.517 - }
1.518 -
1.519 - String[] workingSet;
1.520 -
1.521 - // substitute original newlines with spaces,
1.522 - // remove newlines from head and tail
1.523 - if (removeNewLines) {
1.524 - original = trimString(original);
1.525 - original = original.replace('\n', ' ');
1.526 - workingSet = new String[] { original };
1.527 - } else {
1.528 - StringTokenizer tokens = new StringTokenizer(original, "\n"); // NOI18N
1.529 - int len = tokens.countTokens();
1.530 - workingSet = new String[len];
1.531 -
1.532 - for (int i = 0; i < len; i++) {
1.533 - workingSet[i] = tokens.nextToken();
1.534 - }
1.535 - }
1.536 -
1.537 - if (width < 1) {
1.538 - width = 1;
1.539 - }
1.540 -
1.541 - if (original.length() <= width) {
1.542 - return workingSet;
1.543 - }
1.544 -
1.545 -widthcheck: {
1.546 - boolean ok = true;
1.547 -
1.548 - for (int i = 0; i < workingSet.length; i++) {
1.549 - ok = ok && (workingSet[i].length() < width);
1.550 -
1.551 - if (!ok) {
1.552 - break widthcheck;
1.553 - }
1.554 - }
1.555 -
1.556 - return workingSet;
1.557 - }
1.558 -
1.559 - java.util.ArrayList<String> lines = new java.util.ArrayList<String>();
1.560 -
1.561 - int lineStart = 0; // the position of start of currently processed line in the original string
1.562 -
1.563 - for (int i = 0; i < workingSet.length; i++) {
1.564 - if (workingSet[i].length() < width) {
1.565 - lines.add(workingSet[i]);
1.566 - } else {
1.567 - breakIterator.setText(workingSet[i]);
1.568 -
1.569 - int nextStart = breakIterator.next();
1.570 - int prevStart = 0;
1.571 -
1.572 - do {
1.573 - while (((nextStart - lineStart) < width) && (nextStart != BreakIterator.DONE)) {
1.574 - prevStart = nextStart;
1.575 - nextStart = breakIterator.next();
1.576 - }
1.577 -
1.578 - if (nextStart == BreakIterator.DONE) {
1.579 - nextStart = prevStart = workingSet[i].length();
1.580 - }
1.581 -
1.582 - if (prevStart == 0) {
1.583 - prevStart = nextStart;
1.584 - }
1.585 -
1.586 - lines.add(workingSet[i].substring(lineStart, prevStart));
1.587 -
1.588 - lineStart = prevStart;
1.589 - prevStart = 0;
1.590 - } while (lineStart < workingSet[i].length());
1.591 -
1.592 - lineStart = 0;
1.593 - }
1.594 - }
1.595 -
1.596 - String[] s = new String[lines.size()];
1.597 -
1.598 - return lines.toArray(s);
1.599 - }
1.600 -
1.601 - /** trims String
1.602 - * @param s a String to trim
1.603 - * @return trimmed String
1.604 - */
1.605 - private static String trimString(String s) {
1.606 - int idx = 0;
1.607 - char c;
1.608 - final int slen = s.length();
1.609 -
1.610 - if (slen == 0) {
1.611 - return s;
1.612 - }
1.613 -
1.614 - do {
1.615 - c = s.charAt(idx++);
1.616 - } while (((c == '\n') || (c == '\r')) && (idx < slen));
1.617 -
1.618 - s = s.substring(--idx);
1.619 - idx = s.length() - 1;
1.620 -
1.621 - if (idx < 0) {
1.622 - return s;
1.623 - }
1.624 -
1.625 - do {
1.626 - c = s.charAt(idx--);
1.627 - } while (((c == '\n') || (c == '\r')) && (idx >= 0));
1.628 -
1.629 - return s.substring(0, idx + 2);
1.630 - }
1.631 -
1.632 - /** Wrap multi-line strings.
1.633 - * @param original the original string to wrap
1.634 - * @param width the maximum width of lines
1.635 - * @param breakIterator algorithm for breaking lines
1.636 - * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
1.637 - * @return the whole string with embedded newlines
1.638 - */
1.639 - public static String wrapString(String original, int width, BreakIterator breakIterator, boolean removeNewLines) {
1.640 - String[] sarray = wrapStringToArray(original, width, breakIterator, removeNewLines);
1.641 - StringBuffer retBuf = new StringBuffer();
1.642 -
1.643 - for (int i = 0; i < sarray.length; i++) {
1.644 - retBuf.append(sarray[i]);
1.645 - retBuf.append('\n');
1.646 - }
1.647 -
1.648 - return retBuf.toString();
1.649 - }
1.650 -
1.651 - /** Wrap multi-line strings.
1.652 - * @param original the original string to wrap
1.653 - * @param width the maximum width of lines
1.654 - * @param wrapWords if <code>true</code>, the lines are wrapped on word boundaries (if possible);
1.655 - * if <code>false</code>, character boundaries are used
1.656 - * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
1.657 - * @return the whole string with embedded newlines
1.658 - * @deprecated Use {@link #wrapString (String, int, BreakIterator, boolean)} as it is friendlier to I18N.
1.659 - */
1.660 - @Deprecated
1.661 - public static String wrapString(String original, int width, boolean wrapWords, boolean removeNewLines) {
1.662 - // substitute original newlines with spaces,
1.663 - // remove newlines from head and tail
1.664 - if (removeNewLines) {
1.665 - while (original.startsWith("\n")) // NOI18N
1.666 -
1.667 - original = original.substring(1);
1.668 -
1.669 - while (original.endsWith("\n")) // NOI18N
1.670 -
1.671 - original = original.substring(0, original.length() - 1);
1.672 -
1.673 - original = original.replace('\n', ' ');
1.674 - }
1.675 -
1.676 - if (width < 1) {
1.677 - width = 1;
1.678 - }
1.679 -
1.680 - if (original.length() <= width) {
1.681 - return original;
1.682 - }
1.683 -
1.684 - java.util.Vector<String> lines = new java.util.Vector<String>();
1.685 - int lineStart = 0; // the position of start of currently processed line in the original string
1.686 - int lastSpacePos = -1;
1.687 -
1.688 - for (int i = 0; i < original.length(); i++) {
1.689 - if (lineStart >= (original.length() - 1)) {
1.690 - break;
1.691 - }
1.692 -
1.693 - // newline in the original string
1.694 - if (original.charAt(i) == '\n') {
1.695 - lines.addElement(original.substring(lineStart, i));
1.696 - lineStart = i + 1;
1.697 - lastSpacePos = -1;
1.698 -
1.699 - continue;
1.700 - }
1.701 -
1.702 - // remember last space position
1.703 - if (Character.isSpaceChar(original.charAt(i))) {
1.704 - lastSpacePos = i;
1.705 - }
1.706 -
1.707 - // last position in the original string
1.708 - if (i == (original.length() - 1)) {
1.709 - lines.addElement(original.substring(lineStart));
1.710 -
1.711 - break;
1.712 - }
1.713 -
1.714 - // reached width
1.715 - if ((i - lineStart) == width) {
1.716 - if (wrapWords && (lastSpacePos != -1)) {
1.717 - lines.addElement(original.substring(lineStart, lastSpacePos));
1.718 - lineStart = lastSpacePos + 1; // the space is consumed for the newline
1.719 - lastSpacePos = -1;
1.720 - } else {
1.721 - lines.addElement(original.substring(lineStart, i));
1.722 - lineStart = i;
1.723 - lastSpacePos = -1;
1.724 - }
1.725 - }
1.726 - }
1.727 -
1.728 - StringBuffer retBuf = new StringBuffer();
1.729 -
1.730 - for (java.util.Enumeration e = lines.elements(); e.hasMoreElements();) {
1.731 - retBuf.append((String) e.nextElement());
1.732 - retBuf.append('\n');
1.733 - }
1.734 -
1.735 - return retBuf.toString();
1.736 - }
1.737 -
1.738 - /** Search-and-replace fixed string matches within a string.
1.739 - * @param original the original string
1.740 - * @param replaceFrom the substring to be find
1.741 - * @param replaceTo the substring to replace it with
1.742 - * @return a new string with all occurrences replaced
1.743 - * @deprecated Use {@link String#replace(CharSequence,CharSequence)} instead
1.744 - */
1.745 - @Deprecated
1.746 - public static String replaceString(String original, String replaceFrom, String replaceTo) {
1.747 - int index = 0;
1.748 -
1.749 - if ("".equals(replaceFrom)) {
1.750 - return original; // NOI18N
1.751 - }
1.752 -
1.753 - StringBuffer buf = new StringBuffer();
1.754 -
1.755 - while (true) {
1.756 - int pos = original.indexOf(replaceFrom, index);
1.757 -
1.758 - if (pos == -1) {
1.759 - buf.append(original.substring(index));
1.760 -
1.761 - return buf.toString();
1.762 - }
1.763 -
1.764 - buf.append(original.substring(index, pos));
1.765 - buf.append(replaceTo);
1.766 - index = pos + replaceFrom.length();
1.767 -
1.768 - if (index == original.length()) {
1.769 - return buf.toString();
1.770 - }
1.771 - }
1.772 - }
1.773 -
1.774 - /** Turn full name of an inner class into its pure form.
1.775 - * @param fullName e.g. <code>some.pkg.SomeClass$Inner</code>
1.776 - * @return e.g. <code>Inner</code>
1.777 - */
1.778 - public static final String pureClassName(final String fullName) {
1.779 - final int index = fullName.indexOf('$');
1.780 -
1.781 - if ((index >= 0) && (index < fullName.length())) {
1.782 - return fullName.substring(index + 1, fullName.length());
1.783 - }
1.784 -
1.785 - return fullName;
1.786 - }
1.787 -
1.788 - /** Test whether the operating system supports icons on frames (windows).
1.789 - * @return <code>true</code> if it does <em>not</em>
1.790 - * @deprecated Obsolete, useless method, no replacement.
1.791 - */
1.792 - @Deprecated public static final boolean isLargeFrameIcons() {
1.793 - return (getOperatingSystem() == OS_SOLARIS) || (getOperatingSystem() == OS_HP);
1.794 - }
1.795 -
1.796 - /** Compute hash code of array.
1.797 - * Asks all elements for their own code and composes the
1.798 - * values.
1.799 - * @param arr array of objects, can contain <code>null</code>s
1.800 - * @return the hash code
1.801 - * @see Object#hashCode
1.802 - */
1.803 - public static int arrayHashCode(Object[] arr) {
1.804 - int c = 0;
1.805 - int len = arr.length;
1.806 -
1.807 - for (int i = 0; i < len; i++) {
1.808 - Object o = arr[i];
1.809 - int v = (o == null) ? 1 : o.hashCode();
1.810 - c += (v ^ i);
1.811 - }
1.812 -
1.813 - return c;
1.814 - }
1.815 -
1.816 - /** Safe equality check.
1.817 - * The supplied objects are equal if: <UL>
1.818 - * <LI> both are <code>null</code>
1.819 - * <LI> both are arrays with same length and equal items (if the items are arrays,
1.820 - * they are <em>not</em> checked the same way again)
1.821 - * <LI> the two objects are {@link Object#equals}
1.822 - * </UL>
1.823 - * This method is <code>null</code>-safe, so if one of the parameters is true and the second not,
1.824 - * it returns <code>false</code>.
1.825 - * @param o1 the first object to compare
1.826 - * @param o2 the second object to compare
1.827 - * @return <code>true</code> if the objects are equal
1.828 - */
1.829 - public static boolean compareObjects(Object o1, Object o2) {
1.830 - return compareObjectsImpl(o1, o2, 1);
1.831 - }
1.832 -
1.833 - /** Safe equality check with array recursion.
1.834 - * @param o1 the first object to compare
1.835 - * @param o2 the second object to compare
1.836 - * @param checkArraysDepth the depth to which arrays should be compared for equality (negative for infinite depth, zero for no comparison of elements, one for shallow, etc.)
1.837 - * @return <code>true</code> if the objects are equal
1.838 - * @see #compareObjects(Object, Object)
1.839 - */
1.840 - public static boolean compareObjectsImpl(Object o1, Object o2, int checkArraysDepth) {
1.841 - // handle null values
1.842 - if (o1 == null) {
1.843 - return (o2 == null);
1.844 - } else if (o2 == null) {
1.845 - return false;
1.846 - }
1.847 -
1.848 - // handle arrays
1.849 - if (checkArraysDepth > 0) {
1.850 - if ((o1 instanceof Object[]) && (o2 instanceof Object[])) {
1.851 - // Note: also handles multidimensional arrays of primitive types correctly.
1.852 - // I.e. new int[0][] instanceof Object[]
1.853 - Object[] o1a = (Object[]) o1;
1.854 - Object[] o2a = (Object[]) o2;
1.855 - int l1 = o1a.length;
1.856 - int l2 = o2a.length;
1.857 -
1.858 - if (l1 != l2) {
1.859 - return false;
1.860 - }
1.861 -
1.862 - for (int i = 0; i < l1; i++) {
1.863 - if (!compareObjectsImpl(o1a[i], o2a[i], checkArraysDepth - 1)) {
1.864 - return false;
1.865 - }
1.866 - }
1.867 -
1.868 - return true;
1.869 - } else if ((o1 instanceof byte[]) && (o2 instanceof byte[])) {
1.870 - byte[] o1a = (byte[]) o1;
1.871 - byte[] o2a = (byte[]) o2;
1.872 - int l1 = o1a.length;
1.873 - int l2 = o2a.length;
1.874 -
1.875 - if (l1 != l2) {
1.876 - return false;
1.877 - }
1.878 -
1.879 - for (int i = 0; i < l1; i++)
1.880 - if (o1a[i] != o2a[i]) {
1.881 - return false;
1.882 - }
1.883 -
1.884 - return true;
1.885 - } else if ((o1 instanceof short[]) && (o2 instanceof short[])) {
1.886 - short[] o1a = (short[]) o1;
1.887 - short[] o2a = (short[]) o2;
1.888 - int l1 = o1a.length;
1.889 - int l2 = o2a.length;
1.890 -
1.891 - if (l1 != l2) {
1.892 - return false;
1.893 - }
1.894 -
1.895 - for (int i = 0; i < l1; i++)
1.896 - if (o1a[i] != o2a[i]) {
1.897 - return false;
1.898 - }
1.899 -
1.900 - return true;
1.901 - } else if ((o1 instanceof int[]) && (o2 instanceof int[])) {
1.902 - int[] o1a = (int[]) o1;
1.903 - int[] o2a = (int[]) o2;
1.904 - int l1 = o1a.length;
1.905 - int l2 = o2a.length;
1.906 -
1.907 - if (l1 != l2) {
1.908 - return false;
1.909 - }
1.910 -
1.911 - for (int i = 0; i < l1; i++)
1.912 - if (o1a[i] != o2a[i]) {
1.913 - return false;
1.914 - }
1.915 -
1.916 - return true;
1.917 - } else if ((o1 instanceof long[]) && (o2 instanceof long[])) {
1.918 - long[] o1a = (long[]) o1;
1.919 - long[] o2a = (long[]) o2;
1.920 - int l1 = o1a.length;
1.921 - int l2 = o2a.length;
1.922 -
1.923 - if (l1 != l2) {
1.924 - return false;
1.925 - }
1.926 -
1.927 - for (int i = 0; i < l1; i++)
1.928 - if (o1a[i] != o2a[i]) {
1.929 - return false;
1.930 - }
1.931 -
1.932 - return true;
1.933 - } else if ((o1 instanceof float[]) && (o2 instanceof float[])) {
1.934 - float[] o1a = (float[]) o1;
1.935 - float[] o2a = (float[]) o2;
1.936 - int l1 = o1a.length;
1.937 - int l2 = o2a.length;
1.938 -
1.939 - if (l1 != l2) {
1.940 - return false;
1.941 - }
1.942 -
1.943 - for (int i = 0; i < l1; i++)
1.944 - if (o1a[i] != o2a[i]) {
1.945 - return false;
1.946 - }
1.947 -
1.948 - return true;
1.949 - } else if ((o1 instanceof double[]) && (o2 instanceof double[])) {
1.950 - double[] o1a = (double[]) o1;
1.951 - double[] o2a = (double[]) o2;
1.952 - int l1 = o1a.length;
1.953 - int l2 = o2a.length;
1.954 -
1.955 - if (l1 != l2) {
1.956 - return false;
1.957 - }
1.958 -
1.959 - for (int i = 0; i < l1; i++)
1.960 - if (o1a[i] != o2a[i]) {
1.961 - return false;
1.962 - }
1.963 -
1.964 - return true;
1.965 - } else if ((o1 instanceof char[]) && (o2 instanceof char[])) {
1.966 - char[] o1a = (char[]) o1;
1.967 - char[] o2a = (char[]) o2;
1.968 - int l1 = o1a.length;
1.969 - int l2 = o2a.length;
1.970 -
1.971 - if (l1 != l2) {
1.972 - return false;
1.973 - }
1.974 -
1.975 - for (int i = 0; i < l1; i++)
1.976 - if (o1a[i] != o2a[i]) {
1.977 - return false;
1.978 - }
1.979 -
1.980 - return true;
1.981 - } else if ((o1 instanceof boolean[]) && (o2 instanceof boolean[])) {
1.982 - boolean[] o1a = (boolean[]) o1;
1.983 - boolean[] o2a = (boolean[]) o2;
1.984 - int l1 = o1a.length;
1.985 - int l2 = o2a.length;
1.986 -
1.987 - if (l1 != l2) {
1.988 - return false;
1.989 - }
1.990 -
1.991 - for (int i = 0; i < l1; i++)
1.992 - if (o1a[i] != o2a[i]) {
1.993 - return false;
1.994 - }
1.995 -
1.996 - return true;
1.997 - }
1.998 -
1.999 - // else not array type
1.1000 - }
1.1001 -
1.1002 - // handle common objects--non-arrays, or arrays when depth == 0
1.1003 - return o1.equals(o2);
1.1004 - }
1.1005 -
1.1006 - /** Assemble a human-presentable class name for a specified class.
1.1007 - * Arrays are represented as e.g. <code>java.lang.String[]</code>.
1.1008 - * @param clazz the class to name
1.1009 - * @return the human-presentable name
1.1010 - */
1.1011 - public static String getClassName(Class clazz) {
1.1012 - // if it is an array, get short name of element type and append []
1.1013 - if (clazz.isArray()) {
1.1014 - return getClassName(clazz.getComponentType()) + "[]"; // NOI18N
1.1015 - } else {
1.1016 - return clazz.getName();
1.1017 - }
1.1018 - }
1.1019 -
1.1020 - /** Assemble a human-presentable class name for a specified class (omitting the package).
1.1021 - * Arrays are represented as e.g. <code>String[]</code>.
1.1022 - * @param clazz the class to name
1.1023 - * @return the human-presentable name
1.1024 - */
1.1025 - public static String getShortClassName(Class clazz) {
1.1026 - // if it is an array, get short name of element type and append []
1.1027 - if (clazz.isArray()) {
1.1028 - return getShortClassName(clazz.getComponentType()) + "[]"; // NOI18N
1.1029 - }
1.1030 -
1.1031 - String name = clazz.getName().replace('$', '.');
1.1032 -
1.1033 - return name.substring(name.lastIndexOf(".") + 1, name.length()); // NOI18N
1.1034 - }
1.1035 -
1.1036 - /**
1.1037 - * Convert an array of objects to an array of primitive types.
1.1038 - * E.g. an <code>Integer[]</code> would be changed to an <code>int[]</code>.
1.1039 - * @param array the wrapper array
1.1040 - * @return a primitive array
1.1041 - * @throws IllegalArgumentException if the array element type is not a primitive wrapper
1.1042 - */
1.1043 - public static Object toPrimitiveArray(Object[] array) {
1.1044 - if (array instanceof Integer[]) {
1.1045 - int[] r = new int[array.length];
1.1046 - int i;
1.1047 - int k = array.length;
1.1048 -
1.1049 - for (i = 0; i < k; i++)
1.1050 - r[i] = (((Integer) array[i]) == null) ? 0 : ((Integer) array[i]).intValue();
1.1051 -
1.1052 - return r;
1.1053 - }
1.1054 -
1.1055 - if (array instanceof Boolean[]) {
1.1056 - boolean[] r = new boolean[array.length];
1.1057 - int i;
1.1058 - int k = array.length;
1.1059 -
1.1060 - for (i = 0; i < k; i++)
1.1061 - r[i] = (((Boolean) array[i]) == null) ? false : ((Boolean) array[i]).booleanValue();
1.1062 -
1.1063 - return r;
1.1064 - }
1.1065 -
1.1066 - if (array instanceof Byte[]) {
1.1067 - byte[] r = new byte[array.length];
1.1068 - int i;
1.1069 - int k = array.length;
1.1070 -
1.1071 - for (i = 0; i < k; i++)
1.1072 - r[i] = (((Byte) array[i]) == null) ? 0 : ((Byte) array[i]).byteValue();
1.1073 -
1.1074 - return r;
1.1075 - }
1.1076 -
1.1077 - if (array instanceof Character[]) {
1.1078 - char[] r = new char[array.length];
1.1079 - int i;
1.1080 - int k = array.length;
1.1081 -
1.1082 - for (i = 0; i < k; i++)
1.1083 - r[i] = (((Character) array[i]) == null) ? 0 : ((Character) array[i]).charValue();
1.1084 -
1.1085 - return r;
1.1086 - }
1.1087 -
1.1088 - if (array instanceof Double[]) {
1.1089 - double[] r = new double[array.length];
1.1090 - int i;
1.1091 - int k = array.length;
1.1092 -
1.1093 - for (i = 0; i < k; i++)
1.1094 - r[i] = (((Double) array[i]) == null) ? 0 : ((Double) array[i]).doubleValue();
1.1095 -
1.1096 - return r;
1.1097 - }
1.1098 -
1.1099 - if (array instanceof Float[]) {
1.1100 - float[] r = new float[array.length];
1.1101 - int i;
1.1102 - int k = array.length;
1.1103 -
1.1104 - for (i = 0; i < k; i++)
1.1105 - r[i] = (((Float) array[i]) == null) ? 0 : ((Float) array[i]).floatValue();
1.1106 -
1.1107 - return r;
1.1108 - }
1.1109 -
1.1110 - if (array instanceof Long[]) {
1.1111 - long[] r = new long[array.length];
1.1112 - int i;
1.1113 - int k = array.length;
1.1114 -
1.1115 - for (i = 0; i < k; i++)
1.1116 - r[i] = (((Long) array[i]) == null) ? 0 : ((Long) array[i]).longValue();
1.1117 -
1.1118 - return r;
1.1119 - }
1.1120 -
1.1121 - if (array instanceof Short[]) {
1.1122 - short[] r = new short[array.length];
1.1123 - int i;
1.1124 - int k = array.length;
1.1125 -
1.1126 - for (i = 0; i < k; i++)
1.1127 - r[i] = (((Short) array[i]) == null) ? 0 : ((Short) array[i]).shortValue();
1.1128 -
1.1129 - return r;
1.1130 - }
1.1131 -
1.1132 - throw new IllegalArgumentException();
1.1133 - }
1.1134 -
1.1135 - /**
1.1136 - * Convert an array of primitive types to an array of objects.
1.1137 - * E.g. an <code>int[]</code> would be turned into an <code>Integer[]</code>.
1.1138 - * @param array the primitive array
1.1139 - * @return a wrapper array
1.1140 - * @throws IllegalArgumentException if the array element type is not primitive
1.1141 - */
1.1142 - public static Object[] toObjectArray(Object array) {
1.1143 - if (array instanceof Object[]) {
1.1144 - return (Object[]) array;
1.1145 - }
1.1146 -
1.1147 - if (array instanceof int[]) {
1.1148 - int i;
1.1149 - int k = ((int[]) array).length;
1.1150 - Integer[] r = new Integer[k];
1.1151 -
1.1152 - for (i = 0; i < k; i++)
1.1153 - r[i] = new Integer(((int[]) array)[i]);
1.1154 -
1.1155 - return r;
1.1156 - }
1.1157 -
1.1158 - if (array instanceof boolean[]) {
1.1159 - int i;
1.1160 - int k = ((boolean[]) array).length;
1.1161 - Boolean[] r = new Boolean[k];
1.1162 -
1.1163 - for (i = 0; i < k; i++)
1.1164 - r[i] = ((boolean[]) array)[i] ? Boolean.TRUE : Boolean.FALSE;
1.1165 -
1.1166 - return r;
1.1167 - }
1.1168 -
1.1169 - if (array instanceof byte[]) {
1.1170 - int i;
1.1171 - int k = ((byte[]) array).length;
1.1172 - Byte[] r = new Byte[k];
1.1173 -
1.1174 - for (i = 0; i < k; i++)
1.1175 - r[i] = new Byte(((byte[]) array)[i]);
1.1176 -
1.1177 - return r;
1.1178 - }
1.1179 -
1.1180 - if (array instanceof char[]) {
1.1181 - int i;
1.1182 - int k = ((char[]) array).length;
1.1183 - Character[] r = new Character[k];
1.1184 -
1.1185 - for (i = 0; i < k; i++)
1.1186 - r[i] = new Character(((char[]) array)[i]);
1.1187 -
1.1188 - return r;
1.1189 - }
1.1190 -
1.1191 - if (array instanceof double[]) {
1.1192 - int i;
1.1193 - int k = ((double[]) array).length;
1.1194 - Double[] r = new Double[k];
1.1195 -
1.1196 - for (i = 0; i < k; i++)
1.1197 - r[i] = new Double(((double[]) array)[i]);
1.1198 -
1.1199 - return r;
1.1200 - }
1.1201 -
1.1202 - if (array instanceof float[]) {
1.1203 - int i;
1.1204 - int k = ((float[]) array).length;
1.1205 - Float[] r = new Float[k];
1.1206 -
1.1207 - for (i = 0; i < k; i++)
1.1208 - r[i] = new Float(((float[]) array)[i]);
1.1209 -
1.1210 - return r;
1.1211 - }
1.1212 -
1.1213 - if (array instanceof long[]) {
1.1214 - int i;
1.1215 - int k = ((long[]) array).length;
1.1216 - Long[] r = new Long[k];
1.1217 -
1.1218 - for (i = 0; i < k; i++)
1.1219 - r[i] = new Long(((long[]) array)[i]);
1.1220 -
1.1221 - return r;
1.1222 - }
1.1223 -
1.1224 - if (array instanceof short[]) {
1.1225 - int i;
1.1226 - int k = ((short[]) array).length;
1.1227 - Short[] r = new Short[k];
1.1228 -
1.1229 - for (i = 0; i < k; i++)
1.1230 - r[i] = new Short(((short[]) array)[i]);
1.1231 -
1.1232 - return r;
1.1233 - }
1.1234 -
1.1235 - throw new IllegalArgumentException();
1.1236 - }
1.1237 -
1.1238 - /**
1.1239 - * Get the object type for given primitive type.
1.1240 - *
1.1241 - * @param c primitive type (e.g. <code>int</code>)
1.1242 - * @return object type (e.g. <code>Integer</code>)
1.1243 - */
1.1244 - public static Class getObjectType(Class c) {
1.1245 - if (!c.isPrimitive()) {
1.1246 - return c;
1.1247 - }
1.1248 -
1.1249 - if (c == Integer.TYPE) {
1.1250 - return Integer.class;
1.1251 - }
1.1252 -
1.1253 - if (c == Boolean.TYPE) {
1.1254 - return Boolean.class;
1.1255 - }
1.1256 -
1.1257 - if (c == Byte.TYPE) {
1.1258 - return Byte.class;
1.1259 - }
1.1260 -
1.1261 - if (c == Character.TYPE) {
1.1262 - return Character.class;
1.1263 - }
1.1264 -
1.1265 - if (c == Double.TYPE) {
1.1266 - return Double.class;
1.1267 - }
1.1268 -
1.1269 - if (c == Float.TYPE) {
1.1270 - return Float.class;
1.1271 - }
1.1272 -
1.1273 - if (c == Long.TYPE) {
1.1274 - return Long.class;
1.1275 - }
1.1276 -
1.1277 - if (c == Short.TYPE) {
1.1278 - return Short.class;
1.1279 - }
1.1280 -
1.1281 - throw new IllegalArgumentException();
1.1282 - }
1.1283 -
1.1284 - /**
1.1285 - * Get the primitive type for given object type.
1.1286 - *
1.1287 - * @param c object type (e.g. <code>Integer</code>)
1.1288 - * @return primitive type (e.g. <code>int</code>)
1.1289 - */
1.1290 - public static Class getPrimitiveType(Class c) {
1.1291 - if (!c.isPrimitive()) {
1.1292 - return c;
1.1293 - }
1.1294 -
1.1295 - if (c == Integer.class) {
1.1296 - return Integer.TYPE;
1.1297 - }
1.1298 -
1.1299 - if (c == Boolean.class) {
1.1300 - return Boolean.TYPE;
1.1301 - }
1.1302 -
1.1303 - if (c == Byte.class) {
1.1304 - return Byte.TYPE;
1.1305 - }
1.1306 -
1.1307 - if (c == Character.class) {
1.1308 - return Character.TYPE;
1.1309 - }
1.1310 -
1.1311 - if (c == Double.class) {
1.1312 - return Double.TYPE;
1.1313 - }
1.1314 -
1.1315 - if (c == Float.class) {
1.1316 - return Float.TYPE;
1.1317 - }
1.1318 -
1.1319 - if (c == Long.class) {
1.1320 - return Long.TYPE;
1.1321 - }
1.1322 -
1.1323 - if (c == Short.class) {
1.1324 - return Short.TYPE;
1.1325 - }
1.1326 -
1.1327 - throw new IllegalArgumentException();
1.1328 - }
1.1329 -
1.1330 - /** Find a focus-traverable component.
1.1331 - * @param c the component to look in
1.1332 - * @return the same component if traversable, else a child component if present, else <code>null</code>
1.1333 - * @see Component#isFocusTraversable
1.1334 - */
1.1335 - public static Component getFocusTraversableComponent(Component c) {
1.1336 - if (c.isFocusable()) {
1.1337 - return c;
1.1338 - }
1.1339 -
1.1340 - if (!(c instanceof Container)) {
1.1341 - return null;
1.1342 - }
1.1343 -
1.1344 - int i;
1.1345 - int k = ((Container) c).getComponentCount();
1.1346 -
1.1347 - for (i = 0; i < k; i++) {
1.1348 - Component v = ((Container) c).getComponent(i);
1.1349 -
1.1350 - if (v != null) {
1.1351 - return v;
1.1352 - }
1.1353 - }
1.1354 -
1.1355 - return null;
1.1356 - }
1.1357 -
1.1358 - /** Parses parameters from a given string in shell-like manner.
1.1359 - * Users of the Bourne shell (e.g. on Unix) will already be familiar with the behavior.
1.1360 - * For example, when using <code>org.openide.execution.NbProcessDescriptor</code> (Execution API)
1.1361 - * you should be able to:
1.1362 - * <ul>
1.1363 - * <li>Include command names with embedded spaces, such as <code>c:\Program Files\jdk\bin\javac</code>.
1.1364 - * <li>Include extra command arguments, such as <code>-Dname=value</code>.
1.1365 - * <li>Do anything else which might require unusual characters or processing. For example:
1.1366 - * <p><code><pre>
1.1367 - * "c:\program files\jdk\bin\java" -Dmessage="Hello /\\/\\ there!" -Xmx128m
1.1368 - * </pre></code>
1.1369 - * <p>This example would create the following executable name and arguments:
1.1370 - * <ol>
1.1371 - * <li> <code>c:\program files\jdk\bin\java</code>
1.1372 - * <li> <code>-Dmessage=Hello /\/\ there!</code>
1.1373 - * <li> <code>-Xmx128m</code>
1.1374 - * </ol>
1.1375 - * Note that the command string does not escape its backslashes--under the assumption
1.1376 - * that Windows users will not think to do this, meaningless escapes are just left
1.1377 - * as backslashes plus following character.
1.1378 - * </ul>
1.1379 - * <em>Caveat</em>: even after parsing, Windows programs (such as the Java launcher)
1.1380 - * may not fully honor certain
1.1381 - * characters, such as quotes, in command names or arguments. This is because programs
1.1382 - * under Windows frequently perform their own parsing and unescaping (since the shell
1.1383 - * cannot be relied on to do this). On Unix, this problem should not occur.
1.1384 - * @param s a string to parse
1.1385 - * @return an array of parameters
1.1386 - */
1.1387 - public static String[] parseParameters(String s) {
1.1388 - int NULL = 0x0; // STICK + whitespace or NULL + non_"
1.1389 - int INPARAM = 0x1; // NULL + " or STICK + " or INPARAMPENDING + "\ // NOI18N
1.1390 - int INPARAMPENDING = 0x2; // INPARAM + \
1.1391 - int STICK = 0x4; // INPARAM + " or STICK + non_" // NOI18N
1.1392 - int STICKPENDING = 0x8; // STICK + \
1.1393 - Vector<String> params = new Vector<String>(5, 5);
1.1394 - char c;
1.1395 -
1.1396 - int state = NULL;
1.1397 - StringBuffer buff = new StringBuffer(20);
1.1398 - int slength = s.length();
1.1399 -
1.1400 - for (int i = 0; i < slength; i++) {
1.1401 - c = s.charAt(i);
1.1402 -
1.1403 - if (Character.isWhitespace(c)) {
1.1404 - if (state == NULL) {
1.1405 - if (buff.length() > 0) {
1.1406 - params.addElement(buff.toString());
1.1407 - buff.setLength(0);
1.1408 - }
1.1409 - } else if (state == STICK) {
1.1410 - params.addElement(buff.toString());
1.1411 - buff.setLength(0);
1.1412 - state = NULL;
1.1413 - } else if (state == STICKPENDING) {
1.1414 - buff.append('\\');
1.1415 - params.addElement(buff.toString());
1.1416 - buff.setLength(0);
1.1417 - state = NULL;
1.1418 - } else if (state == INPARAMPENDING) {
1.1419 - state = INPARAM;
1.1420 - buff.append('\\');
1.1421 - buff.append(c);
1.1422 - } else { // INPARAM
1.1423 - buff.append(c);
1.1424 - }
1.1425 -
1.1426 - continue;
1.1427 - }
1.1428 -
1.1429 - if (c == '\\') {
1.1430 - if (state == NULL) {
1.1431 - ++i;
1.1432 -
1.1433 - if (i < slength) {
1.1434 - char cc = s.charAt(i);
1.1435 -
1.1436 - if ((cc == '"') || (cc == '\\')) {
1.1437 - buff.append(cc);
1.1438 - } else if (Character.isWhitespace(cc)) {
1.1439 - buff.append(c);
1.1440 - --i;
1.1441 - } else {
1.1442 - buff.append(c);
1.1443 - buff.append(cc);
1.1444 - }
1.1445 - } else {
1.1446 - buff.append('\\');
1.1447 -
1.1448 - break;
1.1449 - }
1.1450 -
1.1451 - continue;
1.1452 - } else if (state == INPARAM) {
1.1453 - state = INPARAMPENDING;
1.1454 - } else if (state == INPARAMPENDING) {
1.1455 - buff.append('\\');
1.1456 - state = INPARAM;
1.1457 - } else if (state == STICK) {
1.1458 - state = STICKPENDING;
1.1459 - } else if (state == STICKPENDING) {
1.1460 - buff.append('\\');
1.1461 - state = STICK;
1.1462 - }
1.1463 -
1.1464 - continue;
1.1465 - }
1.1466 -
1.1467 - if (c == '"') {
1.1468 - if (state == NULL) {
1.1469 - state = INPARAM;
1.1470 - } else if (state == INPARAM) {
1.1471 - state = STICK;
1.1472 - } else if (state == STICK) {
1.1473 - state = INPARAM;
1.1474 - } else if (state == STICKPENDING) {
1.1475 - buff.append('"');
1.1476 - state = STICK;
1.1477 - } else { // INPARAMPENDING
1.1478 - buff.append('"');
1.1479 - state = INPARAM;
1.1480 - }
1.1481 -
1.1482 - continue;
1.1483 - }
1.1484 -
1.1485 - if (state == INPARAMPENDING) {
1.1486 - buff.append('\\');
1.1487 - state = INPARAM;
1.1488 - } else if (state == STICKPENDING) {
1.1489 - buff.append('\\');
1.1490 - state = STICK;
1.1491 - }
1.1492 -
1.1493 - buff.append(c);
1.1494 - }
1.1495 -
1.1496 - // collect
1.1497 - if (state == INPARAM) {
1.1498 - params.addElement(buff.toString());
1.1499 - } else if ((state & (INPARAMPENDING | STICKPENDING)) != 0) {
1.1500 - buff.append('\\');
1.1501 - params.addElement(buff.toString());
1.1502 - } else { // NULL or STICK
1.1503 -
1.1504 - if (buff.length() != 0) {
1.1505 - params.addElement(buff.toString());
1.1506 - }
1.1507 - }
1.1508 -
1.1509 - String[] ret = new String[params.size()];
1.1510 - params.copyInto(ret);
1.1511 -
1.1512 - return ret;
1.1513 - }
1.1514 -
1.1515 - /** Complementary method to parseParameters
1.1516 - * @see #parseParameters
1.1517 - */
1.1518 - public static String escapeParameters(String[] params) {
1.1519 - StringBuffer sb = new StringBuffer();
1.1520 -
1.1521 - for (int i = 0; i < params.length; i++) {
1.1522 - escapeString(params[i], sb);
1.1523 - sb.append(' ');
1.1524 - }
1.1525 -
1.1526 - final int len = sb.length();
1.1527 -
1.1528 - if (len > 0) {
1.1529 - sb.setLength(len - 1);
1.1530 - }
1.1531 -
1.1532 - return sb.toString().trim();
1.1533 - }
1.1534 -
1.1535 - /** Escapes one string
1.1536 - * @see #escapeParameters
1.1537 - */
1.1538 - private static void escapeString(String s, StringBuffer sb) {
1.1539 - if (s.length() == 0) {
1.1540 - sb.append("\"\"");
1.1541 -
1.1542 - return;
1.1543 - }
1.1544 -
1.1545 - boolean hasSpace = false;
1.1546 - final int sz = sb.length();
1.1547 - final int slen = s.length();
1.1548 - char c;
1.1549 -
1.1550 - for (int i = 0; i < slen; i++) {
1.1551 - c = s.charAt(i);
1.1552 -
1.1553 - if (Character.isWhitespace(c)) {
1.1554 - hasSpace = true;
1.1555 - sb.append(c);
1.1556 -
1.1557 - continue;
1.1558 - }
1.1559 -
1.1560 - if (c == '\\') {
1.1561 - sb.append('\\').append('\\');
1.1562 -
1.1563 - continue;
1.1564 - }
1.1565 -
1.1566 - if (c == '"') {
1.1567 - sb.append('\\').append('"');
1.1568 -
1.1569 - continue;
1.1570 - }
1.1571 -
1.1572 - sb.append(c);
1.1573 - }
1.1574 -
1.1575 - if (hasSpace) {
1.1576 - sb.insert(sz, '"');
1.1577 - sb.append('"');
1.1578 - }
1.1579 - }
1.1580 -
1.1581 - //
1.1582 - // Key conversions
1.1583 - //
1.1584 -
1.1585 - private static final class NamesAndValues {
1.1586 - final Map<Integer,String> keyToString;
1.1587 - final Map<String,Integer> stringToKey;
1.1588 - NamesAndValues(Map<Integer,String> keyToString, Map<String,Integer> stringToKey) {
1.1589 - this.keyToString = keyToString;
1.1590 - this.stringToKey = stringToKey;
1.1591 - }
1.1592 - }
1.1593 -
1.1594 - private static Reference<NamesAndValues> namesAndValues;
1.1595 -
1.1596 - private static synchronized NamesAndValues initNameAndValues() {
1.1597 - if (namesAndValues != null) {
1.1598 - NamesAndValues nav = namesAndValues.get();
1.1599 - if (nav != null) {
1.1600 - return nav;
1.1601 - }
1.1602 - }
1.1603 -
1.1604 - Field[] fields = KeyEvent.class.getDeclaredFields();
1.1605 -
1.1606 - Map<String,Integer> names = new HashMap<String,Integer>(fields.length * 4 / 3 + 5, 0.75f);
1.1607 - Map<Integer,String> values = new HashMap<Integer,String>(fields.length * 4 / 3 + 5, 0.75f);
1.1608 -
1.1609 - for (Field f : fields) {
1.1610 - if (Modifier.isStatic(f.getModifiers())) {
1.1611 - String name = f.getName();
1.1612 - if (name.startsWith("VK_")) { // NOI18N
1.1613 - // exclude VK
1.1614 - name = name.substring(3);
1.1615 - try {
1.1616 - int numb = f.getInt(null);
1.1617 - names.put(name, numb);
1.1618 - values.put(numb, name);
1.1619 - } catch (IllegalArgumentException ex) {
1.1620 - } catch (IllegalAccessException ex) {
1.1621 - }
1.1622 - }
1.1623 - }
1.1624 - }
1.1625 -
1.1626 - if (names.get("CONTEXT_MENU") == null) { // NOI18N
1.1627 - names.put("CONTEXT_MENU", 0x20C); // NOI18N
1.1628 - values.put(0x20C, "CONTEXT_MENU"); // NOI18N
1.1629 - names.put("WINDOWS", 0x20D); // NOI18N
1.1630 - values.put(0x20D, "WINDOWS"); // NOI18N
1.1631 - }
1.1632 -
1.1633 - NamesAndValues nav = new NamesAndValues(values, names);
1.1634 - namesAndValues = new SoftReference<NamesAndValues>(nav);
1.1635 - return nav;
1.1636 - }
1.1637 -
1.1638 - /** Converts a Swing key stroke descriptor to a familiar Emacs-like name.
1.1639 - * @param stroke key description
1.1640 - * @return name of the key (e.g. <code>CS-F1</code> for control-shift-function key one)
1.1641 - * @see #stringToKey
1.1642 - */
1.1643 - public static String keyToString(KeyStroke stroke) {
1.1644 - StringBuilder sb = new StringBuilder();
1.1645 -
1.1646 - // add modifiers that must be pressed
1.1647 - if (addModifiers(sb, stroke.getModifiers())) {
1.1648 - sb.append('-');
1.1649 - }
1.1650 -
1.1651 - appendRest(sb, stroke);
1.1652 - return sb.toString();
1.1653 - }
1.1654 -
1.1655 - private static void appendRest(StringBuilder sb, KeyStroke stroke) {
1.1656 - String c = initNameAndValues().keyToString.get(Integer.valueOf(stroke.getKeyCode()));
1.1657 -
1.1658 - if (c == null) {
1.1659 - sb.append(stroke.getKeyChar());
1.1660 - } else {
1.1661 - sb.append(c);
1.1662 - }
1.1663 - }
1.1664 -
1.1665 - /**
1.1666 - * Converts a Swing key stroke descriptor to a familiar Emacs-like name,
1.1667 - * but in a portable way, ie. <code>Meta-C</code> on Mac => <code>D-C</code>
1.1668 - * @param stroke key description
1.1669 - * @return name of the key (e.g. <code>CS-F1</code> for control-shift-function key one)
1.1670 - * @see #stringToKey
1.1671 - */
1.1672 - public static String keyToString(KeyStroke stroke, boolean portable) {
1.1673 - if (portable) {
1.1674 - StringBuilder sb = new StringBuilder();
1.1675 -
1.1676 - // add modifiers that must be pressed
1.1677 - if (addModifiersPortable(sb, stroke.getModifiers())) {
1.1678 - sb.append('-');
1.1679 - }
1.1680 -
1.1681 - appendRest(sb, stroke);
1.1682 - return sb.toString();
1.1683 - }
1.1684 - return keyToString(stroke);
1.1685 - }
1.1686 -
1.1687 - /** Construct a new key description from a given universal string
1.1688 - * description.
1.1689 - * Provides mapping between Emacs-like textual key descriptions and the
1.1690 - * <code>KeyStroke</code> object used in Swing.
1.1691 - * <P>
1.1692 - * This format has following form:
1.1693 - * <P><code>[C][A][S][M]-<em>identifier</em></code>
1.1694 - * <p>Where:
1.1695 - * <UL>
1.1696 - * <LI> <code>C</code> stands for the Control key
1.1697 - * <LI> <code>A</code> stands for the Alt key
1.1698 - * <LI> <code>S</code> stands for the Shift key
1.1699 - * <LI> <code>M</code> stands for the Meta key
1.1700 - * </UL>
1.1701 - * The format also supports two wildcard codes, to support differences in
1.1702 - * platforms. These are the preferred choices for registering keystrokes,
1.1703 - * since platform conflicts will automatically be handled:
1.1704 - * <UL>
1.1705 - * <LI> <code>D</code> stands for the default menu accelerator - the Control
1.1706 - * key on most platforms, the Command (meta) key on Macintosh</LI>
1.1707 - * <LI> <code>O</code> stands for the alternate accelerator - the Alt key on
1.1708 - * most platforms, the Ctrl key on Macintosh (Macintosh uses Alt as a
1.1709 - * secondary shift key for composing international characters - if you bind
1.1710 - * Alt-8 to an action, a mac user with a French keyboard will not be able
1.1711 - * to type the <code>[</code> character, which is a significant handicap</LI>
1.1712 - * </UL>
1.1713 - * If you use the wildcard characters, and specify a key which will conflict
1.1714 - * with keys the operating system consumes, it will be mapped to whichever
1.1715 - * choice can work - for example, on Macintosh, Command-Q is always consumed
1.1716 - * by the operating system, so <code>D-Q</code> will always map to Control-Q.
1.1717 - * <p>
1.1718 - * Every modifier before the hyphen must be pressed.
1.1719 - * <em>identifier</EM> can be any text constant from {@link KeyEvent} but
1.1720 - * without the leading <code>VK_</code> characters. So {@link KeyEvent#VK_ENTER} is described as
1.1721 - * <code>ENTER</code>.
1.1722 - *
1.1723 - * @param s the string with the description of the key
1.1724 - * @return key description object, or <code>null</code> if the string does not represent any valid key
1.1725 - */
1.1726 - public static KeyStroke stringToKey(String s) {
1.1727 - StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), "-", true); // NOI18N
1.1728 -
1.1729 - int needed = 0;
1.1730 -
1.1731 - Map<String,Integer> names = initNameAndValues().stringToKey;
1.1732 -
1.1733 - int lastModif = -1;
1.1734 -
1.1735 - try {
1.1736 - for (;;) {
1.1737 - String el = st.nextToken();
1.1738 -
1.1739 - // required key
1.1740 - if (el.equals("-")) { // NOI18N
1.1741 -
1.1742 - if (lastModif != -1) {
1.1743 - needed |= lastModif;
1.1744 - lastModif = -1;
1.1745 - }
1.1746 -
1.1747 - continue;
1.1748 - }
1.1749 -
1.1750 - // if there is more elements
1.1751 - if (st.hasMoreElements()) {
1.1752 - // the text should describe modifiers
1.1753 - lastModif = readModifiers(el);
1.1754 - } else {
1.1755 - // last text must be the key code
1.1756 - Integer i = names.get(el);
1.1757 - boolean wildcard = (needed & CTRL_WILDCARD_MASK) != 0;
1.1758 -
1.1759 - //Strip out the explicit mask - KeyStroke won't know
1.1760 - //what to do with it
1.1761 - needed = needed & ~CTRL_WILDCARD_MASK;
1.1762 -
1.1763 - boolean macAlt = (needed & ALT_WILDCARD_MASK) != 0;
1.1764 - needed = needed & ~ALT_WILDCARD_MASK;
1.1765 -
1.1766 - if (i != null) {
1.1767 - //#26854 - Default accelerator should be Command on mac
1.1768 - if (wildcard) {
1.1769 - needed |= getMenuShortcutKeyMask();
1.1770 -
1.1771 - if (isMac()) {
1.1772 - if (!usableKeyOnMac(i, needed)) {
1.1773 - needed &= ~getMenuShortcutKeyMask();
1.1774 - needed |= KeyEvent.CTRL_MASK;
1.1775 - }
1.1776 - }
1.1777 - }
1.1778 -
1.1779 - if (macAlt) {
1.1780 - if (getOperatingSystem() == OS_MAC) {
1.1781 - needed |= KeyEvent.CTRL_MASK;
1.1782 - } else {
1.1783 - needed |= KeyEvent.ALT_MASK;
1.1784 - }
1.1785 - }
1.1786 -
1.1787 - return KeyStroke.getKeyStroke(i, needed);
1.1788 - } else {
1.1789 - return null;
1.1790 - }
1.1791 - }
1.1792 - }
1.1793 - } catch (NoSuchElementException ex) {
1.1794 - return null;
1.1795 - }
1.1796 - }
1.1797 -
1.1798 - private static final boolean usableKeyOnMac(int key, int mask) {
1.1799 - //All permutations fail for Q except ctrl
1.1800 - if (key == KeyEvent.VK_Q) {
1.1801 - return false;
1.1802 - }
1.1803 -
1.1804 - boolean isMeta = ((mask & KeyEvent.META_MASK) != 0) || ((mask & KeyEvent.CTRL_DOWN_MASK) != 0);
1.1805 -
1.1806 - boolean isAlt = ((mask & KeyEvent.ALT_MASK) != 0) || ((mask & KeyEvent.ALT_DOWN_MASK) != 0);
1.1807 -
1.1808 - boolean isOnlyMeta = isMeta && ((mask & ~(KeyEvent.META_DOWN_MASK | KeyEvent.META_MASK)) == 0);
1.1809 -
1.1810 - //Mac OS consumes keys Command+ these keys - the app will never see
1.1811 - //them, so CTRL should not be remapped for these
1.1812 - if (isOnlyMeta) {
1.1813 - return (key != KeyEvent.VK_H) && (key != KeyEvent.VK_SPACE) && (key != KeyEvent.VK_TAB);
1.1814 - } else if ((key == KeyEvent.VK_D) && isMeta && isAlt) {
1.1815 - return false;
1.1816 - } else {
1.1817 - return true;
1.1818 - }
1.1819 - }
1.1820 -
1.1821 - private static final int getMenuShortcutKeyMask() {
1.1822 - // #152050 - work in headless environment too
1.1823 - if (GraphicsEnvironment.isHeadless()) {
1.1824 - return Event.CTRL_MASK;
1.1825 - }
1.1826 - return Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
1.1827 - }
1.1828 -
1.1829 - /** Convert a space-separated list of user-friendly key binding names to a list of Swing key strokes.
1.1830 - * @param s the string with keys
1.1831 - * @return array of key strokes, or <code>null</code> if the string description is not valid
1.1832 - * @see #stringToKey
1.1833 - */
1.1834 - public static KeyStroke[] stringToKeys(String s) {
1.1835 - StringTokenizer st = new StringTokenizer(s.toUpperCase(Locale.ENGLISH), " "); // NOI18N
1.1836 - ArrayList<KeyStroke> arr = new ArrayList<KeyStroke>();
1.1837 -
1.1838 - while (st.hasMoreElements()) {
1.1839 - s = st.nextToken();
1.1840 -
1.1841 - KeyStroke k = stringToKey(s);
1.1842 -
1.1843 - if (k == null) {
1.1844 - return null;
1.1845 - }
1.1846 -
1.1847 - arr.add(k);
1.1848 - }
1.1849 -
1.1850 - return arr.toArray(new KeyStroke[arr.size()]);
1.1851 - }
1.1852 -
1.1853 - /** Adds characters for modifiers to the buffer.
1.1854 - * @param buf buffer to add to
1.1855 - * @param modif modifiers to add (KeyEvent.XXX_MASK)
1.1856 - * @return true if something has been added
1.1857 - */
1.1858 - private static boolean addModifiers(StringBuilder buf, int modif) {
1.1859 - boolean b = false;
1.1860 -
1.1861 - if ((modif & KeyEvent.CTRL_MASK) != 0) {
1.1862 - buf.append("C"); // NOI18N
1.1863 - b = true;
1.1864 - }
1.1865 -
1.1866 - if ((modif & KeyEvent.ALT_MASK) != 0) {
1.1867 - buf.append("A"); // NOI18N
1.1868 - b = true;
1.1869 - }
1.1870 -
1.1871 - if ((modif & KeyEvent.SHIFT_MASK) != 0) {
1.1872 - buf.append("S"); // NOI18N
1.1873 - b = true;
1.1874 - }
1.1875 -
1.1876 - if ((modif & KeyEvent.META_MASK) != 0) {
1.1877 - buf.append("M"); // NOI18N
1.1878 - b = true;
1.1879 - }
1.1880 -
1.1881 - if ((modif & CTRL_WILDCARD_MASK) != 0) {
1.1882 - buf.append("D");
1.1883 - b = true;
1.1884 - }
1.1885 -
1.1886 - if ((modif & ALT_WILDCARD_MASK) != 0) {
1.1887 - buf.append("O");
1.1888 - b = true;
1.1889 - }
1.1890 -
1.1891 - return b;
1.1892 - }
1.1893 -
1.1894 - private static boolean addModifiersPortable(StringBuilder buf, int modifiers) {
1.1895 - boolean b = false;
1.1896 -
1.1897 - if ((modifiers & KeyEvent.SHIFT_MASK) != 0) {
1.1898 - buf.append('S');
1.1899 - b = true;
1.1900 - }
1.1901 -
1.1902 - if (Utilities.isMac() && ((modifiers & KeyEvent.META_MASK) != 0) || !Utilities.isMac() && ((modifiers & KeyEvent.CTRL_MASK) != 0)) {
1.1903 - buf.append('D');
1.1904 - b = true;
1.1905 - }
1.1906 -
1.1907 - if (Utilities.isMac() && ((modifiers & KeyEvent.CTRL_MASK) != 0) || !Utilities.isMac() && ((modifiers & KeyEvent.ALT_MASK) != 0)) {
1.1908 - buf.append('O');
1.1909 - b = true;
1.1910 - }
1.1911 - // mac alt fallback
1.1912 - if (Utilities.isMac() && ((modifiers & KeyEvent.ALT_MASK) != 0)) {
1.1913 - buf.append('A');
1.1914 - b = true;
1.1915 - }
1.1916 -
1.1917 - return b;
1.1918 - }
1.1919 -
1.1920 - /** Reads for modifiers and creates integer with required mask.
1.1921 - * @param s string with modifiers
1.1922 - * @return integer with mask
1.1923 - * @exception NoSuchElementException if some letter is not modifier
1.1924 - */
1.1925 - private static int readModifiers(String s) throws NoSuchElementException {
1.1926 - int m = 0;
1.1927 -
1.1928 - for (int i = 0; i < s.length(); i++) {
1.1929 - switch (s.charAt(i)) {
1.1930 - case 'C':
1.1931 - m |= KeyEvent.CTRL_MASK;
1.1932 -
1.1933 - break;
1.1934 -
1.1935 - case 'A':
1.1936 - m |= KeyEvent.ALT_MASK;
1.1937 -
1.1938 - break;
1.1939 -
1.1940 - case 'M':
1.1941 - m |= KeyEvent.META_MASK;
1.1942 -
1.1943 - break;
1.1944 -
1.1945 - case 'S':
1.1946 - m |= KeyEvent.SHIFT_MASK;
1.1947 -
1.1948 - break;
1.1949 -
1.1950 - case 'D':
1.1951 - m |= CTRL_WILDCARD_MASK;
1.1952 -
1.1953 - break;
1.1954 -
1.1955 - case 'O':
1.1956 - m |= ALT_WILDCARD_MASK;
1.1957 -
1.1958 - break;
1.1959 -
1.1960 - default:
1.1961 - throw new NoSuchElementException(s);
1.1962 - }
1.1963 - }
1.1964 -
1.1965 - return m;
1.1966 - }
1.1967 -
1.1968 - /**
1.1969 - * Finds out the monitor where the user currently has the input focus.
1.1970 - * This method is usually used to help the client code to figure out on
1.1971 - * which monitor it should place newly created windows/frames/dialogs.
1.1972 - *
1.1973 - * @return the GraphicsConfiguration of the monitor which currently has the
1.1974 - * input focus
1.1975 - */
1.1976 - private static GraphicsConfiguration getCurrentGraphicsConfiguration() {
1.1977 - Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
1.1978 - if (focusOwner != null) {
1.1979 - Window w = SwingUtilities.getWindowAncestor(focusOwner);
1.1980 - if (w != null) {
1.1981 - return w.getGraphicsConfiguration();
1.1982 - }
1.1983 - }
1.1984 -
1.1985 - return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1.1986 - }
1.1987 -
1.1988 - /**
1.1989 - * Returns the usable area of the screen where applications can place its
1.1990 - * windows. The method subtracts from the screen the area of taskbars,
1.1991 - * system menus and the like. The screen this method applies to is the one
1.1992 - * which is considered current, ussually the one where the current input
1.1993 - * focus is.
1.1994 - *
1.1995 - * @return the rectangle of the screen where one can place windows
1.1996 - *
1.1997 - * @since 2.5
1.1998 - */
1.1999 - public static Rectangle getUsableScreenBounds() {
1.2000 - return getUsableScreenBounds(getCurrentGraphicsConfiguration());
1.2001 - }
1.2002 -
1.2003 - /**
1.2004 - * Returns the usable area of the screen where applications can place its
1.2005 - * windows. The method subtracts from the screen the area of taskbars,
1.2006 - * system menus and the like.
1.2007 - *
1.2008 - * @param gconf the GraphicsConfiguration of the monitor
1.2009 - * @return the rectangle of the screen where one can place windows
1.2010 - *
1.2011 - * @since 2.5
1.2012 - */
1.2013 - public static Rectangle getUsableScreenBounds(GraphicsConfiguration gconf) {
1.2014 - if (gconf == null) {
1.2015 - gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1.2016 - }
1.2017 -
1.2018 - Rectangle bounds = new Rectangle(gconf.getBounds());
1.2019 -
1.2020 - String str;
1.2021 -
1.2022 - str = System.getProperty("netbeans.screen.insets"); // NOI18N
1.2023 -
1.2024 - if (str != null) {
1.2025 - StringTokenizer st = new StringTokenizer(str, ", "); // NOI18N
1.2026 -
1.2027 - if (st.countTokens() == 4) {
1.2028 - try {
1.2029 - bounds.y = Integer.parseInt(st.nextToken());
1.2030 - bounds.x = Integer.parseInt(st.nextToken());
1.2031 - bounds.height -= (bounds.y + Integer.parseInt(st.nextToken()));
1.2032 - bounds.width -= (bounds.x + Integer.parseInt(st.nextToken()));
1.2033 - } catch (NumberFormatException ex) {
1.2034 - LOG.log(Level.WARNING, null, ex);
1.2035 - }
1.2036 - }
1.2037 -
1.2038 - return bounds;
1.2039 - }
1.2040 -
1.2041 - str = System.getProperty("netbeans.taskbar.height"); // NOI18N
1.2042 -
1.2043 - if (str != null) {
1.2044 - bounds.height -= Integer.getInteger(str, 0).intValue();
1.2045 -
1.2046 - return bounds;
1.2047 - }
1.2048 -
1.2049 - try {
1.2050 - Toolkit toolkit = Toolkit.getDefaultToolkit();
1.2051 - Insets insets = toolkit.getScreenInsets(gconf);
1.2052 - bounds.y += insets.top;
1.2053 - bounds.x += insets.left;
1.2054 - bounds.height -= (insets.top + insets.bottom);
1.2055 - bounds.width -= (insets.left + insets.right);
1.2056 - } catch (Exception ex) {
1.2057 - LOG.log(Level.WARNING, null, ex);
1.2058 - }
1.2059 -
1.2060 - return bounds;
1.2061 - }
1.2062 -
1.2063 - /**
1.2064 - * Helps client code place components on the center of the screen. It
1.2065 - * handles multiple monitor configuration correctly
1.2066 - *
1.2067 - * @param componentSize the size of the component
1.2068 - * @return bounds of the centered component
1.2069 - *
1.2070 - * @since 2.5
1.2071 - */
1.2072 - public static Rectangle findCenterBounds(Dimension componentSize) {
1.2073 - return findCenterBounds(getCurrentGraphicsConfiguration(), componentSize);
1.2074 - }
1.2075 -
1.2076 - /**
1.2077 - * Helps client code place components on the center of the screen. It
1.2078 - * handles multiple monitor configuration correctly
1.2079 - *
1.2080 - * @param gconf the GraphicsConfiguration of the monitor
1.2081 - * @param componentSize the size of the component
1.2082 - * @return bounds of the centered component
1.2083 - */
1.2084 - private static Rectangle findCenterBounds(GraphicsConfiguration gconf, Dimension componentSize) {
1.2085 - if (gconf == null) {
1.2086 - gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1.2087 - }
1.2088 -
1.2089 - Rectangle bounds = gconf.getBounds();
1.2090 -
1.2091 - return new Rectangle(
1.2092 - bounds.x + ((bounds.width - componentSize.width) / 2),
1.2093 - bounds.y + ((bounds.height - componentSize.height) / 2), componentSize.width, componentSize.height
1.2094 - );
1.2095 - }
1.2096 -
1.2097 - /** @return size of the screen. The size is modified for Windows OS
1.2098 - * - some points are subtracted to reflect a presence of the taskbar
1.2099 - *
1.2100 - * @deprecated this method is almost useless in multiple monitor configuration
1.2101 - *
1.2102 - * @see #getUsableScreenBounds()
1.2103 - * @see #findCenterBounds(Dimension)
1.2104 - */
1.2105 - @Deprecated
1.2106 - public static final Dimension getScreenSize() {
1.2107 - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
1.2108 -
1.2109 - if (isWindows() && !Boolean.getBoolean("netbeans.no.taskbar")) {
1.2110 - screenSize.height -= TYPICAL_WINDOWS_TASKBAR_HEIGHT;
1.2111 - } else if (isMac()) {
1.2112 - screenSize.height -= TYPICAL_MACOSX_MENU_HEIGHT;
1.2113 - }
1.2114 -
1.2115 - return screenSize;
1.2116 - }
1.2117 -
1.2118 - /** Utility method for avoiding of memory leak in JDK 1.3 / JFileChooser.showDialog(...)
1.2119 - * @param parent
1.2120 - * @param approveButtonText
1.2121 - * @deprecated Not needed in JDK 1.4.
1.2122 - * @see <a href="@org-openide-filesystems@/org/openide/filesystems/FileChooserBuilder.html"><code>FileChooserBuilder</code></a>
1.2123 - */
1.2124 - @Deprecated
1.2125 - public static final int showJFileChooser(
1.2126 - javax.swing.JFileChooser chooser, java.awt.Component parent, java.lang.String approveButtonText
1.2127 - ) {
1.2128 - if (approveButtonText != null) {
1.2129 - chooser.setApproveButtonText(approveButtonText);
1.2130 - chooser.setDialogType(javax.swing.JFileChooser.CUSTOM_DIALOG);
1.2131 - }
1.2132 -
1.2133 - Frame frame = null;
1.2134 - Dialog parentDlg = null;
1.2135 -
1.2136 - if (parent instanceof Dialog) {
1.2137 - parentDlg = (Dialog) parent;
1.2138 - } else {
1.2139 - frame = (parent instanceof java.awt.Frame) ? (Frame) parent
1.2140 - : (Frame) javax.swing.SwingUtilities.getAncestorOfClass(
1.2141 - Frame.class, parent
1.2142 - );
1.2143 - }
1.2144 -
1.2145 - String title = chooser.getDialogTitle();
1.2146 -
1.2147 - if (title == null) {
1.2148 - title = chooser.getUI().getDialogTitle(chooser);
1.2149 - }
1.2150 -
1.2151 - final javax.swing.JDialog dialog;
1.2152 -
1.2153 - if (parentDlg != null) {
1.2154 - dialog = new javax.swing.JDialog(parentDlg, title, true);
1.2155 - } else {
1.2156 - dialog = new javax.swing.JDialog(frame, title, true);
1.2157 - }
1.2158 -
1.2159 - dialog.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
1.2160 -
1.2161 - Container contentPane = dialog.getContentPane();
1.2162 - contentPane.setLayout(new BorderLayout());
1.2163 - contentPane.add(chooser, BorderLayout.CENTER);
1.2164 -
1.2165 - dialog.pack();
1.2166 - dialog.setBounds(findCenterBounds(parent.getGraphicsConfiguration(), dialog.getSize()));
1.2167 -
1.2168 - chooser.rescanCurrentDirectory();
1.2169 -
1.2170 - final int[] retValue = {javax.swing.JFileChooser.CANCEL_OPTION};
1.2171 -
1.2172 - java.awt.event.ActionListener l = new java.awt.event.ActionListener() {
1.2173 - public void actionPerformed(java.awt.event.ActionEvent ev) {
1.2174 - if (javax.swing.JFileChooser.APPROVE_SELECTION.equals(ev.getActionCommand())) {
1.2175 - retValue[0] = javax.swing.JFileChooser.APPROVE_OPTION;
1.2176 - }
1.2177 -
1.2178 - dialog.setVisible(false);
1.2179 - dialog.dispose();
1.2180 - }
1.2181 - };
1.2182 -
1.2183 - chooser.addActionListener(l);
1.2184 -
1.2185 - dialog.show();
1.2186 -
1.2187 - return retValue[0];
1.2188 - }
1.2189 -
1.2190 - /** Sort a list according to a specified partial order.
1.2191 - * Note that in the current implementation, the comparator will be called
1.2192 - * exactly once for each distinct pair of list elements, ignoring order,
1.2193 - * so caching its results is a waste of time.
1.2194 - * @param l the list to sort (will not be modified)
1.2195 - * @param c a comparator to impose the partial order; "equal" means that the elements
1.2196 - * are not ordered with respect to one another, i.e. may be only a partial order
1.2197 - * @param stable whether to attempt a stable sort, meaning that the position of elements
1.2198 - * will be disturbed as little as possible; might be slightly slower
1.2199 - * @return the partially-sorted list
1.2200 - * @throws UnorderableException if the specified partial order is inconsistent on this list
1.2201 - * @deprecated Deprecated in favor of the potentially much faster (and possibly more correct) {@link #topologicalSort}.
1.2202 - */
1.2203 - @SuppressWarnings("unchecked") // do not bother, it is deprecated anyway
1.2204 - @Deprecated
1.2205 - public static List partialSort(List l, Comparator c, boolean stable)
1.2206 - throws UnorderableException {
1.2207 - // map from objects in the list to null or sets of objects they are greater than
1.2208 - // (i.e. must appear after):
1.2209 - Map deps = new HashMap(); // Map<Object,Set<Object>>
1.2210 - int size = l.size();
1.2211 -
1.2212 - // Create a table of dependencies.
1.2213 - for (int i = 0; i < size; i++) {
1.2214 - for (int j = i + 1; j < size; j++) {
1.2215 - int cmp = c.compare(l.get(i), l.get(j));
1.2216 -
1.2217 - if (cmp != 0) {
1.2218 - Object earlier = l.get((cmp < 0) ? i : j);
1.2219 - Object later = l.get((cmp > 0) ? i : j);
1.2220 - Set s = (Set) deps.get(later);
1.2221 -
1.2222 - if (s == null) {
1.2223 - deps.put(later, s = new HashSet());
1.2224 - }
1.2225 -
1.2226 - s.add(earlier);
1.2227 - }
1.2228 - }
1.2229 - }
1.2230 -
1.2231 - // Lists of items to process, and items sorted.
1.2232 - List left = new LinkedList(l);
1.2233 - List sorted = new ArrayList(size);
1.2234 -
1.2235 - while (left.size() > 0) {
1.2236 - boolean stillGoing = false;
1.2237 - Iterator it = left.iterator();
1.2238 -
1.2239 - while (it.hasNext()) {
1.2240 - Object elt = it.next();
1.2241 - Set eltDeps = (Set) deps.get(elt);
1.2242 -
1.2243 - if ((eltDeps == null) || (eltDeps.size() == 0)) {
1.2244 - // This one is OK to add to the result now.
1.2245 - it.remove();
1.2246 - stillGoing = true;
1.2247 - sorted.add(elt);
1.2248 -
1.2249 - // Mark other elements that should be later
1.2250 - // than this as having their dep satisfied.
1.2251 - Iterator it2 = left.iterator();
1.2252 -
1.2253 - while (it2.hasNext()) {
1.2254 - Object elt2 = it2.next();
1.2255 - Set eltDeps2 = (Set) deps.get(elt2);
1.2256 -
1.2257 - if (eltDeps2 != null) {
1.2258 - eltDeps2.remove(elt);
1.2259 - }
1.2260 - }
1.2261 -
1.2262 - if (stable) {
1.2263 - break;
1.2264 - }
1.2265 - }
1.2266 - }
1.2267 -
1.2268 - if (!stillGoing) {
1.2269 - // Clean up deps to only include "interesting" problems.
1.2270 - it = deps.entrySet().iterator();
1.2271 -
1.2272 - while (it.hasNext()) {
1.2273 - Map.Entry me = (Map.Entry) it.next();
1.2274 -
1.2275 - if (!left.contains(me.getKey())) {
1.2276 - it.remove();
1.2277 - } else {
1.2278 - Set s = (Set) me.getValue();
1.2279 - Iterator it2 = s.iterator();
1.2280 -
1.2281 - while (it2.hasNext()) {
1.2282 - if (!left.contains(it2.next())) {
1.2283 - it2.remove();
1.2284 - }
1.2285 - }
1.2286 -
1.2287 - if (s.isEmpty()) {
1.2288 - it.remove();
1.2289 - }
1.2290 - }
1.2291 - }
1.2292 -
1.2293 - throw new UnorderableException(left, deps);
1.2294 - }
1.2295 - }
1.2296 -
1.2297 - return sorted;
1.2298 - }
1.2299 -
1.2300 - /**
1.2301 - * Topologically sort some objects.
1.2302 - * <p>There may not be any nulls among the objects, nor duplicates
1.2303 - * (as per hash/equals), nor duplicates among the edge lists.
1.2304 - * The edge map need not contain an entry for every object, only if it
1.2305 - * has some outgoing edges (empty but not null map values are permitted).
1.2306 - * The edge map shall not contain neither keys nor value entries for objects not
1.2307 - * in the collection to be sorted, if that happens they will be ignored (since version 7.9).
1.2308 - * <p>The incoming parameters will not be modified; they must not be changed
1.2309 - * during the call and possible calls to TopologicalSortException methods.
1.2310 - * The returned list will support modifications.
1.2311 - * <p>There is a <em>weak</em> stability guarantee: if there are no edges
1.2312 - * which contradict the incoming order, the resulting list will be in the same
1.2313 - * order as the incoming elements. However if some elements need to be rearranged,
1.2314 - * it is <em>not</em> guaranteed that others will not also be rearranged, even
1.2315 - * if they did not strictly speaking need to be.
1.2316 - * @param c a collection of objects to be topologically sorted
1.2317 - * @param edges constraints among those objects, of type <code>Map<Object,Collection></code>;
1.2318 - * if an object is a key in this map, the resulting order will
1.2319 - * have that object before any objects listed in the value
1.2320 - * @return a partial ordering of the objects in the collection,
1.2321 - * @exception TopologicalSortException if the sort cannot succeed due to cycles in the graph, the
1.2322 - * exception contains additional information to describe and possibly recover from the error
1.2323 - * @since 3.30
1.2324 - * @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=27286">Issue #27286</a>
1.2325 - */
1.2326 - public static <T> List<T> topologicalSort(Collection<T> c, Map<? super T, ? extends Collection<? extends T>> edges)
1.2327 - throws TopologicalSortException {
1.2328 - Map<T,Boolean> finished = new HashMap<T,Boolean>();
1.2329 - List<T> r = new ArrayList<T>(Math.max(c.size(), 1));
1.2330 - List<T> cRev = new ArrayList<T>(c);
1.2331 - Collections.reverse(cRev);
1.2332 -
1.2333 - Iterator<T> it = cRev.iterator();
1.2334 -
1.2335 - while (it.hasNext()) {
1.2336 - List<T> cycle = visit(it.next(), edges, finished, r);
1.2337 -
1.2338 - if (cycle != null) {
1.2339 - throw new TopologicalSortException(cRev, edges);
1.2340 - }
1.2341 - }
1.2342 -
1.2343 - Collections.reverse(r);
1.2344 - if (r.size() != c.size()) {
1.2345 - r.retainAll(c);
1.2346 - }
1.2347 -
1.2348 - return r;
1.2349 - }
1.2350 -
1.2351 - /**
1.2352 - * Visit one node in the DAG.
1.2353 - * @param node node to visit
1.2354 - * @param edges edges in the DAG
1.2355 - * @param finished which nodes are finished; a node has no entry if it has not yet
1.2356 - * been visited, else it is set to false while recurring and true
1.2357 - * when it has finished
1.2358 - * @param r the order in progress
1.2359 - * @return list with detected cycle
1.2360 - */
1.2361 - static <T> List<T> visit(
1.2362 - T node,
1.2363 - Map<? super T, ? extends Collection<? extends T>> edges,
1.2364 - Map<T,Boolean> finished,
1.2365 - List<T> r
1.2366 - ) {
1.2367 - Boolean b = finished.get(node);
1.2368 -
1.2369 - //System.err.println("node=" + node + " color=" + b);
1.2370 - if (b != null) {
1.2371 - if (b.booleanValue()) {
1.2372 - return null;
1.2373 - }
1.2374 -
1.2375 - ArrayList<T> cycle = new ArrayList<T>();
1.2376 - cycle.add(node);
1.2377 - finished.put(node, null);
1.2378 -
1.2379 - return cycle;
1.2380 - }
1.2381 -
1.2382 - Collection<? extends T> e = edges.get(node);
1.2383 -
1.2384 - if (e != null) {
1.2385 - finished.put(node, Boolean.FALSE);
1.2386 -
1.2387 - Iterator<? extends T> it = e.iterator();
1.2388 -
1.2389 - while (it.hasNext()) {
1.2390 - List<T> cycle = visit(it.next(), edges, finished, r);
1.2391 -
1.2392 - if (cycle != null) {
1.2393 - if (cycle instanceof ArrayList) {
1.2394 - // if cycle instanceof ArrayList we are still in the
1.2395 - // cycle and we want to collect new members
1.2396 - if (Boolean.FALSE == finished.get(node)) {
1.2397 - // another member in the cycle
1.2398 - cycle.add(node);
1.2399 - } else {
1.2400 - // we have reached the head of the cycle
1.2401 - // do not add additional cycles anymore
1.2402 - Collections.reverse(cycle);
1.2403 -
1.2404 - // changing cycle to not be ArrayList
1.2405 - cycle = Collections.unmodifiableList(cycle);
1.2406 - }
1.2407 - }
1.2408 -
1.2409 - // mark this node as tested
1.2410 - finished.put(node, Boolean.TRUE);
1.2411 -
1.2412 - // and report an error
1.2413 - return cycle;
1.2414 - }
1.2415 - }
1.2416 - }
1.2417 -
1.2418 - finished.put(node, Boolean.TRUE);
1.2419 - r.add(node);
1.2420 -
1.2421 - return null;
1.2422 - }
1.2423 -
1.2424 - /** Provides support for parts of the system that deal with classnames
1.2425 - * (use <code>Class.forName</code>, <code>NbObjectInputStream</code>, etc.).
1.2426 - * <P>
1.2427 - * Often class names (especially package names) changes during lifecycle
1.2428 - * of a module. When some piece of the system stores the name of a class
1.2429 - * in certain point of a time and wants to find the correct <code>Class</code>
1.2430 - * later it needs to count with the possibility of rename.
1.2431 - * <P>
1.2432 - * For such purposes this method has been created. It allows modules to
1.2433 - * register their classes that changed names and other parts of system that
1.2434 - * deal with class names to find the correct names.
1.2435 - * <P>
1.2436 - * To register a mapping from old class names to new ones create a file
1.2437 - * <code>META-INF/netbeans/translate.names</code> in your module and fill it
1.2438 - * with your mapping:
1.2439 - * <PRE>
1.2440 - * #
1.2441 - * # Mapping of legacy classes to new ones
1.2442 - * #
1.2443 - *
1.2444 - * org.oldpackage.MyClass=org.newpackage.MyClass # rename of package for one class
1.2445 - * org.mypackage.OldClass=org.mypackage.NewClass # rename of class in a package
1.2446 - *
1.2447 - * # rename of class and package
1.2448 - * org.oldpackage.OldClass=org.newpackage.NewClass
1.2449 - *
1.2450 - * # rename of whole package
1.2451 - * org.someoldpackage=org.my.new.package.structure
1.2452 - *
1.2453 - * # class was removed without replacement
1.2454 - * org.mypackage.OldClass=
1.2455 - *
1.2456 - * </PRE>
1.2457 - * Btw. one can use spaces instead of <code>=</code> sign.
1.2458 - * For a real world example
1.2459 - * check the
1.2460 - * <a href="http://www.netbeans.org/source/browse/xml/text-edit/compat/src/META-INF/netbeans/">
1.2461 - * xml module</a>.
1.2462 - *
1.2463 - * <P>
1.2464 - * For purposes of <link>org.openide.util.io.NbObjectInputStream</link> there is
1.2465 - * a following special convention:
1.2466 - * If the
1.2467 - * className is not listed as one that is to be renamed, the returned
1.2468 - * string == className, if the className is registered to be renamed
1.2469 - * than the className != returned value, even in a case when className.equals (retValue)
1.2470 - *
1.2471 - * @param className fully qualified name of a class to translate
1.2472 - * @return new name of the class according to renaming rules.
1.2473 - */
1.2474 - public static String translate(final String className) {
1.2475 - checkMapping();
1.2476 -
1.2477 - RE exp;
1.2478 -
1.2479 - synchronized (TRANS_LOCK) {
1.2480 - exp = transExp;
1.2481 - }
1.2482 -
1.2483 - if (exp == null) {
1.2484 - // no transition table found
1.2485 - return className;
1.2486 - }
1.2487 -
1.2488 - synchronized (exp) {
1.2489 - // refusing convertions as fast as possible
1.2490 - return exp.convert(className);
1.2491 - }
1.2492 - }
1.2493 -
1.2494 - /** Loads all resources that contain renaming information.
1.2495 - * @param l classloader to load packages from
1.2496 - */
1.2497 - private static void checkMapping() {
1.2498 - // test if we run in test mode
1.2499 - if (transLoader == TRANS_LOCK) {
1.2500 - // no check
1.2501 - return;
1.2502 - }
1.2503 -
1.2504 - ClassLoader current = Lookup.getDefault().lookup(ClassLoader.class);
1.2505 -
1.2506 - if (current == null) {
1.2507 - current = ClassLoader.getSystemClassLoader();
1.2508 - }
1.2509 -
1.2510 - if (transLoader == current) {
1.2511 - // no change, no rescan
1.2512 - return;
1.2513 - }
1.2514 -
1.2515 - initForLoader(current, current);
1.2516 - }
1.2517 -
1.2518 - /* Initializes the content of transition table from a classloader.
1.2519 - * @param loader loader to read data from
1.2520 - * @param set loader to set as the transLoader or null if we run in test mode
1.2521 - */
1.2522 - static void initForLoader(ClassLoader current, Object set) {
1.2523 - if (set == null) {
1.2524 - set = TRANS_LOCK;
1.2525 - }
1.2526 -
1.2527 - Enumeration en;
1.2528 -
1.2529 - try {
1.2530 - en = current.getResources("META-INF/netbeans/translate.names");
1.2531 - } catch (IOException ex) {
1.2532 - LOG.log(Level.WARNING, null, ex);
1.2533 - en = null;
1.2534 - }
1.2535 -
1.2536 - if ((en == null) || !en.hasMoreElements()) {
1.2537 - synchronized (TRANS_LOCK) {
1.2538 - transLoader = set;
1.2539 - transExp = null;
1.2540 - }
1.2541 -
1.2542 - return;
1.2543 - }
1.2544 -
1.2545 - // format of line in the meta files
1.2546 - //
1.2547 - // # comments are allowed
1.2548 - // a.name.in.a.Package=another.Name # with comment is allowed
1.2549 - // for.compatibility.one.can.use.Space instead.of.Equal
1.2550 - //
1.2551 - RE re = null;
1.2552 -
1.2553 - // [pnejedly:perf] commented out. The RegExp based translation was way slower
1.2554 - // than the hand-written RE13
1.2555 - // if (Dependency.JAVA_SPEC.compareTo(new SpecificationVersion("1.4")) >= 0) { // NOI18N
1.2556 - // try {
1.2557 - // re = (RE)Class.forName ("org.openide.util.RE14").newInstance ();
1.2558 - // } catch (ThreadDeath t) {
1.2559 - // throw t;
1.2560 - // } catch (Throwable t) {
1.2561 - // }
1.2562 - // }
1.2563 - // if (re == null) {
1.2564 - re = new RE13();
1.2565 -
1.2566 - // }
1.2567 - TreeSet<String[]> list = new TreeSet<String[]>(
1.2568 - new Comparator<String[]>() {
1.2569 - public int compare(String[] o1, String[] o2) {
1.2570 - String s1 = o1[0];
1.2571 - String s2 = o2[0];
1.2572 -
1.2573 - int i1 = s1.length();
1.2574 - int i2 = s2.length();
1.2575 -
1.2576 - if (i1 != i2) {
1.2577 - return i2 - i1;
1.2578 - }
1.2579 -
1.2580 - return s2.compareTo(s1);
1.2581 - }
1.2582 - }
1.2583 - );
1.2584 -
1.2585 - while (en.hasMoreElements()) {
1.2586 - URL u = (URL) en.nextElement();
1.2587 -
1.2588 - try {
1.2589 - BufferedReader reader = new BufferedReader(
1.2590 - new InputStreamReader(u.openStream(), "UTF8") // use explicit encoding //NOI18N
1.2591 - );
1.2592 - loadTranslationFile(re, reader, list);
1.2593 - reader.close();
1.2594 - } catch (IOException ex) {
1.2595 - LOG.log(Level.WARNING, "Problematic file: " + u);
1.2596 - LOG.log(Level.WARNING, null, ex);
1.2597 - }
1.2598 - }
1.2599 -
1.2600 - // construct a regular expression of following form. Let "1", "2", "3", "4"
1.2601 - // be the keys:
1.2602 - // "^
1.2603 - // thus if 4 is matched five groups will be created
1.2604 - String[] arr = new String[list.size()];
1.2605 - String[] pattern = new String[arr.length];
1.2606 -
1.2607 - int i = 0;
1.2608 - Iterator it = list.iterator();
1.2609 -
1.2610 - while (it.hasNext()) {
1.2611 - String[] pair = (String[]) it.next();
1.2612 - arr[i] = pair[1].intern(); // name of the track
1.2613 - pattern[i] = pair[0]; // original object
1.2614 - i++;
1.2615 - }
1.2616 -
1.2617 - synchronized (TRANS_LOCK) {
1.2618 - // last check
1.2619 - if (arr.length == 0) {
1.2620 - transExp = null;
1.2621 - } else {
1.2622 - transExp = re;
1.2623 - transExp.init(pattern, arr);
1.2624 - }
1.2625 -
1.2626 - transLoader = set;
1.2627 - }
1.2628 - }
1.2629 -
1.2630 - /**
1.2631 - * Load single translation file.
1.2632 - * @param resource URL identifiing transaction table
1.2633 - * @param results will be filled with String[2]
1.2634 - */
1.2635 - private static void loadTranslationFile(RE re, BufferedReader reader, Set<String[]> results)
1.2636 - throws IOException {
1.2637 - for (;;) {
1.2638 - String line = reader.readLine();
1.2639 -
1.2640 - if (line == null) {
1.2641 - break;
1.2642 - }
1.2643 -
1.2644 - if ((line.length() == 0) || line.startsWith("#")) { // NOI18N
1.2645 -
1.2646 - continue;
1.2647 - }
1.2648 -
1.2649 - String[] pair = re.readPair(line);
1.2650 -
1.2651 - if (pair == null) {
1.2652 - throw new java.io.InvalidObjectException("Line is invalid: " + line);
1.2653 - }
1.2654 -
1.2655 - results.add(pair);
1.2656 - }
1.2657 - }
1.2658 -
1.2659 - /** This method merges two images into the new one. The second image is drawn
1.2660 - * over the first one with its top-left corner at x, y. Images need not be of the same size.
1.2661 - * New image will have a size of max(second image size + top-left corner, first image size).
1.2662 - * Method is used mostly when second image contains transparent pixels (e.g. for badging).
1.2663 - * @param image1 underlying image
1.2664 - * @param image2 second image
1.2665 - * @param x x position of top-left corner
1.2666 - * @param y y position of top-left corner
1.2667 - * @return new merged image
1.2668 - * @deprecated Use {@link ImageUtilities#mergeImages}.
1.2669 - */
1.2670 - @Deprecated
1.2671 - public static final Image mergeImages(Image image1, Image image2, int x, int y) {
1.2672 - return ImageUtilities.mergeImages(image1, image2, x, y);
1.2673 - }
1.2674 -
1.2675 - /**
1.2676 - * Loads an image from the specified resource ID. The image is loaded using the "system" classloader registered in
1.2677 - * Lookup.
1.2678 - * @param resourceID resource path of the icon (no initial slash)
1.2679 - * @return icon's Image, or null, if the icon cannot be loaded.
1.2680 - * @deprecated Use {@link ImageUtilities#loadImage(java.lang.String)}.
1.2681 - */
1.2682 - @Deprecated
1.2683 - public static final Image loadImage(String resourceID) {
1.2684 - return ImageUtilities.loadImage(resourceID);
1.2685 - }
1.2686 -
1.2687 - /**
1.2688 - * Converts given icon to a {@link java.awt.Image}.
1.2689 - *
1.2690 - * @param icon {@link javax.swing.Icon} to be converted.
1.2691 - * @since 7.3
1.2692 - * @deprecated Use {@link ImageUtilities#icon2Image}.
1.2693 - */
1.2694 - @Deprecated
1.2695 - public static final Image icon2Image(Icon icon) {
1.2696 - return ImageUtilities.icon2Image(icon);
1.2697 - }
1.2698 -
1.2699 - /** Builds a popup menu from actions for provided context specified by
1.2700 - * <code>Lookup</code>.
1.2701 - * Takes list of actions and for actions whic are instances of
1.2702 - * <code>ContextAwareAction</code> creates and uses the context aware instance.
1.2703 - * Then gets the action presenter or simple menu item for the action to the
1.2704 - * popup menu for each action (or separator for each 'lonely' null array member).
1.2705 - *
1.2706 - * @param actions array of actions to build menu for. Can contain null
1.2707 - * elements, they will be replaced by separators
1.2708 - * @param context the context for which the popup is build
1.2709 - * @return the constructed popup menu
1.2710 - * @see ContextAwareAction
1.2711 - * @since 3.29
1.2712 - */
1.2713 - public static JPopupMenu actionsToPopup(Action[] actions, Lookup context) {
1.2714 - // keeps actions for which was menu item created already (do not add them twice)
1.2715 - Set<Action> counted = new HashSet<Action>();
1.2716 - // components to be added (separators are null)
1.2717 - List<Component> components = new ArrayList<Component>();
1.2718 -
1.2719 - for (Action action : actions) {
1.2720 - if (action != null && counted.add(action)) {
1.2721 - // switch to replacement action if there is some
1.2722 - if (action instanceof ContextAwareAction) {
1.2723 - Action contextAwareAction = ((ContextAwareAction) action).createContextAwareInstance(context);
1.2724 - if (contextAwareAction == null) {
1.2725 - Logger.getLogger(Utilities.class.getName()).warning(
1.2726 - "ContextAwareAction.createContextAwareInstance(context) returns null. That is illegal!" // NOI18N
1.2727 - + " action=" + action + ", context=" + context); // NOI18N
1.2728 - } else {
1.2729 - action = contextAwareAction;
1.2730 - }
1.2731 - }
1.2732 -
1.2733 - JMenuItem item;
1.2734 - if (action instanceof Presenter.Popup) {
1.2735 - item = ((Presenter.Popup) action).getPopupPresenter();
1.2736 - if (item == null) {
1.2737 - Logger.getLogger(Utilities.class.getName()).warning(
1.2738 - "findContextMenuImpl, getPopupPresenter returning null for " + action); // NOI18N
1.2739 - continue;
1.2740 - }
1.2741 - } else {
1.2742 - // We need to correctly handle mnemonics with '&' etc.
1.2743 - item = ActionPresenterProvider.getDefault().createPopupPresenter(action);
1.2744 - }
1.2745 -
1.2746 - for (Component c : ActionPresenterProvider.getDefault().convertComponents(item)) {
1.2747 - if (c instanceof JSeparator) {
1.2748 - components.add(null);
1.2749 - } else {
1.2750 - components.add(c);
1.2751 - }
1.2752 - }
1.2753 - } else {
1.2754 - components.add(null);
1.2755 - }
1.2756 - }
1.2757 -
1.2758 - // Now create actual menu. Strip adjacent, leading, and trailing separators.
1.2759 - JPopupMenu menu = ActionPresenterProvider.getDefault().createEmptyPopup();
1.2760 - boolean nonempty = false; // has anything been added yet?
1.2761 - boolean pendingSep = false; // should there be a separator before any following item?
1.2762 - for (Component c : components) {
1.2763 - if (c == null) {
1.2764 - pendingSep = nonempty;
1.2765 - } else {
1.2766 - nonempty = true;
1.2767 - if (pendingSep) {
1.2768 - pendingSep = false;
1.2769 - menu.addSeparator();
1.2770 - }
1.2771 - menu.add(c);
1.2772 - }
1.2773 - }
1.2774 - return menu;
1.2775 - }
1.2776 -
1.2777 - /** Builds a popup menu for provided component. It retrieves context
1.2778 - * (lookup) from provided component instance or one of its parent
1.2779 - * (it searches up to the hierarchy for <code>Lookup.Provider</code> instance).
1.2780 - * If none of the components is <code>Lookup.Provider</code> instance, then
1.2781 - * it is created context which is fed with composite ActionMap which delegates
1.2782 - * to all components up to hierarchy started from the specified one.
1.2783 - * Then <code>actionsToPopup(Action[], Lookup)</code>} is called with
1.2784 - * the found <code>Lookup</code> instance, which actually creates a popup menu.
1.2785 - *
1.2786 - * @param actions array of actions to build menu for. Can contain null
1.2787 - * elements, they will be replaced by separators
1.2788 - * @param component a component in which to search for a context
1.2789 - * @return the constructed popup menu
1.2790 - * @see Lookup.Provider
1.2791 - * @see #actionsToPopup(Action[], Lookup)
1.2792 - * @since 3.29
1.2793 - */
1.2794 - public static javax.swing.JPopupMenu actionsToPopup(Action[] actions, java.awt.Component component) {
1.2795 - Lookup lookup = null;
1.2796 -
1.2797 - for (Component c = component; c != null; c = c.getParent()) {
1.2798 - if (c instanceof Lookup.Provider) {
1.2799 - lookup = ((Lookup.Provider) c).getLookup();
1.2800 -
1.2801 - if (lookup != null) {
1.2802 - break;
1.2803 - }
1.2804 - }
1.2805 - }
1.2806 -
1.2807 - if (lookup == null) {
1.2808 - // Fallback to composite action map, even it is questionable,
1.2809 - // whether we should support component which is not (nor
1.2810 - // none of its parents) lookup provider.
1.2811 - UtilitiesCompositeActionMap map = new UtilitiesCompositeActionMap(component);
1.2812 - lookup = org.openide.util.lookup.Lookups.singleton(map);
1.2813 - }
1.2814 -
1.2815 - return actionsToPopup(actions, lookup);
1.2816 - }
1.2817 -
1.2818 - /**
1.2819 - * Load a menu sequence from a lookup path.
1.2820 - * Any {@link Action} instances are returned as is;
1.2821 - * any {@link JSeparator} instances are translated to nulls.
1.2822 - * Warnings are logged for any other instances.
1.2823 - * @param path a path as given to {@link Lookups#forPath}, generally a layer folder name
1.2824 - * @return a list of actions interspersed with null separators
1.2825 - * @since org.openide.util 7.14
1.2826 - */
1.2827 - public static List<? extends Action> actionsForPath(String path) {
1.2828 - List<Action> actions = new ArrayList<Action>();
1.2829 - for (Lookup.Item<Object> item : Lookups.forPath(path).lookupResult(Object.class).allItems()) {
1.2830 - if (Action.class.isAssignableFrom(item.getType())) {
1.2831 - Object instance = item.getInstance();
1.2832 - if (instance != null) {
1.2833 - actions.add((Action) instance);
1.2834 - }
1.2835 - } else if (JSeparator.class.isAssignableFrom(item.getType())) {
1.2836 - actions.add(null);
1.2837 - } else {
1.2838 - Logger.getLogger(Utilities.class.getName()).warning("Unrecognized object of " + item.getType() + " found in actions path " + path);
1.2839 - }
1.2840 - }
1.2841 - return actions;
1.2842 - }
1.2843 -
1.2844 - /**
1.2845 - * Global context for actions. Toolbar, menu or any other "global"
1.2846 - * action presenters shall operate in this context.
1.2847 - * Presenters for context menu items should <em>not</em> use
1.2848 - * this method; instead see {@link ContextAwareAction}.
1.2849 - * @see ContextGlobalProvider
1.2850 - * @see ContextAwareAction
1.2851 - * @see <a href="http://wiki.netbeans.org/DevFaqActionContextSensitive">NetBeans FAQ</a>
1.2852 - * @return the context for actions
1.2853 - * @since 4.10
1.2854 - */
1.2855 - public static Lookup actionsGlobalContext() {
1.2856 - synchronized (ContextGlobalProvider.class) {
1.2857 - if (global != null) {
1.2858 - return global;
1.2859 - }
1.2860 - }
1.2861 -
1.2862 - ContextGlobalProvider p = Lookup.getDefault().lookup(ContextGlobalProvider.class);
1.2863 - Lookup l = (p == null) ? Lookup.EMPTY : p.createGlobalContext();
1.2864 -
1.2865 - synchronized (ContextGlobalProvider.class) {
1.2866 - if (global == null) {
1.2867 - global = l;
1.2868 - }
1.2869 -
1.2870 - return global;
1.2871 - }
1.2872 - }
1.2873 -
1.2874 - //
1.2875 - // end of actions stuff
1.2876 - //
1.2877 -
1.2878 - /**
1.2879 - * Loads an image based on resource path.
1.2880 - * Exactly like {@link #loadImage(String)} but may do a localized search.
1.2881 - * For example, requesting <samp>org/netbeans/modules/foo/resources/foo.gif</samp>
1.2882 - * might actually find <samp>org/netbeans/modules/foo/resources/foo_ja.gif</samp>
1.2883 - * or <samp>org/netbeans/modules/foo/resources/foo_mybranding.gif</samp>.
1.2884 - *
1.2885 - * <p>Caching of loaded images can be used internally to improve performance.
1.2886 - *
1.2887 - * @since 3.24
1.2888 - * @deprecated Use {@link ImageUtilities#loadImage(java.lang.String, boolean)}.
1.2889 - */
1.2890 - @Deprecated
1.2891 - public static final Image loadImage(String resource, boolean localized) {
1.2892 - return ImageUtilities.loadImage(resource, localized);
1.2893 - }
1.2894 -
1.2895 - /**
1.2896 - * Returns a cursor with an arrow and an hourglass (or stop watch) badge,
1.2897 - * to be used when a component is busy but the UI is still responding to the user.
1.2898 - *
1.2899 - * Similar to the predefined {@link Cursor#WAIT_CURSOR}, but has an arrow to indicate
1.2900 - * a still-responsive UI.
1.2901 - *
1.2902 - * <p>Typically you will set the cursor only temporarily:
1.2903 - *
1.2904 - * <pre>
1.2905 - * <font class="comment">// code is running in other then event dispatch thread</font>
1.2906 - * currentComponent.setCursor(Utilities.createProgressCursor(currentComponent));
1.2907 - * <font class="keyword">try</font> {
1.2908 - * <font class="comment">// perform some work in other than event dispatch thread
1.2909 - * // (do not block UI)</font>
1.2910 - * } <font class="keyword">finally</font> {
1.2911 - * currentComponent.setCursor(<font class="constant">null</font>);
1.2912 - * }
1.2913 - * </pre>
1.2914 - *
1.2915 - * <p>This implementation provides one cursor for all Mac systems, one for all
1.2916 - * Unix systems (regardless of window manager), and one for all other systems
1.2917 - * including Windows. Note: The cursor does not have to look native in some
1.2918 - * cases on some platforms!
1.2919 - *
1.2920 - * @param component the non-null component that will use the progress cursor
1.2921 - * @return a progress cursor (Unix, Windows or Mac)
1.2922 - *
1.2923 - * @since 3.23
1.2924 - */
1.2925 - public static final Cursor createProgressCursor(Component component) {
1.2926 - // refuse null component
1.2927 - if (component == null) {
1.2928 - throw new NullPointerException("Given component is null"); //NOI18N
1.2929 - }
1.2930 -
1.2931 - Image image = null;
1.2932 -
1.2933 - // First check for Mac because its part of the Unix_Mask
1.2934 - if (isMac()) {
1.2935 - image = ImageUtilities.loadImage("org/openide/util/progress-cursor-mac.gif"); //NOI18N
1.2936 - } else if (isUnix()) {
1.2937 - image = ImageUtilities.loadImage("org/openide/util/progress-cursor-motif.gif"); //NOI18N
1.2938 - }
1.2939 - // All other OS, including Windows, use Windows cursor
1.2940 - else {
1.2941 - image = ImageUtilities.loadImage("org/openide/util/progress-cursor-win.gif"); //NOI18N
1.2942 - }
1.2943 -
1.2944 - return createCustomCursor(component, image, "PROGRESS_CURSOR"); //NOI18N
1.2945 - }
1.2946 -
1.2947 - // added to fix issue #30665 (bad size on linux)
1.2948 - public static Cursor createCustomCursor(Component component, Image icon, String name) {
1.2949 - Toolkit t = component.getToolkit();
1.2950 - Dimension d = t.getBestCursorSize(16, 16);
1.2951 - Image i = icon;
1.2952 -
1.2953 - if (d.width != icon.getWidth(null)) {
1.2954 - if (((d.width) == 0) && (d.height == 0)) {
1.2955 - // system doesn't support custom cursors, falling back
1.2956 - return Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
1.2957 - }
1.2958 -
1.2959 - // need to resize the icon
1.2960 - Image empty = ImageUtilities.createBufferedImage(d.width, d.height);
1.2961 - i = ImageUtilities.mergeImages(icon, empty, 0, 0);
1.2962 - }
1.2963 -
1.2964 - return t.createCustomCursor(i, new Point(1, 1), name);
1.2965 - }
1.2966 -
1.2967 - /** Attaches asynchronous init job to given component.
1.2968 - * {@link AsyncGUIJob#construct()} will be called after first
1.2969 - * paint, when paint event arrives. Later, {@link AsyncGUIJob#finished()}
1.2970 - * will be called according to the rules of the <code>AsyncGUIJob</code> interface.
1.2971 - *
1.2972 - * Useful for components that have slower initialization phase, component
1.2973 - * can benefit from more responsive behaviour during init.
1.2974 - *
1.2975 - * @param comp4Init Regular component in its pre-inited state, state in which
1.2976 - * component will be shown between first paint and init completion.
1.2977 - * @param initJob Initialization job to be called asynchronously. Job can
1.2978 - * optionally implement {@link Cancellable}
1.2979 - * interface for proper cancel logic. Cancel method will be called
1.2980 - * when component stops to be showing during job's progress.
1.2981 - * See {@link java.awt.Component#isShowing}
1.2982 - *
1.2983 - * @since 3.36
1.2984 - */
1.2985 - public static final void attachInitJob(Component comp4Init, AsyncGUIJob initJob) {
1.2986 - new AsyncInitSupport(comp4Init, initJob);
1.2987 - }
1.2988 -
1.2989 - /**
1.2990 - * Convert a file to a matching <code>file:</code> URL.
1.2991 - * @param f a file (absolute only)
1.2992 - * @return a URL using the <code>file</code> protocol
1.2993 - * @throws MalformedURLException for no good reason
1.2994 - * @see #toFile
1.2995 - * @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=29711">Issue #29711</a>
1.2996 - * @since 3.26
1.2997 - * @deprecated Use {@link File#toURI} and {@link URI#toURL} instead under JDK 1.4.
1.2998 - * ({@link File#toURL} is buggy in JDK 1.3 and the bugs are not fixed in JDK 1.4.)
1.2999 - */
1.3000 - @Deprecated
1.3001 - public static URL toURL(File f) throws MalformedURLException {
1.3002 - if (f == null) {
1.3003 - throw new NullPointerException();
1.3004 - }
1.3005 -
1.3006 - if (!f.isAbsolute()) {
1.3007 - throw new IllegalArgumentException("Relative path: " + f); // NOI18N
1.3008 - }
1.3009 -
1.3010 - URI uri = f.toURI();
1.3011 -
1.3012 - return uri.toURL();
1.3013 - }
1.3014 -
1.3015 - /**
1.3016 - * Convert a <code>file:</code> URL to a matching file.
1.3017 - * <p>You may not use a URL generated from a file on a different
1.3018 - * platform, as file name conventions may make the result meaningless
1.3019 - * or even unparsable.
1.3020 - * @param u a URL with the <code>file</code> protocol
1.3021 - * @return an absolute file it points to, or <code>null</code> if the URL
1.3022 - * does not seem to point to a file at all
1.3023 - * @see #toURL
1.3024 - * @see <a href="http://www.netbeans.org/issues/show_bug.cgi?id=29711">Issue #29711</a>
1.3025 - * @since 3.26
1.3026 - * @deprecated Use {@link URI#URI(String)} and {@link File#File(URI)} instead under JDK 1.4.
1.3027 - * (There was no proper equivalent under JDK 1.3.)
1.3028 - */
1.3029 - @Deprecated
1.3030 - public static File toFile(URL u) {
1.3031 - if (u == null) {
1.3032 - throw new NullPointerException();
1.3033 - }
1.3034 -
1.3035 - try {
1.3036 - URI uri = new URI(u.toExternalForm());
1.3037 -
1.3038 - return new File(uri);
1.3039 - } catch (URISyntaxException use) {
1.3040 - // malformed URL
1.3041 - return null;
1.3042 - } catch (IllegalArgumentException iae) {
1.3043 - // not a file: URL
1.3044 - return null;
1.3045 - }
1.3046 - }
1.3047 -
1.3048 - /** Interfaces for communication between Utilities.translate and regular
1.3049 - * expression impl.
1.3050 - *
1.3051 - * Order of methods is:
1.3052 - * readPair few times
1.3053 - * init once
1.3054 - * convert many times
1.3055 - */
1.3056 - static interface RE {
1.3057 - public void init(String[] original, String[] newversion);
1.3058 -
1.3059 - public String convert(String pattern);
1.3060 -
1.3061 - /** Parses line of text to two parts: the key and the rest
1.3062 - */
1.3063 - public String[] readPair(String line);
1.3064 - }
1.3065 -
1.3066 - /** Exception indicating that a given list could not be partially-ordered.
1.3067 - * @see #partialSort
1.3068 - * @deprecated Used only by the deprecated partialSort
1.3069 - */
1.3070 - @Deprecated
1.3071 - public static class UnorderableException extends RuntimeException {
1.3072 - static final long serialVersionUID = 6749951134051806661L;
1.3073 - private Collection unorderable;
1.3074 - private Map deps;
1.3075 -
1.3076 - /** Create a new unorderable-list exception with no detail message.
1.3077 - * @param unorderable a collection of list elements which could not be ordered
1.3078 - * (because there was some sort of cycle)
1.3079 - * @param deps dependencies associated with the list; a map from list elements
1.3080 - * to sets of list elements which that element must appear after
1.3081 - */
1.3082 - public UnorderableException(Collection unorderable, Map deps) {
1.3083 - super( /* "Cannot be ordered: " + unorderable */
1.3084 - ); // NOI18N
1.3085 - this.unorderable = unorderable;
1.3086 - this.deps = deps;
1.3087 - }
1.3088 -
1.3089 - /** Create a new unorderable-list exception with a specified detail message.
1.3090 - * @param message the detail message
1.3091 - * @param unorderable a collection of list elements which could not be ordered
1.3092 - * (because there was some sort of cycle)
1.3093 - * @param deps dependencies associated with the list; a map from list elements
1.3094 - * to sets of list elements which that element must appear after
1.3095 - */
1.3096 - public UnorderableException(String message, Collection unorderable, Map deps) {
1.3097 - super(message);
1.3098 - this.unorderable = unorderable;
1.3099 - this.deps = deps;
1.3100 - }
1.3101 -
1.3102 - /** Get the unorderable elements.
1.3103 - * @return the elements
1.3104 - * @see Utilities.UnorderableException#Utilities.UnorderableException(Collection,Map)
1.3105 - */
1.3106 - public Collection getUnorderable() {
1.3107 - return unorderable;
1.3108 - }
1.3109 -
1.3110 - /** Get the dependencies.
1.3111 - * @return the dependencies
1.3112 - * @see Utilities.UnorderableException#Utilities.UnorderableException(Collection,Map)
1.3113 - */
1.3114 - public Map getDeps() {
1.3115 - return deps;
1.3116 - }
1.3117 - }
1.3118 -}