KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > util > Utilities


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

19
20 package org.openide.util;
21
22 import java.awt.BorderLayout JavaDoc;
23 import java.awt.Component JavaDoc;
24 import java.awt.Container JavaDoc;
25 import java.awt.Cursor JavaDoc;
26 import java.awt.Dialog JavaDoc;
27 import java.awt.Dimension JavaDoc;
28 import java.awt.Frame JavaDoc;
29 import java.awt.Graphics JavaDoc;
30 import java.awt.GraphicsConfiguration JavaDoc;
31 import java.awt.GraphicsEnvironment JavaDoc;
32 import java.awt.Image JavaDoc;
33 import java.awt.Insets JavaDoc;
34 import java.awt.KeyboardFocusManager JavaDoc;
35 import java.awt.Point JavaDoc;
36 import java.awt.Rectangle JavaDoc;
37 import java.awt.Toolkit JavaDoc;
38 import java.awt.Window JavaDoc;
39 import java.awt.event.ActionEvent JavaDoc;
40 import java.awt.event.ActionListener JavaDoc;
41 import java.awt.event.KeyEvent JavaDoc;
42 import java.awt.image.BufferedImage JavaDoc;
43 import java.io.BufferedReader JavaDoc;
44 import java.io.File JavaDoc;
45 import java.io.IOException JavaDoc;
46 import java.io.InputStreamReader JavaDoc;
47 import java.lang.ref.Reference JavaDoc;
48 import java.lang.ref.ReferenceQueue JavaDoc;
49 import java.lang.ref.SoftReference JavaDoc;
50 import java.lang.reflect.Field JavaDoc;
51 import java.lang.reflect.Method JavaDoc;
52 import java.lang.reflect.Modifier JavaDoc;
53 import java.net.MalformedURLException JavaDoc;
54 import java.net.URI JavaDoc;
55 import java.net.URISyntaxException JavaDoc;
56 import java.net.URL JavaDoc;
57 import java.text.BreakIterator JavaDoc;
58 import java.util.ArrayList JavaDoc;
59 import java.util.Arrays JavaDoc;
60 import java.util.Collection JavaDoc;
61 import java.util.Collections JavaDoc;
62 import java.util.Comparator JavaDoc;
63 import java.util.Enumeration JavaDoc;
64 import java.util.HashMap JavaDoc;
65 import java.util.HashSet JavaDoc;
66 import java.util.Iterator JavaDoc;
67 import java.util.LinkedList JavaDoc;
68 import java.util.List JavaDoc;
69 import java.util.Locale JavaDoc;
70 import java.util.Map JavaDoc;
71 import java.util.NoSuchElementException JavaDoc;
72 import java.util.Set JavaDoc;
73 import java.util.StringTokenizer JavaDoc;
74 import java.util.TreeSet JavaDoc;
75 import java.util.Vector JavaDoc;
76 import java.util.logging.Level JavaDoc;
77 import java.util.logging.Logger JavaDoc;
78 import javax.swing.Action JavaDoc;
79 import javax.swing.Icon JavaDoc;
80 import javax.swing.ImageIcon JavaDoc;
81 import javax.swing.JLabel JavaDoc;
82 import javax.swing.JMenuItem JavaDoc;
83 import javax.swing.JPopupMenu JavaDoc;
84 import javax.swing.JSeparator JavaDoc;
85 import javax.swing.KeyStroke JavaDoc;
86 import javax.swing.SwingUtilities JavaDoc;
87 import javax.swing.Timer JavaDoc;
88 import org.netbeans.modules.openide.util.AWTBridge;
89 import org.openide.util.actions.Presenter;
90
91 /** Otherwise uncategorized useful static methods.
92 *
93 * @author Jan Palka, Ian Formanek, Jaroslav Tulach
94 */

95 public final class Utilities {
96     /** Operating system is Windows NT. */
97     public static final int OS_WINNT = 1 << 0;
98
99     /** Operating system is Windows 95. */
100     public static final int OS_WIN95 = OS_WINNT << 1;
101
102     /** Operating system is Windows 98. */
103     public static final int OS_WIN98 = OS_WIN95 << 1;
104
105     /** Operating system is Solaris. */
106     public static final int OS_SOLARIS = OS_WIN98 << 1;
107
108     /** Operating system is Linux. */
109     public static final int OS_LINUX = OS_SOLARIS << 1;
110
111     /** Operating system is HP-UX. */
112     public static final int OS_HP = OS_LINUX << 1;
113
114     /** Operating system is IBM AIX. */
115     public static final int OS_AIX = OS_HP << 1;
116
117     /** Operating system is SGI IRIX. */
118     public static final int OS_IRIX = OS_AIX << 1;
119
120     /** Operating system is Sun OS. */
121     public static final int OS_SUNOS = OS_IRIX << 1;
122
123     /** Operating system is Compaq TRU64 Unix */
124     public static final int OS_TRU64 = OS_SUNOS << 1;
125
126     /** @deprecated please use OS_TRU64 instead */
127     @Deprecated JavaDoc
128     public static final int OS_DEC = OS_TRU64 << 1;
129
130     /** Operating system is OS/2. */
131     public static final int OS_OS2 = OS_DEC << 1;
132
133     /** Operating system is Mac. */
134     public static final int OS_MAC = OS_OS2 << 1;
135
136     /** Operating system is Windows 2000. */
137     public static final int OS_WIN2000 = OS_MAC << 1;
138
139     /** Operating system is Compaq OpenVMS */
140     public static final int OS_VMS = OS_WIN2000 << 1;
141
142     /**
143      *Operating system is one of the Windows variants but we don't know which
144      *one it is
145      */

146     public static final int OS_WIN_OTHER = OS_VMS << 1;
147
148     /** Operating system is unknown. */
149     public static final int OS_OTHER = OS_WIN_OTHER << 1;
150
151     /** Operating system is FreeBSD
152      * @since 4.50
153      */

154     public static final int OS_FREEBSD = OS_OTHER << 1;
155
156     /** A mask for Windows platforms. */
157     public static final int OS_WINDOWS_MASK = OS_WINNT | OS_WIN95 | OS_WIN98 | OS_WIN2000 | OS_WIN_OTHER;
158
159     /** A mask for Unix platforms. */
160     public static final int OS_UNIX_MASK = OS_SOLARIS | OS_LINUX | OS_HP | OS_AIX | OS_IRIX | OS_SUNOS | OS_TRU64 |
161         OS_MAC | OS_FREEBSD;
162
163     /** A height of the windows's taskbar */
164     public static final int TYPICAL_WINDOWS_TASKBAR_HEIGHT = 27;
165
166     /** A height of the Mac OS X's menu */
167     private static final int TYPICAL_MACOSX_MENU_HEIGHT = 24;
168
169     private static ActiveQueue activeReferenceQueue;
170
171     /** reference to map that maps allowed key names to their values (String, Integer)
172     and reference to map for mapping of values to their names */

173     private static Reference JavaDoc<Object JavaDoc> namesAndValues;
174
175     /** The operating system on which NetBeans runs*/
176     private static int operatingSystem = -1;
177     private static final String JavaDoc[] keywords = new String JavaDoc[] {
178             
179             //If adding to this, insert in alphabetical order!
180
"abstract", "assert", "boolean", "break", "byte", "case", //NOI18N
181
"catch", "char", "class", "const", "continue", "default", //NOI18N
182
"do", "double", "else", "enum", "extends", "false", "final", //NOI18N
183
"finally", "float", "for", "goto", "if", "implements", //NOI18N
184
"import", "instanceof", "int", "interface", "long", //NOI18N
185
"native", "new", "null", "package", "private", //NOI18N
186
"protected", "public", "return", "short", "static", //NOI18N
187
"strictfp", "super", "switch", "synchronized", "this", //NOI18N
188
"throw", "throws", "transient", "true", "try", "void", //NOI18N
189
"volatile", "while" //NOI18N
190
};
191     private static Timer JavaDoc clearIntrospector;
192     private static ActionListener JavaDoc doClear;
193     private static final int CTRL_WILDCARD_MASK = 32768;
194     private static final int ALT_WILDCARD_MASK = CTRL_WILDCARD_MASK * 2;
195
196     // Package retranslation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
197
private static final String JavaDoc TRANS_LOCK = "TRANS_LOCK";
198
199     /** last used classloader or if run in test mode the TRANS_LOCK */
200     private static Object JavaDoc transLoader;
201
202     /** regular expression to with all changes */
203     private static RE transExp;
204
205     //
206
// Support for work with actions
207
//
208

209     /** type of Class or of an Exception thrown */
210     private static Object JavaDoc actionClassForPopupMenu;
211
212     /** the found actionsGlobalContext */
213     private static Lookup global;
214
215     private Utilities() {
216     }
217
218     /**
219      * Useful queue for all parts of system that use <code>java.lang.ref.Reference</code>s
220      * together with some <code>ReferenceQueue</code> and need to do some clean up
221      * when the reference is enqueued. Usually, in order to be notified about that, one
222      * needs to either create a dedicated thread that blocks on the queue and is
223      * <code>Object.notify</code>-ed, which is the right approach but consumes
224      * valuable system resources (threads) or one can periodically check the content
225      * of the queue by <code>RequestProcessor.Task.schedule</code> which is
226      * completely wrong, because it wakes up the system every (say) 15 seconds.
227      * In order to provide useful support for this problem, this queue has been
228      * provided.
229      * <P>
230      * If you have a reference that needs cleanup, make it implement <link>Runnable</link>
231      * and register it with the queue:
232      * <PRE>
233      * class MyReference extends WeakReference<Thing> implements Runnable {
234      * private final OtherInfo dataToCleanUp;
235      * public MyReference(Thing ref, OtherInfo data) {
236      * super(ref, Utilities.activeReferenceQueue());
237      * dataToCleanUp = data;
238      * }
239      * public void run() {
240      * dataToCleanUp.releaseOrWhateverYouNeed();
241      * }
242      * }
243      * </PRE>
244      * When the <code>ref</code> object is garbage collected, your run method
245      * will be invoked by calling
246      * <code>((Runnable) reference).run()</code>
247      * and you can perform whatever cleanup is necessary. Be sure not to block
248      * in such cleanup for a long time as this prevents other waiting references
249      * from cleaning themselves up.
250      * <P>
251      * Do not call any <code>ReferenceQueue</code> methods. They
252      * will throw exceptions. You may only enqueue a reference.
253      * <p>
254      * Be sure to call this method anew for each reference.
255      * Do not attempt to cache the return value.
256      * @since 3.11
257      */

258     public static synchronized ReferenceQueue JavaDoc<Object JavaDoc> activeReferenceQueue() {
259         if (activeReferenceQueue == null) {
260             activeReferenceQueue = new ActiveQueue(false);
261         }
262
263         activeReferenceQueue.ping();
264
265         return activeReferenceQueue;
266     }
267
268     /** Get the operating system on which NetBeans is running.
269     * @return one of the <code>OS_*</code> constants (such as {@link #OS_WINNT})
270     */

271     public static final int getOperatingSystem() {
272         if (operatingSystem == -1) {
273             String JavaDoc osName = System.getProperty("os.name");
274
275             if ("Windows NT".equals(osName)) { // NOI18N
276
operatingSystem = OS_WINNT;
277             } else if ("Windows 95".equals(osName)) { // NOI18N
278
operatingSystem = OS_WIN95;
279             } else if ("Windows 98".equals(osName)) { // NOI18N
280
operatingSystem = OS_WIN98;
281             } else if ("Windows 2000".equals(osName)) { // NOI18N
282
operatingSystem = OS_WIN2000;
283             } else if (osName.startsWith("Windows ")) { // NOI18N
284
operatingSystem = OS_WIN_OTHER;
285             } else if ("Solaris".equals(osName)) { // NOI18N
286
operatingSystem = OS_SOLARIS;
287             } else if (osName.startsWith("SunOS")) { // NOI18N
288
operatingSystem = OS_SOLARIS;
289             }
290             // JDK 1.4 b2 defines os.name for me as "Redhat Linux" -jglick
291
else if (osName.endsWith("Linux")) { // NOI18N
292
operatingSystem = OS_LINUX;
293             } else if ("HP-UX".equals(osName)) { // NOI18N
294
operatingSystem = OS_HP;
295             } else if ("AIX".equals(osName)) { // NOI18N
296
operatingSystem = OS_AIX;
297             } else if ("Irix".equals(osName)) { // NOI18N
298
operatingSystem = OS_IRIX;
299             } else if ("SunOS".equals(osName)) { // NOI18N
300
operatingSystem = OS_SUNOS;
301             } else if ("Digital UNIX".equals(osName)) { // NOI18N
302
operatingSystem = OS_TRU64;
303             } else if ("OS/2".equals(osName)) { // NOI18N
304
operatingSystem = OS_OS2;
305             } else if ("OpenVMS".equals(osName)) { // NOI18N
306
operatingSystem = OS_VMS;
307             } else if (osName.equals("Mac OS X")) { // NOI18N
308
operatingSystem = OS_MAC;
309             } else if (osName.startsWith("Darwin")) { // NOI18N
310
operatingSystem = OS_MAC;
311             } else if (osName.toLowerCase(Locale.US).startsWith("freebsd")) { // NOI18N
312
operatingSystem = OS_FREEBSD;
313             } else {
314                 operatingSystem = OS_OTHER;
315             }
316         }
317
318         return operatingSystem;
319     }
320
321     /** Test whether NetBeans is running on some variant of Windows.
322     * @return <code>true</code> if Windows, <code>false</code> if some other manner of operating system
323     */

324     public static final boolean isWindows() {
325         return (getOperatingSystem() & OS_WINDOWS_MASK) != 0;
326     }
327
328     /** Test whether NetBeans is running on MacOS.
329      * @since 7.7
330     * @return <code>true</code> if Mac, <code>false</code> if some other manner of operating system
331     */

332     public static final boolean isMac() {
333         return (getOperatingSystem() & OS_MAC) != 0;
334     }
335
336     /** Test whether NetBeans is running on some variant of Unix.
337     * Linux is included as well as the commercial vendors.
338     * @return <code>true</code> some sort of Unix, <code>false</code> if some other manner of operating system
339     */

340     public static final boolean isUnix() {
341         return (getOperatingSystem() & OS_UNIX_MASK) != 0;
342     }
343
344     // only for UtilitiesTest purposes
345
final static void resetOperatingSystem() {
346         operatingSystem = -1;
347     }
348
349     /** Test whether a given string is a valid Java identifier.
350     * @param id string which should be checked
351     * @return <code>true</code> if a valid identifier
352     */

353     public static final boolean isJavaIdentifier(String JavaDoc id) {
354         if (id == null) {
355             return false;
356         }
357
358         if (id.equals("")) {
359             return false;
360         }
361
362         if (!(java.lang.Character.isJavaIdentifierStart(id.charAt(0)))) {
363             return false;
364         }
365
366         for (int i = 1; i < id.length(); i++) {
367             if (!(java.lang.Character.isJavaIdentifierPart(id.charAt(i)))) {
368                 return false;
369             }
370         }
371
372         return Arrays.binarySearch(keywords, id) < 0;
373     }
374
375     /** Central method for obtaining <code>BeanInfo</code> for potential JavaBean classes.
376     * @param clazz class of the bean to provide the <code>BeanInfo</code> for
377     * @return the bean info
378     * @throws java.beans.IntrospectionException for the usual reasons
379     * @see java.beans.Introspector#getBeanInfo(Class)
380     */

381     public static java.beans.BeanInfo JavaDoc getBeanInfo(Class JavaDoc clazz)
382     throws java.beans.IntrospectionException JavaDoc {
383         java.beans.BeanInfo JavaDoc bi;
384
385         try {
386             bi = java.beans.Introspector.getBeanInfo(clazz);
387         } catch (java.beans.IntrospectionException JavaDoc ie) {
388             Exceptions.attachMessage(ie,
389                                      "Encountered while introspecting " +
390                                      clazz.getName()); // NOI18N
391
throw ie;
392         } catch (Error JavaDoc e) {
393             // Could be a bug in Introspector triggered by NB code.
394
Exceptions.attachMessage(e,
395                                      "Encountered while introspecting " +
396                                      clazz.getName()); // NOI18N
397
throw e;
398         }
399
400         if (java.awt.Component JavaDoc.class.isAssignableFrom(clazz)) {
401             java.beans.PropertyDescriptor JavaDoc[] pds = bi.getPropertyDescriptors();
402
403             for (int i = 0; i < pds.length; i++) {
404                 if (pds[i].getName().equals("cursor")) { // NOI18N
405

406                     try {
407                         Method JavaDoc getter = Component JavaDoc.class.getDeclaredMethod("getCursor", new Class JavaDoc[0]); // NOI18N
408
Method JavaDoc setter = Component JavaDoc.class.getDeclaredMethod("setCursor", new Class JavaDoc[] { Cursor JavaDoc.class }); // NOI18N
409
pds[i] = new java.beans.PropertyDescriptor JavaDoc("cursor", getter, setter); // NOI18N
410
} catch (NoSuchMethodException JavaDoc e) {
411                         e.printStackTrace();
412                     }
413
414                     break;
415                 }
416             }
417         }
418
419         // clears about 1000 instances of Method
420
if (bi != null) {
421             if (clearIntrospector == null) {
422                 doClear = new ActionListener JavaDoc() {
423                             public void actionPerformed(ActionEvent JavaDoc ev) {
424                                 java.beans.Introspector.flushCaches();
425                             }
426                         };
427                 clearIntrospector = new Timer JavaDoc(15000, doClear);
428                 clearIntrospector.setRepeats(false);
429             }
430
431             clearIntrospector.restart();
432         }
433
434         return bi;
435     }
436
437     /** Central method for obtaining <code>BeanInfo</code> for potential JavaBean classes, with a stop class.
438     * @param clazz class of the bean to provide the <code>BeanInfo</code> for
439     * @param stopClass the stop class
440     * @return the bean info
441     * @throws java.beans.IntrospectionException for the usual reasons
442     * @see java.beans.Introspector#getBeanInfo(Class, Class)
443     */

444     public static java.beans.BeanInfo JavaDoc getBeanInfo(Class JavaDoc clazz, Class JavaDoc stopClass)
445     throws java.beans.IntrospectionException JavaDoc {
446         return java.beans.Introspector.getBeanInfo(clazz, stopClass);
447     }
448
449     /** Wrap multi-line strings (and get the individual lines).
450     * @param original the original string to wrap
451     * @param width the maximum width of lines
452     * @param wrapWords if <code>true</code>, the lines are wrapped on word boundaries (if possible);
453     * if <code>false</code>, character boundaries are used
454     * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
455     * @return the lines after wrapping
456     * @deprecated use {@link #wrapStringToArray(String, int, BreakIterator, boolean)} since it is better for I18N
457     */

458     @Deprecated JavaDoc
459     public static String JavaDoc[] wrapStringToArray(String JavaDoc original, int width, boolean wrapWords, boolean removeNewLines) {
460         BreakIterator JavaDoc bi = (wrapWords ? BreakIterator.getWordInstance() : BreakIterator.getCharacterInstance());
461
462         return wrapStringToArray(original, width, bi, removeNewLines);
463     }
464
465     /** Wrap multi-line strings (and get the individual lines).
466     * @param original the original string to wrap
467     * @param width the maximum width of lines
468     * @param breakIterator breaks original to chars, words, sentences, depending on what instance you provide.
469     * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
470     * @return the lines after wrapping
471     */

472     public static String JavaDoc[] wrapStringToArray(
473         String JavaDoc original, int width, BreakIterator JavaDoc breakIterator, boolean removeNewLines
474     ) {
475         if (original.length() == 0) {
476             return new String JavaDoc[] { original };
477         }
478
479         String JavaDoc[] workingSet;
480
481         // substitute original newlines with spaces,
482
// remove newlines from head and tail
483
if (removeNewLines) {
484             original = trimString(original);
485             original = original.replace('\n', ' ');
486             workingSet = new String JavaDoc[] { original };
487         } else {
488             StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(original, "\n"); // NOI18N
489
int len = tokens.countTokens();
490             workingSet = new String JavaDoc[len];
491
492             for (int i = 0; i < len; i++) {
493                 workingSet[i] = tokens.nextToken();
494             }
495         }
496
497         if (width < 1) {
498             width = 1;
499         }
500
501         if (original.length() <= width) {
502             return workingSet;
503         }
504
505 widthcheck: {
506             boolean ok = true;
507
508             for (int i = 0; i < workingSet.length; i++) {
509                 ok = ok && (workingSet[i].length() < width);
510
511                 if (!ok) {
512                     break widthcheck;
513                 }
514             }
515
516             return workingSet;
517         }
518
519         java.util.ArrayList JavaDoc<String JavaDoc> lines = new java.util.ArrayList JavaDoc<String JavaDoc>();
520
521         int lineStart = 0; // the position of start of currently processed line in the original string
522

523         for (int i = 0; i < workingSet.length; i++) {
524             if (workingSet[i].length() < width) {
525                 lines.add(workingSet[i]);
526             } else {
527                 breakIterator.setText(workingSet[i]);
528
529                 int nextStart = breakIterator.next();
530                 int prevStart = 0;
531
532                 do {
533                     while (((nextStart - lineStart) < width) && (nextStart != BreakIterator.DONE)) {
534                         prevStart = nextStart;
535                         nextStart = breakIterator.next();
536                     }
537
538                     if (nextStart == BreakIterator.DONE) {
539                         nextStart = prevStart = workingSet[i].length();
540                     }
541
542                     if (prevStart == 0) {
543                         prevStart = nextStart;
544                     }
545
546                     lines.add(workingSet[i].substring(lineStart, prevStart));
547
548                     lineStart = prevStart;
549                     prevStart = 0;
550                 } while (lineStart < workingSet[i].length());
551
552                 lineStart = 0;
553             }
554         }
555
556         String JavaDoc[] s = new String JavaDoc[lines.size()];
557
558         return lines.toArray(s);
559     }
560
561     /** trims String
562     * @param s a String to trim
563     * @return trimmed String
564     */

565     private static String JavaDoc trimString(String JavaDoc s) {
566         int idx = 0;
567         char c;
568         final int slen = s.length();
569
570         if (slen == 0) {
571             return s;
572         }
573
574         do {
575             c = s.charAt(idx++);
576         } while (((c == '\n') || (c == '\r')) && (idx < slen));
577
578         s = s.substring(--idx);
579         idx = s.length() - 1;
580
581         if (idx < 0) {
582             return s;
583         }
584
585         do {
586             c = s.charAt(idx--);
587         } while (((c == '\n') || (c == '\r')) && (idx >= 0));
588
589         return s.substring(0, idx + 2);
590     }
591
592     /** Wrap multi-line strings.
593     * @param original the original string to wrap
594     * @param width the maximum width of lines
595     * @param breakIterator algorithm for breaking lines
596     * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
597     * @return the whole string with embedded newlines
598     */

599     public static String JavaDoc wrapString(String JavaDoc original, int width, BreakIterator JavaDoc breakIterator, boolean removeNewLines) {
600         String JavaDoc[] sarray = wrapStringToArray(original, width, breakIterator, removeNewLines);
601         StringBuffer JavaDoc retBuf = new StringBuffer JavaDoc();
602
603         for (int i = 0; i < sarray.length; i++) {
604             retBuf.append(sarray[i]);
605             retBuf.append('\n');
606         }
607
608         return retBuf.toString();
609     }
610
611     /** Wrap multi-line strings.
612     * @param original the original string to wrap
613     * @param width the maximum width of lines
614     * @param wrapWords if <code>true</code>, the lines are wrapped on word boundaries (if possible);
615     * if <code>false</code>, character boundaries are used
616     * @param removeNewLines if <code>true</code>, any newlines in the original string are ignored
617     * @return the whole string with embedded newlines
618     * @deprecated Use {@link #wrapString (String, int, BreakIterator, boolean)} as it is friendlier to I18N.
619     */

620     @Deprecated JavaDoc
621     public static String JavaDoc wrapString(String JavaDoc original, int width, boolean wrapWords, boolean removeNewLines) {
622         // substitute original newlines with spaces,
623
// remove newlines from head and tail
624
if (removeNewLines) {
625             while (original.startsWith("\n")) // NOI18N
626

627                 original = original.substring(1);
628
629             while (original.endsWith("\n")) // NOI18N
630

631                 original = original.substring(0, original.length() - 1);
632
633             original = original.replace('\n', ' ');
634         }
635
636         if (width < 1) {
637             width = 1;
638         }
639
640         if (original.length() <= width) {
641             return original;
642         }
643
644         java.util.Vector JavaDoc<String JavaDoc> lines = new java.util.Vector JavaDoc<String JavaDoc>();
645         int lineStart = 0; // the position of start of currently processed line in the original string
646
int lastSpacePos = -1;
647
648         for (int i = 0; i < original.length(); i++) {
649             if (lineStart >= (original.length() - 1)) {
650                 break;
651             }
652
653             // newline in the original string
654
if (original.charAt(i) == '\n') {
655                 lines.addElement(original.substring(lineStart, i));
656                 lineStart = i + 1;
657                 lastSpacePos = -1;
658
659                 continue;
660             }
661
662             // remember last space position
663
if (Character.isSpaceChar(original.charAt(i))) {
664                 lastSpacePos = i;
665             }
666
667             // last position in the original string
668
if (i == (original.length() - 1)) {
669                 lines.addElement(original.substring(lineStart));
670
671                 break;
672             }
673
674             // reached width
675
if ((i - lineStart) == width) {
676                 if (wrapWords && (lastSpacePos != -1)) {
677                     lines.addElement(original.substring(lineStart, lastSpacePos));
678                     lineStart = lastSpacePos + 1; // the space is consumed for the newline
679
lastSpacePos = -1;
680                 } else {
681                     lines.addElement(original.substring(lineStart, i));
682                     lineStart = i;
683                     lastSpacePos = -1;
684                 }
685             }
686         }
687
688         StringBuffer JavaDoc retBuf = new StringBuffer JavaDoc();
689
690         for (java.util.Enumeration JavaDoc e = lines.elements(); e.hasMoreElements();) {
691             retBuf.append((String JavaDoc) e.nextElement());
692             retBuf.append('\n');
693         }
694
695         return retBuf.toString();
696     }
697
698     /** Search-and-replace fixed string matches within a string.
699     * @param original the original string
700     * @param replaceFrom the substring to be find
701     * @param replaceTo the substring to replace it with
702     * @return a new string with all occurrences replaced
703     */

704     public static String JavaDoc replaceString(String JavaDoc original, String JavaDoc replaceFrom, String JavaDoc replaceTo) {
705         int index = 0;
706
707         if ("".equals(replaceFrom)) {
708             return original; // NOI18N
709
}
710
711         StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
712
713         while (true) {
714             int pos = original.indexOf(replaceFrom, index);
715
716             if (pos == -1) {
717                 buf.append(original.substring(index));
718
719                 return buf.toString();
720             }
721
722             buf.append(original.substring(index, pos));
723             buf.append(replaceTo);
724             index = pos + replaceFrom.length();
725
726             if (index == original.length()) {
727                 return buf.toString();
728             }
729         }
730     }
731
732     /** Turn full name of an inner class into its pure form.
733     * @param fullName e.g. <code>some.pkg.SomeClass$Inner</code>
734     * @return e.g. <code>Inner</code>
735     */

736     public static final String JavaDoc pureClassName(final String JavaDoc fullName) {
737         final int index = fullName.indexOf('$');
738
739         if ((index >= 0) && (index < fullName.length())) {
740             return fullName.substring(index + 1, fullName.length());
741         }
742
743         return fullName;
744     }
745
746     /** Test whether the operating system supports icons on frames (windows).
747     * @return <code>true</code> if it does <em>not</em>
748     *
749     */

750     public static final boolean isLargeFrameIcons() {
751         return (getOperatingSystem() == OS_SOLARIS) || (getOperatingSystem() == OS_HP);
752     }
753
754     /** Compute hash code of array.
755     * Asks all elements for their own code and composes the
756     * values.
757     * @param arr array of objects, can contain <code>null</code>s
758     * @return the hash code
759     * @see Object#hashCode
760     */

761     public static int arrayHashCode(Object JavaDoc[] arr) {
762         int c = 0;
763         int len = arr.length;
764
765         for (int i = 0; i < len; i++) {
766             Object JavaDoc o = arr[i];
767             int v = (o == null) ? 1 : o.hashCode();
768             c += (v ^ i);
769         }
770
771         return c;
772     }
773
774     /** Safe equality check.
775     * The supplied objects are equal if: <UL>
776     * <LI> both are <code>null</code>
777     * <LI> both are arrays with same length and equal items (if the items are arrays,
778     * they are <em>not</em> checked the same way again)
779     * <LI> the two objects are {@link Object#equals}
780     * </UL>
781     * This method is <code>null</code>-safe, so if one of the parameters is true and the second not,
782     * it returns <code>false</code>.
783     * @param o1 the first object to compare
784     * @param o2 the second object to compare
785     * @return <code>true</code> if the objects are equal
786     */

787     public static boolean compareObjects(Object JavaDoc o1, Object JavaDoc o2) {
788         return compareObjectsImpl(o1, o2, 1);
789     }
790
791     /** Safe equality check with array recursion.
792     * @param o1 the first object to compare
793     * @param o2 the second object to compare
794     * @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.)
795     * @return <code>true</code> if the objects are equal
796     * @see #compareObjects(Object, Object)
797     */

798     public static boolean compareObjectsImpl(Object JavaDoc o1, Object JavaDoc o2, int checkArraysDepth) {
799         // handle null values
800
if (o1 == null) {
801             return (o2 == null);
802         } else if (o2 == null) {
803             return false;
804         }
805
806         // handle arrays
807
if (checkArraysDepth > 0) {
808             if ((o1 instanceof Object JavaDoc[]) && (o2 instanceof Object JavaDoc[])) {
809                 // Note: also handles multidimensional arrays of primitive types correctly.
810
// I.e. new int[0][] instanceof Object[]
811
Object JavaDoc[] o1a = (Object JavaDoc[]) o1;
812                 Object JavaDoc[] o2a = (Object JavaDoc[]) o2;
813                 int l1 = o1a.length;
814                 int l2 = o2a.length;
815
816                 if (l1 != l2) {
817                     return false;
818                 }
819
820                 for (int i = 0; i < l1; i++) {
821                     if (!compareObjectsImpl(o1a[i], o2a[i], checkArraysDepth - 1)) {
822                         return false;
823                     }
824                 }
825
826                 return true;
827             } else if ((o1 instanceof byte[]) && (o2 instanceof byte[])) {
828                 byte[] o1a = (byte[]) o1;
829                 byte[] o2a = (byte[]) o2;
830                 int l1 = o1a.length;
831                 int l2 = o2a.length;
832
833                 if (l1 != l2) {
834                     return false;
835                 }
836
837                 for (int i = 0; i < l1; i++)
838                     if (o1a[i] != o2a[i]) {
839                         return false;
840                     }
841
842                 return true;
843             } else if ((o1 instanceof short[]) && (o2 instanceof short[])) {
844                 short[] o1a = (short[]) o1;
845                 short[] o2a = (short[]) o2;
846                 int l1 = o1a.length;
847                 int l2 = o2a.length;
848
849                 if (l1 != l2) {
850                     return false;
851                 }
852
853                 for (int i = 0; i < l1; i++)
854                     if (o1a[i] != o2a[i]) {
855                         return false;
856                     }
857
858                 return true;
859             } else if ((o1 instanceof int[]) && (o2 instanceof int[])) {
860                 int[] o1a = (int[]) o1;
861                 int[] o2a = (int[]) o2;
862                 int l1 = o1a.length;
863                 int l2 = o2a.length;
864
865                 if (l1 != l2) {
866                     return false;
867                 }
868
869                 for (int i = 0; i < l1; i++)
870                     if (o1a[i] != o2a[i]) {
871                         return false;
872                     }
873
874                 return true;
875             } else if ((o1 instanceof long[]) && (o2 instanceof long[])) {
876                 long[] o1a = (long[]) o1;
877                 long[] o2a = (long[]) o2;
878                 int l1 = o1a.length;
879                 int l2 = o2a.length;
880
881                 if (l1 != l2) {
882                     return false;
883                 }
884
885                 for (int i = 0; i < l1; i++)
886                     if (o1a[i] != o2a[i]) {
887                         return false;
888                     }
889
890                 return true;
891             } else if ((o1 instanceof float[]) && (o2 instanceof float[])) {
892                 float[] o1a = (float[]) o1;
893                 float[] o2a = (float[]) o2;
894                 int l1 = o1a.length;
895                 int l2 = o2a.length;
896
897                 if (l1 != l2) {
898                     return false;
899                 }
900
901                 for (int i = 0; i < l1; i++)
902                     if (o1a[i] != o2a[i]) {
903                         return false;
904                     }
905
906                 return true;
907             } else if ((o1 instanceof double[]) && (o2 instanceof double[])) {
908                 double[] o1a = (double[]) o1;
909                 double[] o2a = (double[]) o2;
910                 int l1 = o1a.length;
911                 int l2 = o2a.length;
912
913                 if (l1 != l2) {
914                     return false;
915                 }
916
917                 for (int i = 0; i < l1; i++)
918                     if (o1a[i] != o2a[i]) {
919                         return false;
920                     }
921
922                 return true;
923             } else if ((o1 instanceof char[]) && (o2 instanceof char[])) {
924                 char[] o1a = (char[]) o1;
925                 char[] o2a = (char[]) o2;
926                 int l1 = o1a.length;
927                 int l2 = o2a.length;
928
929                 if (l1 != l2) {
930                     return false;
931                 }
932
933                 for (int i = 0; i < l1; i++)
934                     if (o1a[i] != o2a[i]) {
935                         return false;
936                     }
937
938                 return true;
939             } else if ((o1 instanceof boolean[]) && (o2 instanceof boolean[])) {
940                 boolean[] o1a = (boolean[]) o1;
941                 boolean[] o2a = (boolean[]) o2;
942                 int l1 = o1a.length;
943                 int l2 = o2a.length;
944
945                 if (l1 != l2) {
946                     return false;
947                 }
948
949                 for (int i = 0; i < l1; i++)
950                     if (o1a[i] != o2a[i]) {
951                         return false;
952                     }
953
954                 return true;
955             }
956
957             // else not array type
958
}
959
960         // handle common objects--non-arrays, or arrays when depth == 0
961
return o1.equals(o2);
962     }
963
964     /** Assemble a human-presentable class name for a specified class.
965     * Arrays are represented as e.g. <code>java.lang.String[]</code>.
966     * @param clazz the class to name
967     * @return the human-presentable name
968     */

969     public static String JavaDoc getClassName(Class JavaDoc clazz) {
970         // if it is an array, get short name of element type and append []
971
if (clazz.isArray()) {
972             return getClassName(clazz.getComponentType()) + "[]"; // NOI18N
973
} else {
974             return clazz.getName();
975         }
976     }
977
978     /** Assemble a human-presentable class name for a specified class (omitting the package).
979     * Arrays are represented as e.g. <code>String[]</code>.
980     * @param clazz the class to name
981     * @return the human-presentable name
982     */

983     public static String JavaDoc getShortClassName(Class JavaDoc clazz) {
984         // if it is an array, get short name of element type and append []
985
if (clazz.isArray()) {
986             return getShortClassName(clazz.getComponentType()) + "[]"; // NOI18N
987
}
988
989         String JavaDoc name = clazz.getName().replace('$', '.');
990
991         return name.substring(name.lastIndexOf(".") + 1, name.length()); // NOI18N
992
}
993
994     /**
995     * Convert an array of objects to an array of primitive types.
996     * E.g. an <code>Integer[]</code> would be changed to an <code>int[]</code>.
997     * @param array the wrapper array
998     * @return a primitive array
999     * @throws IllegalArgumentException if the array element type is not a primitive wrapper
1000    */

1001    public static Object JavaDoc toPrimitiveArray(Object JavaDoc[] array) {
1002        if (array instanceof Integer JavaDoc[]) {
1003            int[] r = new int[array.length];
1004            int i;
1005            int k = array.length;
1006
1007            for (i = 0; i < k; i++)
1008                r[i] = (((Integer JavaDoc) array[i]) == null) ? 0 : ((Integer JavaDoc) array[i]).intValue();
1009
1010            return r;
1011        }
1012
1013        if (array instanceof Boolean JavaDoc[]) {
1014            boolean[] r = new boolean[array.length];
1015            int i;
1016            int k = array.length;
1017
1018            for (i = 0; i < k; i++)
1019                r[i] = (((Boolean JavaDoc) array[i]) == null) ? false : ((Boolean JavaDoc) array[i]).booleanValue();
1020
1021            return r;
1022        }
1023
1024        if (array instanceof Byte JavaDoc[]) {
1025            byte[] r = new byte[array.length];
1026            int i;
1027            int k = array.length;
1028
1029            for (i = 0; i < k; i++)
1030                r[i] = (((Byte JavaDoc) array[i]) == null) ? 0 : ((Byte JavaDoc) array[i]).byteValue();
1031
1032            return r;
1033        }
1034
1035        if (array instanceof Character JavaDoc[]) {
1036            char[] r = new char[array.length];
1037            int i;
1038            int k = array.length;
1039
1040            for (i = 0; i < k; i++)
1041                r[i] = (((Character JavaDoc) array[i]) == null) ? 0 : ((Character JavaDoc) array[i]).charValue();
1042
1043            return r;
1044        }
1045
1046        if (array instanceof Double JavaDoc[]) {
1047            double[] r = new double[array.length];
1048            int i;
1049            int k = array.length;
1050
1051            for (i = 0; i < k; i++)
1052                r[i] = (((Double JavaDoc) array[i]) == null) ? 0 : ((Double JavaDoc) array[i]).doubleValue();
1053
1054            return r;
1055        }
1056
1057        if (array instanceof Float JavaDoc[]) {
1058            float[] r = new float[array.length];
1059            int i;
1060            int k = array.length;
1061
1062            for (i = 0; i < k; i++)
1063                r[i] = (((Float JavaDoc) array[i]) == null) ? 0 : ((Float JavaDoc) array[i]).floatValue();
1064
1065            return r;
1066        }
1067
1068        if (array instanceof Long JavaDoc[]) {
1069            long[] r = new long[array.length];
1070            int i;
1071            int k = array.length;
1072
1073            for (i = 0; i < k; i++)
1074                r[i] = (((Long JavaDoc) array[i]) == null) ? 0 : ((Long JavaDoc) array[i]).longValue();
1075
1076            return r;
1077        }
1078
1079        if (array instanceof Short JavaDoc[]) {
1080            short[] r = new short[array.length];
1081            int i;
1082            int k = array.length;
1083
1084            for (i = 0; i < k; i++)
1085                r[i] = (((Short JavaDoc) array[i]) == null) ? 0 : ((Short JavaDoc) array[i]).shortValue();
1086
1087            return r;
1088        }
1089
1090        throw new IllegalArgumentException JavaDoc();
1091    }
1092
1093    /**
1094    * Convert an array of primitive types to an array of objects.
1095    * E.g. an <code>int[]</code> would be turned into an <code>Integer[]</code>.
1096    * @param array the primitive array
1097    * @return a wrapper array
1098    * @throws IllegalArgumentException if the array element type is not primitive
1099    */

1100    public static Object JavaDoc[] toObjectArray(Object JavaDoc array) {
1101        if (array instanceof Object JavaDoc[]) {
1102            return (Object JavaDoc[]) array;
1103        }
1104
1105        if (array instanceof int[]) {
1106            int i;
1107            int k = ((int[]) array).length;
1108            Integer JavaDoc[] r = new Integer JavaDoc[k];
1109
1110            for (i = 0; i < k; i++)
1111                r[i] = new Integer JavaDoc(((int[]) array)[i]);
1112
1113            return r;
1114        }
1115
1116        if (array instanceof boolean[]) {
1117            int i;
1118            int k = ((boolean[]) array).length;
1119            Boolean JavaDoc[] r = new Boolean JavaDoc[k];
1120
1121            for (i = 0; i < k; i++)
1122                r[i] = ((boolean[]) array)[i] ? Boolean.TRUE : Boolean.FALSE;
1123
1124            return r;
1125        }
1126
1127        if (array instanceof byte[]) {
1128            int i;
1129            int k = ((byte[]) array).length;
1130            Byte JavaDoc[] r = new Byte JavaDoc[k];
1131
1132            for (i = 0; i < k; i++)
1133                r[i] = new Byte JavaDoc(((byte[]) array)[i]);
1134
1135            return r;
1136        }
1137
1138        if (array instanceof char[]) {
1139            int i;
1140            int k = ((char[]) array).length;
1141            Character JavaDoc[] r = new Character JavaDoc[k];
1142
1143            for (i = 0; i < k; i++)
1144                r[i] = new Character JavaDoc(((char[]) array)[i]);
1145
1146            return r;
1147        }
1148
1149        if (array instanceof double[]) {
1150            int i;
1151            int k = ((double[]) array).length;
1152            Double JavaDoc[] r = new Double JavaDoc[k];
1153
1154            for (i = 0; i < k; i++)
1155                r[i] = new Double JavaDoc(((double[]) array)[i]);
1156
1157            return r;
1158        }
1159
1160        if (array instanceof float[]) {
1161            int i;
1162            int k = ((float[]) array).length;
1163            Float JavaDoc[] r = new Float JavaDoc[k];
1164
1165            for (i = 0; i < k; i++)
1166                r[i] = new Float JavaDoc(((float[]) array)[i]);
1167
1168            return r;
1169        }
1170
1171        if (array instanceof long[]) {
1172            int i;
1173            int k = ((long[]) array).length;
1174            Long JavaDoc[] r = new Long JavaDoc[k];
1175
1176            for (i = 0; i < k; i++)
1177                r[i] = new Long JavaDoc(((long[]) array)[i]);
1178
1179            return r;
1180        }
1181
1182        if (array instanceof short[]) {
1183            int i;
1184            int k = ((short[]) array).length;
1185            Short JavaDoc[] r = new Short JavaDoc[k];
1186
1187            for (i = 0; i < k; i++)
1188                r[i] = new Short JavaDoc(((short[]) array)[i]);
1189
1190            return r;
1191        }
1192
1193        throw new IllegalArgumentException JavaDoc();
1194    }
1195
1196    /**
1197    * Get the object type for given primitive type.
1198    *
1199    * @param c primitive type (e.g. <code>int</code>)
1200    * @return object type (e.g. <code>Integer</code>)
1201    */

1202    public static Class JavaDoc getObjectType(Class JavaDoc c) {
1203        if (!c.isPrimitive()) {
1204            return c;
1205        }
1206
1207        if (c == Integer.TYPE) {
1208            return Integer JavaDoc.class;
1209        }
1210
1211        if (c == Boolean.TYPE) {
1212            return Boolean JavaDoc.class;
1213        }
1214
1215        if (c == Byte.TYPE) {
1216            return Byte JavaDoc.class;
1217        }
1218
1219        if (c == Character.TYPE) {
1220            return Character JavaDoc.class;
1221        }
1222
1223        if (c == Double.TYPE) {
1224            return Double JavaDoc.class;
1225        }
1226
1227        if (c == Float.TYPE) {
1228            return Float JavaDoc.class;
1229        }
1230
1231        if (c == Long.TYPE) {
1232            return Long JavaDoc.class;
1233        }
1234
1235        if (c == Short.TYPE) {
1236            return Short JavaDoc.class;
1237        }
1238
1239        throw new IllegalArgumentException JavaDoc();
1240    }
1241
1242    /**
1243    * Get the primitive type for given object type.
1244    *
1245    * @param c object type (e.g. <code>Integer</code>)
1246    * @return primitive type (e.g. <code>int</code>)
1247    */

1248    public static Class JavaDoc getPrimitiveType(Class JavaDoc c) {
1249        if (!c.isPrimitive()) {
1250            return c;
1251        }
1252
1253        if (c == Integer JavaDoc.class) {
1254            return Integer.TYPE;
1255        }
1256
1257        if (c == Boolean JavaDoc.class) {
1258            return Boolean.TYPE;
1259        }
1260
1261        if (c == Byte JavaDoc.class) {
1262            return Byte.TYPE;
1263        }
1264
1265        if (c == Character JavaDoc.class) {
1266            return Character.TYPE;
1267        }
1268
1269        if (c == Double JavaDoc.class) {
1270            return Double.TYPE;
1271        }
1272
1273        if (c == Float JavaDoc.class) {
1274            return Float.TYPE;
1275        }
1276
1277        if (c == Long JavaDoc.class) {
1278            return Long.TYPE;
1279        }
1280
1281        if (c == Short JavaDoc.class) {
1282            return Short.TYPE;
1283        }
1284
1285        throw new IllegalArgumentException JavaDoc();
1286    }
1287
1288    /** Find a focus-traverable component.
1289    * @param c the component to look in
1290    * @return the same component if traversable, else a child component if present, else <code>null</code>
1291    * @see Component#isFocusTraversable
1292    */

1293    public static Component JavaDoc getFocusTraversableComponent(Component JavaDoc c) {
1294        if (c.isFocusable()) {
1295            return c;
1296        }
1297
1298        if (!(c instanceof Container JavaDoc)) {
1299            return null;
1300        }
1301
1302        int i;
1303        int k = ((Container JavaDoc) c).getComponentCount();
1304
1305        for (i = 0; i < k; i++) {
1306            Component JavaDoc v = ((Container JavaDoc) c).getComponent(i);
1307
1308            if (v != null) {
1309                return v;
1310            }
1311        }
1312
1313        return null;
1314    }
1315
1316    /** Parses parameters from a given string in shell-like manner.
1317    * Users of the Bourne shell (e.g. on Unix) will already be familiar with the behavior.
1318    * For example, when using <code>org.openide.execution.NbProcessDescriptor</code> (Execution API)
1319    * you should be able to:
1320    * <ul>
1321    * <li>Include command names with embedded spaces, such as <code>c:\Program Files\jdk\bin\javac</code>.
1322    * <li>Include extra command arguments, such as <code>-Dname=value</code>.
1323    * <li>Do anything else which might require unusual characters or processing. For example:
1324    * <p><code><pre>
1325    * "c:\program files\jdk\bin\java" -Dmessage="Hello /\\/\\ there!" -Xmx128m
1326    * </pre></code>
1327    * <p>This example would create the following executable name and arguments:
1328    * <ol>
1329    * <li> <code>c:\program files\jdk\bin\java</code>
1330    * <li> <code>-Dmessage=Hello /\/\ there!</code>
1331    * <li> <code>-Xmx128m</code>
1332    * </ol>
1333    * Note that the command string does not escape its backslashes--under the assumption
1334    * that Windows users will not think to do this, meaningless escapes are just left
1335    * as backslashes plus following character.
1336    * </ul>
1337    * <em>Caveat</em>: even after parsing, Windows programs (such as the Java launcher)
1338    * may not fully honor certain
1339    * characters, such as quotes, in command names or arguments. This is because programs
1340    * under Windows frequently perform their own parsing and unescaping (since the shell
1341    * cannot be relied on to do this). On Unix, this problem should not occur.
1342    * @param s a string to parse
1343    * @return an array of parameters
1344    */

1345    public static String JavaDoc[] parseParameters(String JavaDoc s) {
1346        int NULL = 0x0; // STICK + whitespace or NULL + non_"
1347
int INPARAM = 0x1; // NULL + " or STICK + " or INPARAMPENDING + "\ // NOI18N
1348
int INPARAMPENDING = 0x2; // INPARAM + \
1349
int STICK = 0x4; // INPARAM + " or STICK + non_" // NOI18N
1350
int STICKPENDING = 0x8; // STICK + \
1351
Vector JavaDoc<String JavaDoc> params = new Vector JavaDoc<String JavaDoc>(5, 5);
1352        char c;
1353
1354        int state = NULL;
1355        StringBuffer JavaDoc buff = new StringBuffer JavaDoc(20);
1356        int slength = s.length();
1357
1358        for (int i = 0; i < slength; i++) {
1359            c = s.charAt(i);
1360
1361            if (Character.isWhitespace(c)) {
1362                if (state == NULL) {
1363                    if (buff.length() > 0) {
1364                        params.addElement(buff.toString());
1365                        buff.setLength(0);
1366                    }
1367                } else if (state == STICK) {
1368                    params.addElement(buff.toString());
1369                    buff.setLength(0);
1370                    state = NULL;
1371                } else if (state == STICKPENDING) {
1372                    buff.append('\\');
1373                    params.addElement(buff.toString());
1374                    buff.setLength(0);
1375                    state = NULL;
1376                } else if (state == INPARAMPENDING) {
1377                    state = INPARAM;
1378                    buff.append('\\');
1379                    buff.append(c);
1380                } else { // INPARAM
1381
buff.append(c);
1382                }
1383
1384                continue;
1385            }
1386
1387            if (c == '\\') {
1388                if (state == NULL) {
1389                    ++i;
1390
1391                    if (i < slength) {
1392                        char cc = s.charAt(i);
1393
1394                        if ((cc == '"') || (cc == '\\')) {
1395                            buff.append(cc);
1396                        } else if (Character.isWhitespace(cc)) {
1397                            buff.append(c);
1398                            --i;
1399                        } else {
1400                            buff.append(c);
1401                            buff.append(cc);
1402                        }
1403                    } else {
1404                        buff.append('\\');
1405
1406                        break;
1407                    }
1408
1409                    continue;
1410                } else if (state == INPARAM) {
1411                    state = INPARAMPENDING;
1412                } else if (state == INPARAMPENDING) {
1413                    buff.append('\\');
1414                    state = INPARAM;
1415                } else if (state == STICK) {
1416                    state = STICKPENDING;
1417                } else if (state == STICKPENDING) {
1418                    buff.append('\\');
1419                    state = STICK;
1420                }
1421
1422                continue;
1423            }
1424
1425            if (c == '"') {
1426                if (state == NULL) {
1427                    state = INPARAM;
1428                } else if (state == INPARAM) {
1429                    state = STICK;
1430                } else if (state == STICK) {
1431                    state = INPARAM;
1432                } else if (state == STICKPENDING) {
1433                    buff.append('"');
1434                    state = STICK;
1435                } else { // INPARAMPENDING
1436
buff.append('"');
1437                    state = INPARAM;
1438                }
1439
1440                continue;
1441            }
1442
1443            if (state == INPARAMPENDING) {
1444                buff.append('\\');
1445                state = INPARAM;
1446            } else if (state == STICKPENDING) {
1447                buff.append('\\');
1448                state = STICK;
1449            }
1450
1451            buff.append(c);
1452        }
1453
1454        // collect
1455
if (state == INPARAM) {
1456            params.addElement(buff.toString());
1457        } else if ((state & (INPARAMPENDING | STICKPENDING)) != 0) {
1458            buff.append('\\');
1459            params.addElement(buff.toString());
1460        } else { // NULL or STICK
1461

1462            if (buff.length() != 0) {
1463                params.addElement(buff.toString());
1464            }
1465        }
1466
1467        String JavaDoc[] ret = new String JavaDoc[params.size()];
1468        params.copyInto(ret);
1469
1470        return ret;
1471    }
1472
1473    /** Complementary method to parseParameters
1474     * @see #parseParameters
1475     */

1476    public static String JavaDoc escapeParameters(String JavaDoc[] params) {
1477        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1478
1479        for (int i = 0; i < params.length; i++) {
1480            escapeString(params[i], sb);
1481            sb.append(' ');
1482        }
1483
1484        final int len = sb.length();
1485
1486        if (len > 0) {
1487            sb.setLength(len - 1);
1488        }
1489
1490        return sb.toString().trim();
1491    }
1492
1493    /** Escapes one string
1494     * @see #escapeParameters
1495     */

1496    private static void escapeString(String JavaDoc s, StringBuffer JavaDoc sb) {
1497        if (s.length() == 0) {
1498            sb.append("\"\"");
1499
1500            return;
1501        }
1502
1503        boolean hasSpace = false;
1504        final int sz = sb.length();
1505        final int slen = s.length();
1506        char c;
1507
1508        for (int i = 0; i < slen; i++) {
1509            c = s.charAt(i);
1510
1511            if (Character.isWhitespace(c)) {
1512                hasSpace = true;
1513                sb.append(c);
1514
1515                continue;
1516            }
1517
1518            if (c == '\\') {
1519                sb.append('\\').append('\\');
1520
1521                continue;
1522            }
1523
1524            if (c == '"') {
1525                sb.append('\\').append('"');
1526
1527                continue;
1528            }
1529
1530            sb.append(c);
1531        }
1532
1533        if (hasSpace) {
1534            sb.insert(sz, '"');
1535            sb.append('"');
1536        }
1537    }
1538
1539    //
1540
// Key conversions
1541
//
1542

1543    /** Initialization of the names and values
1544    * @return array of two hashmaps first maps
1545    * allowed key names to their values (String, Integer)
1546    * and second
1547    * hashtable for mapping of values to their names (Integer, String)
1548    */

1549    private static synchronized HashMap JavaDoc[] initNameAndValues() {
1550        if (namesAndValues != null) {
1551            HashMap JavaDoc[] arr = (HashMap JavaDoc[]) namesAndValues.get();
1552
1553            if (arr != null) {
1554                return arr;
1555            }
1556        }
1557
1558        Field JavaDoc[] fields = KeyEvent JavaDoc.class.getDeclaredFields();
1559
1560        HashMap JavaDoc<String JavaDoc,Integer JavaDoc> names = new HashMap JavaDoc<String JavaDoc,Integer JavaDoc>(((fields.length * 4) / 3) + 5, 0.75f);
1561        HashMap JavaDoc<Integer JavaDoc,String JavaDoc> values = new HashMap JavaDoc<Integer JavaDoc,String JavaDoc>(((fields.length * 4) / 3) + 5, 0.75f);
1562
1563        for (int i = 0; i < fields.length; i++) {
1564            if (Modifier.isStatic(fields[i].getModifiers())) {
1565                String JavaDoc name = fields[i].getName();
1566
1567                if (name.startsWith("VK_")) { // NOI18N
1568

1569                    // exclude VK
1570
name = name.substring(3);
1571
1572                    try {
1573                        int numb = fields[i].getInt(null);
1574                        Integer JavaDoc value = new Integer JavaDoc(numb);
1575                        names.put(name, value);
1576                        values.put(value, name);
1577                    } catch (IllegalArgumentException JavaDoc ex) {
1578                    } catch (IllegalAccessException JavaDoc ex) {
1579                    }
1580                }
1581            }
1582        }
1583
1584        if (names.get("CONTEXT_MENU") == null) { // NOI18N
1585

1586            Integer JavaDoc n = new Integer JavaDoc(0x20C);
1587            names.put("CONTEXT_MENU", n); // NOI18N
1588
values.put(n, "CONTEXT_MENU"); // NOI18N
1589

1590            n = new Integer JavaDoc(0x20D);
1591            names.put("WINDOWS", n); // NOI18N
1592
values.put(n, "WINDOWS"); // NOI18N
1593
}
1594
1595        HashMap JavaDoc[] arr = { names, values };
1596
1597        namesAndValues = new SoftReference JavaDoc<Object JavaDoc>(arr);
1598
1599        return arr;
1600    }
1601
1602    /** Converts a Swing key stroke descriptor to a familiar Emacs-like name.
1603    * @param stroke key description
1604    * @return name of the key (e.g. <code>CS-F1</code> for control-shift-function key one)
1605    * @see #stringToKey
1606    */

1607    public static String JavaDoc keyToString(KeyStroke JavaDoc stroke) {
1608        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1609
1610        // add modifiers that must be pressed
1611
if (addModifiers(sb, stroke.getModifiers())) {
1612            sb.append('-');
1613        }
1614
1615        HashMap JavaDoc[] namesAndValues = initNameAndValues();
1616
1617        String JavaDoc c = (String JavaDoc) namesAndValues[1].get(new Integer JavaDoc(stroke.getKeyCode()));
1618
1619        if (c == null) {
1620            sb.append(stroke.getKeyChar());
1621        } else {
1622            sb.append(c);
1623        }
1624
1625        return sb.toString();
1626    }
1627
1628    /** Construct a new key description from a given universal string
1629    * description.
1630    * Provides mapping between Emacs-like textual key descriptions and the
1631    * <code>KeyStroke</code> object used in Swing.
1632    * <P>
1633    * This format has following form:
1634    * <P><code>[C][A][S][M]-<em>identifier</em></code>
1635    * <p>Where:
1636    * <UL>
1637    * <LI> <code>C</code> stands for the Control key
1638    * <LI> <code>A</code> stands for the Alt key
1639    * <LI> <code>S</code> stands for the Shift key
1640    * <LI> <code>M</code> stands for the Meta key
1641    * </UL>
1642    * The format also supports two wildcard codes, to support differences in
1643    * platforms. These are the preferred choices for registering keystrokes,
1644    * since platform conflicts will automatically be handled:
1645    * <UL>
1646    * <LI> <code>D</code> stands for the default menu accelerator - the Control
1647    * key on most platforms, the Command (meta) key on Macintosh</LI>
1648    * <LI> <code>O</code> stands for the alternate accelerator - the Alt key on
1649    * most platforms, the Ctrl key on Macintosh (Macintosh uses Alt as a
1650    * secondary shift key for composing international characters - if you bind
1651    * Alt-8 to an action, a mac user with a French keyboard will not be able
1652    * to type the <code>[</code> character, which is a significant handicap</LI>
1653    * </UL>
1654    * If you use the wildcard characters, and specify a key which will conflict
1655    * with keys the operating system consumes, it will be mapped to whichever
1656    * choice can work - for example, on Macintosh, Command-Q is always consumed
1657    * by the operating system, so <code>D-Q</code> will always map to Control-Q.
1658    * <p>
1659    * Every modifier before the hyphen must be pressed.
1660    * <em>identifier</EM> can be any text constant from {@link KeyEvent} but
1661    * without the leading <code>VK_</code> characters. So {@link KeyEvent#VK_ENTER} is described as
1662    * <code>ENTER</code>.
1663    *
1664    * @param s the string with the description of the key
1665    * @return key description object, or <code>null</code> if the string does not represent any valid key
1666    */

1667    public static KeyStroke JavaDoc stringToKey(String JavaDoc s) {
1668        StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s.toUpperCase(Locale.ENGLISH), "-", true); // NOI18N
1669

1670        int needed = 0;
1671
1672        HashMap JavaDoc names = initNameAndValues()[0];
1673
1674        int lastModif = -1;
1675
1676        try {
1677            for (;;) {
1678                String JavaDoc el = st.nextToken();
1679
1680                // required key
1681
if (el.equals("-")) { // NOI18N
1682

1683                    if (lastModif != -1) {
1684                        needed |= lastModif;
1685                        lastModif = -1;
1686                    }
1687
1688                    continue;
1689                }
1690
1691                // if there is more elements
1692
if (st.hasMoreElements()) {
1693                    // the text should describe modifiers
1694
lastModif = readModifiers(el);
1695                } else {
1696                    // last text must be the key code
1697
Integer JavaDoc i = (Integer JavaDoc) names.get(el);
1698                    boolean wildcard = (needed & CTRL_WILDCARD_MASK) != 0;
1699
1700                    //Strip out the explicit mask - KeyStroke won't know
1701
//what to do with it
1702
needed = needed & ~CTRL_WILDCARD_MASK;
1703
1704                    boolean macAlt = (needed & ALT_WILDCARD_MASK) != 0;
1705                    needed = needed & ~ALT_WILDCARD_MASK;
1706
1707                    if (i != null) {
1708                        //#26854 - Default accelerator should be Command on mac
1709
if (wildcard) {
1710                            needed |= Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
1711
1712                            if (isMac()) {
1713                                if (!usableKeyOnMac(i.intValue(), needed)) {
1714                                    needed &= ~Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
1715                                    needed |= KeyEvent.CTRL_MASK;
1716                                }
1717                            }
1718                        }
1719
1720                        if (macAlt) {
1721                            if (getOperatingSystem() == OS_MAC) {
1722                                needed |= KeyEvent.CTRL_MASK;
1723                            } else {
1724                                needed |= KeyEvent.ALT_MASK;
1725                            }
1726                        }
1727
1728                        return KeyStroke.getKeyStroke(i.intValue(), needed);
1729                    } else {
1730                        return null;
1731                    }
1732                }
1733            }
1734        } catch (NoSuchElementException JavaDoc ex) {
1735            return null;
1736        }
1737    }
1738
1739    private static final boolean usableKeyOnMac(int key, int mask) {
1740        //All permutations fail for Q except ctrl
1741
if (key == KeyEvent.VK_Q) {
1742            return false;
1743        }
1744
1745        boolean isMeta = ((mask & KeyEvent.META_MASK) != 0) || ((mask & KeyEvent.CTRL_DOWN_MASK) != 0);
1746
1747        boolean isAlt = ((mask & KeyEvent.ALT_MASK) != 0) || ((mask & KeyEvent.ALT_DOWN_MASK) != 0);
1748
1749        boolean isOnlyMeta = isMeta && ((mask & ~(KeyEvent.META_DOWN_MASK | KeyEvent.META_MASK)) == 0);
1750
1751        //Mac OS consumes keys Command+ these keys - the app will never see
1752
//them, so CTRL should not be remapped for these
1753
if (isOnlyMeta) {
1754            return (key != KeyEvent.VK_H) && (key != KeyEvent.VK_SPACE) && (key != KeyEvent.VK_TAB);
1755        } else if ((key == KeyEvent.VK_D) && isMeta && isAlt) {
1756            return false;
1757        } else {
1758            return true;
1759        }
1760    }
1761
1762    /** Convert a space-separated list of user-friendly key binding names to a list of Swing key strokes.
1763    * @param s the string with keys
1764    * @return array of key strokes, or <code>null</code> if the string description is not valid
1765    * @see #stringToKey
1766    */

1767    public static KeyStroke JavaDoc[] stringToKeys(String JavaDoc s) {
1768        StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(s.toUpperCase(Locale.ENGLISH), " "); // NOI18N
1769
ArrayList JavaDoc<KeyStroke JavaDoc> arr = new ArrayList JavaDoc<KeyStroke JavaDoc>();
1770
1771        while (st.hasMoreElements()) {
1772            s = st.nextToken();
1773
1774            KeyStroke JavaDoc k = stringToKey(s);
1775
1776            if (k == null) {
1777                return null;
1778            }
1779
1780            arr.add(k);
1781        }
1782
1783        return arr.toArray(new KeyStroke JavaDoc[arr.size()]);
1784    }
1785
1786    /** Adds characters for modifiers to the buffer.
1787    * @param buf buffer to add to
1788    * @param modif modifiers to add (KeyEvent.XXX_MASK)
1789    * @return true if something has been added
1790    */

1791    private static boolean addModifiers(StringBuffer JavaDoc buf, int modif) {
1792        boolean b = false;
1793
1794        if ((modif & KeyEvent.CTRL_MASK) != 0) {
1795            buf.append("C"); // NOI18N
1796
b = true;
1797        }
1798
1799        if ((modif & KeyEvent.ALT_MASK) != 0) {
1800            buf.append("A"); // NOI18N
1801
b = true;
1802        }
1803
1804        if ((modif & KeyEvent.SHIFT_MASK) != 0) {
1805            buf.append("S"); // NOI18N
1806
b = true;
1807        }
1808
1809        if ((modif & KeyEvent.META_MASK) != 0) {
1810            buf.append("M"); // NOI18N
1811
b = true;
1812        }
1813
1814        if ((modif & CTRL_WILDCARD_MASK) != 0) {
1815            buf.append("D");
1816            b = true;
1817        }
1818
1819        if ((modif & ALT_WILDCARD_MASK) != 0) {
1820            buf.append("O");
1821            b = true;
1822        }
1823
1824        return b;
1825    }
1826
1827    /** Reads for modifiers and creates integer with required mask.
1828    * @param s string with modifiers
1829    * @return integer with mask
1830    * @exception NoSuchElementException if some letter is not modifier
1831    */

1832    private static int readModifiers(String JavaDoc s) throws NoSuchElementException JavaDoc {
1833        int m = 0;
1834
1835        for (int i = 0; i < s.length(); i++) {
1836            switch (s.charAt(i)) {
1837            case 'C':
1838                m |= KeyEvent.CTRL_MASK;
1839
1840                break;
1841
1842            case 'A':
1843                m |= KeyEvent.ALT_MASK;
1844
1845                break;
1846
1847            case 'M':
1848                m |= KeyEvent.META_MASK;
1849
1850                break;
1851
1852            case 'S':
1853                m |= KeyEvent.SHIFT_MASK;
1854
1855                break;
1856
1857            case 'D':
1858                m |= CTRL_WILDCARD_MASK;
1859
1860                break;
1861
1862            case 'O':
1863                m |= ALT_WILDCARD_MASK;
1864
1865                break;
1866
1867            default:
1868                throw new NoSuchElementException JavaDoc(s);
1869            }
1870        }
1871
1872        return m;
1873    }
1874
1875    /**
1876     * Finds out the monitor where the user currently has the input focus.
1877     * This method is usually used to help the client code to figure out on
1878     * which monitor it should place newly created windows/frames/dialogs.
1879     *
1880     * @return the GraphicsConfiguration of the monitor which currently has the
1881     * input focus
1882     */

1883    private static GraphicsConfiguration JavaDoc getCurrentGraphicsConfiguration() {
1884    Component JavaDoc focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
1885        if (focusOwner != null) {
1886            Window JavaDoc w = SwingUtilities.getWindowAncestor(focusOwner);
1887            if (w != null) {
1888                return w.getGraphicsConfiguration();
1889            }
1890        }
1891
1892        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1893    }
1894
1895    /**
1896     * Returns the usable area of the screen where applications can place its
1897     * windows. The method subtracts from the screen the area of taskbars,
1898     * system menus and the like. The screen this method applies to is the one
1899     * which is considered current, ussually the one where the current input
1900     * focus is.
1901     *
1902     * @return the rectangle of the screen where one can place windows
1903     *
1904     * @since 2.5
1905     */

1906    public static Rectangle JavaDoc getUsableScreenBounds() {
1907        return getUsableScreenBounds(getCurrentGraphicsConfiguration());
1908    }
1909
1910    /**
1911     * Returns the usable area of the screen where applications can place its
1912     * windows. The method subtracts from the screen the area of taskbars,
1913     * system menus and the like.
1914     *
1915     * @param gconf the GraphicsConfiguration of the monitor
1916     * @return the rectangle of the screen where one can place windows
1917     *
1918     * @since 2.5
1919     */

1920    public static Rectangle JavaDoc getUsableScreenBounds(GraphicsConfiguration JavaDoc gconf) {
1921        if (gconf == null) {
1922            gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1923        }
1924
1925        Rectangle JavaDoc bounds = new Rectangle JavaDoc(gconf.getBounds());
1926
1927        String JavaDoc str;
1928
1929        str = System.getProperty("netbeans.screen.insets"); // NOI18N
1930

1931        if (str != null) {
1932            StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(str, ", "); // NOI18N
1933

1934            if (st.countTokens() == 4) {
1935                try {
1936                    bounds.y = Integer.parseInt(st.nextToken());
1937                    bounds.x = Integer.parseInt(st.nextToken());
1938                    bounds.height -= (bounds.y + Integer.parseInt(st.nextToken()));
1939                    bounds.width -= (bounds.x + Integer.parseInt(st.nextToken()));
1940                } catch (NumberFormatException JavaDoc ex) {
1941                    Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
1942                }
1943            }
1944
1945            return bounds;
1946        }
1947
1948        str = System.getProperty("netbeans.taskbar.height"); // NOI18N
1949

1950        if (str != null) {
1951            bounds.height -= Integer.getInteger(str, 0).intValue();
1952
1953            return bounds;
1954        }
1955
1956        try {
1957            Toolkit JavaDoc toolkit = Toolkit.getDefaultToolkit();
1958            Insets JavaDoc insets = toolkit.getScreenInsets(gconf);
1959            bounds.y += insets.top;
1960            bounds.x += insets.left;
1961            bounds.height -= (insets.top + insets.bottom);
1962            bounds.width -= (insets.left + insets.right);
1963        } catch (Exception JavaDoc ex) {
1964            Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
1965        }
1966
1967        return bounds;
1968    }
1969
1970    /**
1971     * Helps client code place components on the center of the screen. It
1972     * handles multiple monitor configuration correctly
1973     *
1974     * @param componentSize the size of the component
1975     * @return bounds of the centered component
1976     *
1977     * @since 2.5
1978     */

1979    public static Rectangle JavaDoc findCenterBounds(Dimension JavaDoc componentSize) {
1980        return findCenterBounds(getCurrentGraphicsConfiguration(), componentSize);
1981    }
1982
1983    /**
1984     * Helps client code place components on the center of the screen. It
1985     * handles multiple monitor configuration correctly
1986     *
1987     * @param gconf the GraphicsConfiguration of the monitor
1988     * @param componentSize the size of the component
1989     * @return bounds of the centered component
1990     */

1991    private static Rectangle JavaDoc findCenterBounds(GraphicsConfiguration JavaDoc gconf, Dimension JavaDoc componentSize) {
1992        if (gconf == null) {
1993            gconf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
1994        }
1995
1996        Rectangle JavaDoc bounds = gconf.getBounds();
1997
1998        return new Rectangle JavaDoc(
1999            bounds.x + ((bounds.width - componentSize.width) / 2),
2000            bounds.y + ((bounds.height - componentSize.height) / 2), componentSize.width, componentSize.height
2001        );
2002    }
2003
2004    /** @return size of the screen. The size is modified for Windows OS
2005     * - some points are subtracted to reflect a presence of the taskbar
2006     *
2007     * @deprecated this method is almost useless in multiple monitor configuration
2008     *
2009     * @see #getUsableScreenBounds()
2010     * @see #findCenterBounds(Dimension)
2011     */

2012    @Deprecated JavaDoc
2013    public static final Dimension JavaDoc getScreenSize() {
2014        Dimension JavaDoc screenSize = Toolkit.getDefaultToolkit().getScreenSize();
2015
2016        if (isWindows() && !Boolean.getBoolean("netbeans.no.taskbar")) {
2017            screenSize.height -= TYPICAL_WINDOWS_TASKBAR_HEIGHT;
2018        } else if (isMac()) {
2019            screenSize.height -= TYPICAL_MACOSX_MENU_HEIGHT;
2020        }
2021
2022        return screenSize;
2023    }
2024
2025    /** Utility method for avoiding of memory leak in JDK 1.3 / JFileChooser.showDialog(...)
2026     * @param parent
2027     * @param approveButtonText
2028     * @deprecated Not needed in JDK 1.4.
2029     */

2030    @Deprecated JavaDoc
2031    public static final int showJFileChooser(
2032        javax.swing.JFileChooser JavaDoc chooser, java.awt.Component JavaDoc parent, java.lang.String JavaDoc approveButtonText
2033    ) {
2034        if (approveButtonText != null) {
2035            chooser.setApproveButtonText(approveButtonText);
2036            chooser.setDialogType(javax.swing.JFileChooser.CUSTOM_DIALOG);
2037        }
2038
2039        Frame JavaDoc frame = null;
2040        Dialog JavaDoc parentDlg = null;
2041
2042        if (parent instanceof Dialog JavaDoc) {
2043            parentDlg = (Dialog JavaDoc) parent;
2044        } else {
2045            frame = (parent instanceof java.awt.Frame JavaDoc) ? (Frame JavaDoc) parent
2046                                                       : (Frame JavaDoc) javax.swing.SwingUtilities.getAncestorOfClass(
2047                    Frame JavaDoc.class, parent
2048                );
2049        }
2050
2051        String JavaDoc title = chooser.getDialogTitle();
2052
2053        if (title == null) {
2054            title = chooser.getUI().getDialogTitle(chooser);
2055        }
2056
2057        final javax.swing.JDialog JavaDoc dialog;
2058
2059        if (parentDlg != null) {
2060            dialog = new javax.swing.JDialog JavaDoc(parentDlg, title, true);
2061        } else {
2062            dialog = new javax.swing.JDialog JavaDoc(frame, title, true);
2063        }
2064
2065        dialog.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
2066
2067        Container JavaDoc contentPane = dialog.getContentPane();
2068        contentPane.setLayout(new BorderLayout JavaDoc());
2069        contentPane.add(chooser, BorderLayout.CENTER);
2070
2071        dialog.pack();
2072        dialog.setBounds(findCenterBounds(parent.getGraphicsConfiguration(), dialog.getSize()));
2073
2074        chooser.rescanCurrentDirectory();
2075
2076        final int[] retValue = new int[] { javax.swing.JFileChooser.CANCEL_OPTION };
2077
2078        java.awt.event.ActionListener JavaDoc l = new java.awt.event.ActionListener JavaDoc() {
2079                public void actionPerformed(java.awt.event.ActionEvent JavaDoc ev) {
2080                    if (ev.getActionCommand() == javax.swing.JFileChooser.APPROVE_SELECTION) {
2081                        retValue[0] = javax.swing.JFileChooser.APPROVE_OPTION;
2082                    }
2083
2084                    dialog.setVisible(false);
2085                    dialog.dispose();
2086                }
2087            };
2088
2089        chooser.addActionListener(l);
2090
2091        dialog.show();
2092
2093        return retValue[0];
2094    }
2095
2096    /** Sort a list according to a specified partial order.
2097    * Note that in the current implementation, the comparator will be called
2098    * exactly once for each distinct pair of list elements, ignoring order,
2099    * so caching its results is a waste of time.
2100    * @param l the list to sort (will not be modified)
2101    * @param c a comparator to impose the partial order; "equal" means that the elements
2102    * are not ordered with respect to one another, i.e. may be only a partial order
2103    * @param stable whether to attempt a stable sort, meaning that the position of elements
2104    * will be disturbed as little as possible; might be slightly slower
2105    * @return the partially-sorted list
2106    * @throws UnorderableException if the specified partial order is inconsistent on this list
2107    * @deprecated Deprecated in favor of the potentially much faster (and possibly more correct) {@link #topologicalSort}.
2108    */

2109    @SuppressWarnings JavaDoc("unchecked") // do not bother, it is deprecated anyway
2110
@Deprecated JavaDoc
2111    public static List JavaDoc partialSort(List JavaDoc l, Comparator JavaDoc c, boolean stable)
2112    throws UnorderableException {
2113        // map from objects in the list to null or sets of objects they are greater than
2114
// (i.e. must appear after):
2115
Map JavaDoc deps = new HashMap JavaDoc(); // Map<Object,Set<Object>>
2116
int size = l.size();
2117
2118        // Create a table of dependencies.
2119
for (int i = 0; i < size; i++) {
2120            for (int j = i + 1; j < size; j++) {
2121                int cmp = c.compare(l.get(i), l.get(j));
2122
2123                if (cmp != 0) {
2124                    Object JavaDoc earlier = l.get((cmp < 0) ? i : j);
2125                    Object JavaDoc later = l.get((cmp > 0) ? i : j);
2126                    Set JavaDoc s = (Set JavaDoc) deps.get(later);
2127
2128                    if (s == null) {
2129                        deps.put(later, s = new HashSet JavaDoc());
2130                    }
2131
2132                    s.add(earlier);
2133                }
2134            }
2135        }
2136
2137        // Lists of items to process, and items sorted.
2138
List JavaDoc left = new LinkedList JavaDoc(l);
2139        List JavaDoc sorted = new ArrayList JavaDoc(size);
2140
2141        while (left.size() > 0) {
2142            boolean stillGoing = false;
2143            Iterator JavaDoc it = left.iterator();
2144
2145            while (it.hasNext()) {
2146                Object JavaDoc elt = it.next();
2147                Set JavaDoc eltDeps = (Set JavaDoc) deps.get(elt);
2148
2149                if ((eltDeps == null) || (eltDeps.size() == 0)) {
2150                    // This one is OK to add to the result now.
2151
it.remove();
2152                    stillGoing = true;
2153                    sorted.add(elt);
2154
2155                    // Mark other elements that should be later
2156
// than this as having their dep satisfied.
2157
Iterator JavaDoc it2 = left.iterator();
2158
2159                    while (it2.hasNext()) {
2160                        Object JavaDoc elt2 = it2.next();
2161                        Set JavaDoc eltDeps2 = (Set JavaDoc) deps.get(elt2);
2162
2163                        if (eltDeps2 != null) {
2164                            eltDeps2.remove(elt);
2165                        }
2166                    }
2167
2168                    if (stable) {
2169                        break;
2170                    }
2171                }
2172            }
2173
2174            if (!stillGoing) {
2175                // Clean up deps to only include "interesting" problems.
2176
it = deps.entrySet().iterator();
2177
2178                while (it.hasNext()) {
2179                    Map.Entry JavaDoc me = (Map.Entry JavaDoc) it.next();
2180
2181                    if (!left.contains(me.getKey())) {
2182                        it.remove();
2183                    } else {
2184                        Set JavaDoc s = (Set JavaDoc) me.getValue();
2185                        Iterator JavaDoc it2 = s.iterator();
2186
2187                        while (it2.hasNext()) {
2188                            if (!left.contains(it2.next())) {
2189                                it2.remove();
2190                            }
2191                        }
2192
2193                        if (s.isEmpty()) {
2194                            it.remove();
2195                        }
2196                    }
2197                }
2198
2199                throw new UnorderableException(left, deps);
2200            }
2201        }
2202
2203        return sorted;
2204    }
2205
2206    /**
2207     * Topologically sort some objects.
2208     * <p>There may not be any nulls among the objects, nor duplicates
2209     * (as per hash/equals), nor duplicates among the edge lists.
2210     * The edge map need not contain an entry for every object, only if it
2211     * has some outgoing edges (empty but not null map values are permitted).
2212     * The edge map may contain neither keys nor value entries for objects not
2213     * in the collection to be sorted.
2214     * <p>The incoming parameters will not be modified; they must not be changed
2215     * during the call and possible calls to TopologicalSortException methods.
2216     * The returned list will support modifications.
2217     * <p>There is a <em>weak</em> stability guarantee: if there are no edges
2218     * which contradict the incoming order, the resulting list will be in the same
2219     * order as the incoming elements. However if some elements need to be rearranged,
2220     * it is <em>not</em> guaranteed that others will not also be rearranged, even
2221     * if they did not strictly speaking need to be.
2222     * @param c a collection of objects to be topologically sorted
2223     * @param edges constraints among those objects, of type <code>Map&lt;Object,Collection&gt;</code>;
2224     * if an object is a key in this map, the resulting order will
2225     * have that object before any objects listed in the value
2226     * @return a partial ordering of the objects in the collection,
2227     * @exception TopologicalSortException if the sort cannot succeed due to cycles in the graph, the
2228     * exception contains additional information to describe and possibly recover from the error
2229     * @since 3.30
2230     * @see <a HREF="http://www.netbeans.org/issues/show_bug.cgi?id=27286">Issue #27286</a>
2231     */

2232    public static <T> List JavaDoc<T> topologicalSort(Collection JavaDoc<T> c, Map JavaDoc<? super T, ? extends Collection JavaDoc<? extends T>> edges)
2233    throws TopologicalSortException {
2234        Map JavaDoc<T,Boolean JavaDoc> finished = new HashMap JavaDoc<T,Boolean JavaDoc>();
2235        List JavaDoc<T> r = new ArrayList JavaDoc<T>(Math.max(c.size(), 1));
2236        List JavaDoc<T> cRev = new ArrayList JavaDoc<T>(c);
2237        Collections.reverse(cRev);
2238
2239        Iterator JavaDoc<T> it = cRev.iterator();
2240
2241        while (it.hasNext()) {
2242            List JavaDoc<T> cycle = visit(it.next(), edges, finished, r);
2243
2244            if (cycle != null) {
2245                throw new TopologicalSortException(cRev, edges);
2246            }
2247        }
2248
2249        Collections.reverse(r);
2250
2251        return r;
2252    }
2253
2254    /**
2255     * Visit one node in the DAG.
2256     * @param node node to visit
2257     * @param edges edges in the DAG
2258     * @param finished which nodes are finished; a node has no entry if it has not yet
2259     * been visited, else it is set to false while recurring and true
2260     * when it has finished
2261     * @param r the order in progress
2262     * @return list with detected cycle
2263     */

2264    static <T> List JavaDoc<T> visit(
2265        T node,
2266        Map JavaDoc<? super T, ? extends Collection JavaDoc<? extends T>> edges,
2267        Map JavaDoc<T,Boolean JavaDoc> finished,
2268        List JavaDoc<T> r
2269    ) {
2270        Boolean JavaDoc b = finished.get(node);
2271
2272        //System.err.println("node=" + node + " color=" + b);
2273
if (b != null) {
2274            if (b.booleanValue()) {
2275                return null;
2276            }
2277
2278            ArrayList JavaDoc<T> cycle = new ArrayList JavaDoc<T>();
2279            cycle.add(node);
2280            finished.put(node, null);
2281
2282            return cycle;
2283        }
2284
2285        Collection JavaDoc<? extends T> e = edges.get(node);
2286
2287        if (e != null) {
2288            finished.put(node, Boolean.FALSE);
2289
2290            Iterator JavaDoc<? extends T> it = e.iterator();
2291
2292            while (it.hasNext()) {
2293                List JavaDoc<T> cycle = visit(it.next(), edges, finished, r);
2294
2295                if (cycle != null) {
2296                    if (cycle instanceof ArrayList JavaDoc) {
2297                        // if cycle instanceof ArrayList we are still in the
2298
// cycle and we want to collect new members
2299
if (Boolean.FALSE == finished.get(node)) {
2300                            // another member in the cycle
2301
cycle.add(node);
2302                        } else {
2303                            // we have reached the head of the cycle
2304
// do not add additional cycles anymore
2305
Collections.reverse(cycle);
2306
2307                            // changing cycle to not be ArrayList
2308
cycle = Collections.unmodifiableList(cycle);
2309                        }
2310                    }
2311
2312                    // mark this node as tested
2313
finished.put(node, Boolean.TRUE);
2314
2315                    // and report an error
2316
return cycle;
2317                }
2318            }
2319        }
2320
2321        finished.put(node, Boolean.TRUE);
2322        r.add(node);
2323
2324        return null;
2325    }
2326
2327    /** Provides support for parts of the system that deal with classnames
2328     * (use <code>Class.forName</code>, <code>NbObjectInputStream</code>, etc.).
2329     * <P>
2330     * Often class names (especially package names) changes during lifecycle
2331     * of a module. When some piece of the system stores the name of a class
2332     * in certain point of a time and wants to find the correct <code>Class</code>
2333     * later it needs to count with the possibility of rename.
2334     * <P>
2335     * For such purposes this method has been created. It allows modules to
2336     * register their classes that changed names and other parts of system that
2337     * deal with class names to find the correct names.
2338     * <P>
2339     * To register a mapping from old class names to new ones create a file
2340     * <code>META-INF/netbeans/translate.names</code> in your module and fill it
2341     * with your mapping:
2342     * <PRE>
2343     * #
2344     * # Mapping of legacy classes to new ones
2345     * #
2346     *
2347     * org.oldpackage.MyClass=org.newpackage.MyClass # rename of package for one class
2348     * org.mypackage.OldClass=org.mypackage.NewClass # rename of class in a package
2349     *
2350     * # rename of class and package
2351     * org.oldpackage.OldClass=org.newpackage.NewClass
2352     *
2353     * # rename of whole package
2354     * org.someoldpackage=org.my.new.package.structure
2355     *
2356     * </PRE>
2357     * Btw. one can use spaces instead of <code>=</code> sign.
2358     * For a real world example
2359     * check the
2360     * <a HREF="http://www.netbeans.org/source/browse/xml/text-edit/compat/src/META-INF/netbeans/">
2361     * xml module</a>.
2362     *
2363     * <P>
2364     * For purposes of <link>org.openide.util.io.NbObjectInputStream</link> there is
2365     * a following special convention:
2366     * If the
2367     * className is not listed as one that is to be renamed, the returned
2368     * string == className, if the className is registered to be renamed
2369     * than the className != returned value, even in a case when className.equals (retValue)
2370     *
2371     * @param className fully qualified name of a class to translate
2372     * @return new name of the class according to renaming rules.
2373     */

2374    public static String JavaDoc translate(final String JavaDoc className) {
2375        checkMapping();
2376
2377        RE exp;
2378
2379        synchronized (TRANS_LOCK) {
2380            exp = transExp;
2381        }
2382
2383        if (exp == null) {
2384            // no transition table found
2385
return className;
2386        }
2387
2388        synchronized (exp) {
2389            // refusing convertions as fast as possible
2390
return exp.convert(className);
2391        }
2392    }
2393
2394    /** Loads all resources that contain renaming information.
2395     * @param l classloader to load packages from
2396     */

2397    private static void checkMapping() {
2398        // test if we run in test mode
2399
if (transLoader == TRANS_LOCK) {
2400            // no check
2401
return;
2402        }
2403
2404        ClassLoader JavaDoc current = Lookup.getDefault().lookup(ClassLoader JavaDoc.class);
2405
2406        if (current == null) {
2407            current = ClassLoader.getSystemClassLoader();
2408        }
2409
2410        if (transLoader == current) {
2411            // no change, no rescan
2412
return;
2413        }
2414
2415        initForLoader(current, current);
2416    }
2417
2418    /* Initializes the content of transition table from a classloader.
2419     * @param loader loader to read data from
2420     * @param set loader to set as the transLoader or null if we run in test mode
2421     */

2422    static void initForLoader(ClassLoader JavaDoc current, Object JavaDoc set) {
2423        if (set == null) {
2424            set = TRANS_LOCK;
2425        }
2426
2427        Enumeration JavaDoc en;
2428
2429        try {
2430            en = current.getResources("META-INF/netbeans/translate.names");
2431        } catch (IOException JavaDoc ex) {
2432            Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
2433            en = null;
2434        }
2435
2436        if ((en == null) || !en.hasMoreElements()) {
2437            synchronized (TRANS_LOCK) {
2438                transLoader = set;
2439                transExp = null;
2440            }
2441
2442            return;
2443        }
2444
2445        // format of line in the meta files
2446
//
2447
// # comments are allowed
2448
// a.name.in.a.Package=another.Name # with comment is allowed
2449
// for.compatibility.one.can.use.Space instead.of.Equal
2450
//
2451
RE re = null;
2452
2453        // [pnejedly:perf] commented out. The RegExp based translation was way slower
2454
// than the hand-written RE13
2455
// if (Dependency.JAVA_SPEC.compareTo(new SpecificationVersion("1.4")) >= 0) { // NOI18N
2456
// try {
2457
// re = (RE)Class.forName ("org.openide.util.RE14").newInstance ();
2458
// } catch (ThreadDeath t) {
2459
// throw t;
2460
// } catch (Throwable t) {
2461
// }
2462
// }
2463
// if (re == null) {
2464
re = new RE13();
2465
2466        // }
2467
TreeSet JavaDoc<String JavaDoc[]> list = new TreeSet JavaDoc<String JavaDoc[]>(
2468                new Comparator JavaDoc<String JavaDoc[]>() {
2469                    public int compare(String JavaDoc[] o1, String JavaDoc[] o2) {
2470                        String JavaDoc s1 = o1[0];
2471                        String JavaDoc s2 = o2[0];
2472
2473                        int i1 = s1.length();
2474                        int i2 = s2.length();
2475
2476                        if (i1 != i2) {
2477                            return i2 - i1;
2478                        }
2479
2480                        return s2.compareTo(s1);
2481                    }
2482                }
2483            );
2484
2485        while (en.hasMoreElements()) {
2486            URL JavaDoc u = (URL JavaDoc) en.nextElement();
2487
2488            try {
2489                BufferedReader JavaDoc reader = new BufferedReader JavaDoc(
2490                        new InputStreamReader JavaDoc(u.openStream(), "UTF8") // use explicit encoding //NOI18N
2491
);
2492                loadTranslationFile(re, reader, list);
2493                reader.close();
2494            } catch (IOException JavaDoc ex) {
2495                Logger.getAnonymousLogger().log(Level.WARNING, "Problematic file: " + u);
2496                Logger.getAnonymousLogger().log(Level.WARNING, null, ex);
2497            }
2498        }
2499
2500        // construct a regular expression of following form. Let "1", "2", "3", "4"
2501
// be the keys:
2502
// "^
2503
// thus if 4 is matched five groups will be created
2504
String JavaDoc[] arr = new String JavaDoc[list.size()];
2505        String JavaDoc[] pattern = new String JavaDoc[arr.length];
2506
2507        int i = 0;
2508        Iterator JavaDoc it = list.iterator();
2509
2510        while (it.hasNext()) {
2511            String JavaDoc[] pair = (String JavaDoc[]) it.next();
2512            arr[i] = pair[1].intern(); // name of the track
2513
pattern[i] = pair[0]; // original object
2514
i++;
2515        }
2516
2517        synchronized (TRANS_LOCK) {
2518            // last check
2519
if (arr.length == 0) {
2520                transExp = null;
2521            } else {
2522                transExp = re;
2523                transExp.init(pattern, arr);
2524            }
2525
2526            transLoader = set;
2527        }
2528    }
2529
2530    /**
2531     * Load single translation file.
2532     * @param resource URL identifiing transaction table
2533     * @param results will be filled with String[2]
2534     */

2535    private static void loadTranslationFile(RE re, BufferedReader JavaDoc reader, Set JavaDoc<String JavaDoc[]> results)
2536    throws IOException JavaDoc {
2537        for (;;) {
2538            String JavaDoc line = reader.readLine();
2539
2540            if (line == null) {
2541                break;
2542            }
2543
2544            if ((line.length() == 0) || line.startsWith("#")) { // NOI18N
2545

2546                continue;
2547            }
2548
2549            String JavaDoc[] pair = re.readPair(line);
2550
2551            if (pair == null) {
2552                throw new java.io.InvalidObjectException JavaDoc("Line is invalid: " + line);
2553            }
2554
2555            results.add(pair);
2556        }
2557    }
2558
2559    /** This method merges two images into the new one. The second image is drawn
2560     * over the first one with its top-left corner at x, y. Images need not be of the same size.
2561     * New image will have a size of max(second image size + top-left corner, first image size).
2562     * Method is used mostly when second image contains transparent pixels (e.g. for badging).
2563     * If both images are <code>null</code>, it makes default transparent 16x16 image.
2564     * @param image1 underlying image
2565     * @param image2 second image
2566     * @param x x position of top-left corner
2567     * @param y y position of top-left corner
2568     * @return new merged image
2569     */

2570    public static final Image JavaDoc mergeImages(Image JavaDoc image1, Image JavaDoc image2, int x, int y) {
2571        if (image1 == null) {
2572            throw new NullPointerException JavaDoc();
2573        }
2574
2575        if (image2 == null) {
2576            throw new NullPointerException JavaDoc();
2577        }
2578
2579        return IconManager.mergeImages(image1, image2, x, y);
2580    }
2581
2582    /**
2583     * Loads an image from the specified resource ID. The image is loaded using the "system" classloader registered in
2584     * Lookup.
2585     * @param resourceID resource path of the icon (no initial slash)
2586     * @return icon's Image, or null, if the icon cannot be loaded.
2587     */

2588    public static final Image JavaDoc loadImage(String JavaDoc resourceID) {
2589        return IconManager.getIcon(resourceID, false);
2590    }
2591
2592    /**
2593     * Converts given icon to a {@link java.awt.Image}.
2594     *
2595     * @param icon {@link javax.swing.Icon} to be converted.
2596     * @since 7.3
2597     */

2598    public static final Image JavaDoc icon2Image(Icon JavaDoc icon) {
2599        if (icon instanceof ImageIcon JavaDoc) {
2600            return ((ImageIcon JavaDoc) icon).getImage();
2601        } else {
2602            BufferedImage JavaDoc bImage = new BufferedImage JavaDoc(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
2603            Graphics JavaDoc g = bImage.getGraphics();
2604            icon.paintIcon(new JLabel JavaDoc(), g, 0, 0);
2605            g.dispose();
2606            return bImage;
2607        }
2608    }
2609
2610    /** Builds a popup menu from actions for provided context specified by
2611     * <code>Lookup</code>.
2612     * Takes list of actions and for actions whic are instances of
2613     * <code>ContextAwareAction</code> creates and uses the context aware instance.
2614     * Then gets the action presenter or simple menu item for the action to the
2615     * popup menu for each action (or separator for each 'lonely' null array member).
2616     *
2617     * @param actions array of actions to build menu for. Can contain null
2618     * elements, they will be replaced by separators
2619     * @param context the context for which the popup is build
2620     * @return the constructed popup menu
2621     * @see ContextAwareAction
2622     * @since 3.29
2623     */

2624    public static JPopupMenu JavaDoc actionsToPopup(Action JavaDoc[] actions, Lookup context) {
2625        // keeps actions for which was menu item created already (do not add them twice)
2626
Set JavaDoc<Action JavaDoc> counted = new HashSet JavaDoc<Action JavaDoc>();
2627        // components to be added (separators are null)
2628
List JavaDoc<Component JavaDoc> components = new ArrayList JavaDoc<Component JavaDoc>();
2629
2630        for (Action JavaDoc action : actions) {
2631            if (action != null && counted.add(action)) {
2632                // switch to replacement action if there is some
2633
if (action instanceof ContextAwareAction) {
2634                    Action JavaDoc contextAwareAction = ((ContextAwareAction) action).createContextAwareInstance(context);
2635                    if (contextAwareAction == null) {
2636                        Logger.getLogger(Utilities.class.getName()).warning(
2637                                "ContextAwareAction.createContextAwareInstance(context) returns null. That is illegal!" // NOI18N
2638
+ " action=" + action + ", context=" + context); // NOI18N
2639
} else {
2640                        action = contextAwareAction;
2641                    }
2642                }
2643
2644                JMenuItem JavaDoc item;
2645                if (action instanceof Presenter.Popup) {
2646                    item = ((Presenter.Popup) action).getPopupPresenter();
2647                    if (item == null) {
2648                        Logger.getLogger(Utilities.class.getName()).warning(
2649                                "findContextMenuImpl, getPopupPresenter returning null for " + action); // NOI18N
2650
continue;
2651                    }
2652                } else {
2653                    // We need to correctly handle mnemonics with '&' etc.
2654
item = AWTBridge.getDefault().createPopupPresenter(action);
2655                }
2656
2657                for (Component JavaDoc c : AWTBridge.getDefault().convertComponents(item)) {
2658                    if (c instanceof JSeparator JavaDoc) {
2659                        components.add(null);
2660                    } else {
2661                        components.add(c);
2662                    }
2663                }
2664            } else {
2665                components.add(null);
2666            }
2667        }
2668
2669        // Now create actual menu. Strip adjacent, leading, and trailing separators.
2670
JPopupMenu JavaDoc menu = AWTBridge.getDefault().createEmptyPopup();
2671        boolean nonempty = false; // has anything been added yet?
2672
boolean pendingSep = false; // should there be a separator before any following item?
2673
for (Component JavaDoc c : components) {
2674            if (c == null) {
2675                pendingSep = nonempty;
2676            } else {
2677                nonempty = true;
2678                if (pendingSep) {
2679                    pendingSep = false;
2680                    menu.addSeparator();
2681                }
2682                menu.add(c);
2683            }
2684        }
2685        return menu;
2686    }
2687
2688    /** Builds a popup menu for provided component. It retrieves context
2689     * (lookup) from provided component instance or one of its parent
2690     * (it searches up to the hierarchy for <code>Lookup.Provider</code> instance).
2691     * If none of the components is <code>Lookup.Provider</code> instance, then
2692     * it is created context which is fed with composite ActionMap which delegates
2693     * to all components up to hierarchy started from the specified one.
2694     * Then <code>actionsToPopup(Action[],&nbsp;Lookup)</code>} is called with
2695     * the found <code>Lookup</code> instance, which actually creates a popup menu.
2696     *
2697     * @param actions array of actions to build menu for. Can contain null
2698     * elements, they will be replaced by separators
2699     * @param component a component in which to search for a context
2700     * @return the constructed popup menu
2701     * @see Lookup.Provider
2702     * @see #actionsToPopup(Action[], Lookup)
2703     * @since 3.29
2704     */

2705    public static javax.swing.JPopupMenu JavaDoc actionsToPopup(Action JavaDoc[] actions, java.awt.Component JavaDoc component) {
2706        Lookup lookup = null;
2707
2708        for (Component JavaDoc c = component; c != null; c = c.getParent()) {
2709            if (c instanceof Lookup.Provider) {
2710                lookup = ((Lookup.Provider) c).getLookup();
2711
2712                if (lookup != null) {
2713                    break;
2714                }
2715            }
2716        }
2717
2718        if (lookup == null) {
2719            // Fallback to composite action map, even it is questionable,
2720
// whether we should support component which is not (nor
2721
// none of its parents) lookup provider.
2722
UtilitiesCompositeActionMap map = new UtilitiesCompositeActionMap(component);
2723            lookup = org.openide.util.lookup.Lookups.singleton(map);
2724        }
2725
2726        return actionsToPopup(actions, lookup);
2727    }
2728
2729    /**
2730     * Global context for actions. Toolbar, menu or any other "global"
2731     * action presenters shall operate in this context.
2732     * Presenters for context menu items should <em>not</em> use
2733     * this method; instead see {@link ContextAwareAction}.
2734     * @see ContextGlobalProvider
2735     * @return the context for actions
2736     * @since 4.10
2737     */

2738    public static Lookup actionsGlobalContext() {
2739        synchronized (ContextGlobalProvider.class) {
2740            if (global != null) {
2741                return global;
2742            }
2743        }
2744
2745        ContextGlobalProvider p = Lookup.getDefault().lookup(ContextGlobalProvider.class);
2746        Lookup l = (p == null) ? Lookup.EMPTY : p.createGlobalContext();
2747
2748        synchronized (ContextGlobalProvider.class) {
2749            if (global == null) {
2750                global = l;
2751            }
2752
2753            return global;
2754        }
2755    }
2756
2757    //
2758
// end of actions stuff
2759
//
2760

2761    /**
2762     * Loads an image based on resource path.
2763     * Exactly like {@link #loadImage(String)} but may do a localized search.
2764     * For example, requesting <samp>org/netbeans/modules/foo/resources/foo.gif</samp>
2765     * might actually find <samp>org/netbeans/modules/foo/resources/foo_ja.gif</samp>
2766     * or <samp>org/netbeans/modules/foo/resources/foo_mybranding.gif</samp>.
2767     *
2768     * <p>Caching of loaded images can be used internally to improve performance.
2769     *
2770     * @since 3.24
2771     */

2772    public static final Image JavaDoc loadImage(String JavaDoc resource, boolean localized) {
2773        return IconManager.getIcon(resource, localized);
2774    }
2775
2776    /**
2777     * Returns a cursor with an arrow and an hourglass (or stop watch) badge,
2778     * to be used when a component is busy but the UI is still responding to the user.
2779     *
2780     * Similar to the predefined {@link Cursor#WAIT_CURSOR}, but has an arrow to indicate
2781     * a still-responsive UI.
2782     *
2783     * <p>Typically you will set the cursor only temporarily:
2784     *
2785     * <pre>
2786     * <font class="comment">// code is running in other then event dispatch thread</font>
2787     * currentComponent.setCursor(Utilities.createProgressCursor(currentComponent));
2788     * <font class="keyword">try</font> {
2789     * <font class="comment">// perform some work in other than event dispatch thread
2790     * // (do not block UI)</font>
2791     * } <font class="keyword">finally</font> {
2792     * currentComponent.setCursor(<font class="constant">null</font>);
2793     * }
2794     * </pre>
2795     *
2796     * <p>This implementation provides one cursor for all Mac systems, one for all
2797     * Unix systems (regardless of window manager), and one for all other systems
2798     * including Windows.
2799     *
2800     * @param component the non-null component that will use the progress cursor
2801     * @return a progress cursor (Unix, Windows or Mac)
2802     *
2803     * @since 3.23
2804     */

2805    public static final Cursor JavaDoc createProgressCursor(Component JavaDoc component) {
2806        // refuse null component
2807
if (component == null) {
2808            throw new NullPointerException JavaDoc("Given component is null"); //NOI18N
2809
}
2810
2811        Image JavaDoc image = null;
2812
2813        // First check for Mac because its part of the Unix_Mask
2814
if (isMac()) {
2815            image = loadImage("org/openide/util/progress-cursor-mac.gif"); //NOI18N
2816
} else if (isUnix()) {
2817            image = loadImage("org/openide/util/progress-cursor-motif.gif"); //NOI18N
2818
}
2819        // All other OS, including Windows, use Windows cursor
2820
else {
2821            image = loadImage("org/openide/util/progress-cursor-win.gif"); //NOI18N
2822
}
2823
2824        return createCustomCursor(component, image, "PROGRESS_CURSOR"); //NOI18N
2825
}
2826
2827    // added to fix issue #30665 (bad size on linux)
2828
public static Cursor JavaDoc createCustomCursor(Component JavaDoc component, Image JavaDoc icon, String JavaDoc name) {
2829        Toolkit JavaDoc t = component.getToolkit();
2830        Dimension JavaDoc d = t.getBestCursorSize(16, 16);
2831        Image JavaDoc i = icon;
2832
2833        if (d.width != icon.getWidth(null)) {
2834            if (((d.width) == 0) && (d.height == 0)) {
2835                // system doesn't support custom cursors, falling back
2836
return Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);
2837            }
2838
2839            // need to resize the icon
2840
Image JavaDoc empty = IconManager.createBufferedImage(d.width, d.height);
2841            i = Utilities.mergeImages(icon, empty, 0, 0);
2842        }
2843
2844        return t.createCustomCursor(i, new Point JavaDoc(1, 1), name);
2845    }
2846
2847    /** Attaches asynchronous init job to given component.
2848     * {@link AsyncGUIJob#construct()} will be called after first
2849     * paint, when paint event arrives. Later, {@link AsyncGUIJob#finished()}
2850     * will be called according to the rules of the <code>AsyncGUIJob</code> interface.
2851     *
2852     * Useful for components that have slower initialization phase, component
2853     * can benefit from more responsive behaviour during init.
2854     *
2855     * @param comp4Init Regular component in its pre-inited state, state in which
2856     * component will be shown between first paint and init completion.
2857     * @param initJob Initialization job to be called asynchronously. Job can
2858     * optionally implement {@link Cancellable}
2859     * interface for proper cancel logic. Cancel method will be called
2860     * when component stops to be showing during job's progress.
2861     * See {@link java.awt.Component#isShowing}
2862     *
2863     * @since 3.36
2864     */

2865    public static final void attachInitJob(Component JavaDoc comp4Init, AsyncGUIJob initJob) {
2866        new AsyncInitSupport(comp4Init, initJob);
2867    }
2868
2869    /**
2870     * Convert a file to a matching <code>file:</code> URL.
2871     * @param f a file (absolute only)
2872     * @return a URL using the <code>file</code> protocol
2873     * @throws MalformedURLException for no good reason
2874     * @see #toFile
2875     * @see <a HREF="http://www.netbeans.org/issues/show_bug.cgi?id=29711">Issue #29711</a>
2876     * @since 3.26
2877     * @deprecated Use {@link File#toURI} and {@link URI#toURL} instead under JDK 1.4.
2878     * ({@link File#toURL} is buggy in JDK 1.3 and the bugs are not fixed in JDK 1.4.)
2879     */

2880    @Deprecated JavaDoc
2881    public static URL JavaDoc toURL(File JavaDoc f) throws MalformedURLException JavaDoc {
2882        if (f == null) {
2883            throw new NullPointerException JavaDoc();
2884        }
2885
2886        if (!f.isAbsolute()) {
2887            throw new IllegalArgumentException JavaDoc("Relative path: " + f); // NOI18N
2888
}
2889
2890        URI JavaDoc uri = f.toURI();
2891
2892        return uri.toURL();
2893    }
2894
2895    /**
2896     * Convert a <code>file:</code> URL to a matching file.
2897     * <p>You may not use a URL generated from a file on a different
2898     * platform, as file name conventions may make the result meaningless
2899     * or even unparsable.
2900     * @param u a URL with the <code>file</code> protocol
2901     * @return an absolute file it points to, or <code>null</code> if the URL
2902     * does not seem to point to a file at all
2903     * @see #toURL
2904     * @see <a HREF="http://www.netbeans.org/issues/show_bug.cgi?id=29711">Issue #29711</a>
2905     * @since 3.26
2906     * @deprecated Use {@link URI#URI(String)} and {@link File#File(URI)} instead under JDK 1.4.
2907     * (There was no proper equivalent under JDK 1.3.)
2908     */

2909    @Deprecated JavaDoc
2910    public static File JavaDoc toFile(URL JavaDoc u) {
2911        if (u == null) {
2912            throw new NullPointerException JavaDoc();
2913        }
2914
2915        try {
2916            URI JavaDoc uri = new URI JavaDoc(u.toExternalForm());
2917
2918            return new File JavaDoc(uri);
2919        } catch (URISyntaxException JavaDoc use) {
2920            // malformed URL
2921
return null;
2922        } catch (IllegalArgumentException JavaDoc iae) {
2923            // not a file: URL
2924
return null;
2925        }
2926    }
2927
2928    /** Interfaces for communication between Utilities.translate and regular
2929     * expression impl.
2930     *
2931     * Order of methods is:
2932     * readPair few times
2933     * init once
2934     * convert many times
2935     */

2936    static interface RE {
2937        public void init(String JavaDoc[] original, String JavaDoc[] newversion);
2938
2939        public String JavaDoc convert(String JavaDoc pattern);
2940
2941        /** Parses line of text to two parts: the key and the rest
2942         */

2943        public String JavaDoc[] readPair(String JavaDoc line);
2944    }
2945
2946    /** Exception indicating that a given list could not be partially-ordered.
2947    * @see #partialSort
2948    * @deprecated Used only by the deprecated partialSort
2949    */

2950    @Deprecated JavaDoc
2951    public static class UnorderableException extends RuntimeException JavaDoc {
2952        static final long serialVersionUID = 6749951134051806661L;
2953        private Collection JavaDoc unorderable;
2954        private Map JavaDoc deps;
2955
2956        /** Create a new unorderable-list exception with no detail message.
2957        * @param unorderable a collection of list elements which could not be ordered
2958        * (because there was some sort of cycle)
2959        * @param deps dependencies associated with the list; a map from list elements
2960        * to sets of list elements which that element must appear after
2961        */

2962        public UnorderableException(Collection JavaDoc unorderable, Map JavaDoc deps) {
2963            super( /* "Cannot be ordered: " + unorderable */
2964            ); // NOI18N
2965
this.unorderable = unorderable;
2966            this.deps = deps;
2967        }
2968
2969        /** Create a new unorderable-list exception with a specified detail message.
2970        * @param message the detail message
2971        * @param unorderable a collection of list elements which could not be ordered
2972        * (because there was some sort of cycle)
2973        * @param deps dependencies associated with the list; a map from list elements
2974        * to sets of list elements which that element must appear after
2975        */

2976        public UnorderableException(String JavaDoc message, Collection JavaDoc unorderable, Map JavaDoc deps) {
2977            super(message);
2978            this.unorderable = unorderable;
2979            this.deps = deps;
2980        }
2981
2982        /** Get the unorderable elements.
2983        * @return the elements
2984        * @see Utilities.UnorderableException#Utilities.UnorderableException(Collection,Map)
2985        */

2986        public Collection JavaDoc getUnorderable() {
2987            return unorderable;
2988        }
2989
2990        /** Get the dependencies.
2991        * @return the dependencies
2992        * @see Utilities.UnorderableException#Utilities.UnorderableException(Collection,Map)
2993        */

2994        public Map JavaDoc getDeps() {
2995            return deps;
2996        }
2997    }
2998
2999    /** Implementation of the active queue.
3000     */

3001    private static final class ActiveQueue extends ReferenceQueue JavaDoc<Object JavaDoc> implements Runnable JavaDoc {
3002
3003        private static final Logger JavaDoc LOGGER = Logger.getLogger(ActiveQueue.class.getName().replace('$', '.'));
3004
3005        /** number of known outstanding references */
3006        private int count;
3007        private boolean deprecated;
3008
3009        public ActiveQueue(boolean deprecated) {
3010            this.deprecated = deprecated;
3011        }
3012
3013        public Reference JavaDoc<Object JavaDoc> poll() {
3014            throw new UnsupportedOperationException JavaDoc();
3015        }
3016
3017        public Reference JavaDoc<Object JavaDoc> remove(long timeout) throws IllegalArgumentException JavaDoc, InterruptedException JavaDoc {
3018            throw new InterruptedException JavaDoc();
3019        }
3020
3021        public Reference JavaDoc<Object JavaDoc> remove() throws InterruptedException JavaDoc {
3022            throw new InterruptedException JavaDoc();
3023        }
3024
3025        public void run() {
3026            while (true) {
3027                try {
3028                    Reference JavaDoc<?> ref = super.remove(0);
3029                    LOGGER.finer("dequeued reference");
3030
3031                    if (!(ref instanceof Runnable JavaDoc)) {
3032                        LOGGER.warning(
3033                            "A reference not implementing runnable has been added to the Utilities.activeReferenceQueue(): " +
3034                            ref.getClass() // NOI18N
3035
);
3036
3037                        continue;
3038                    }
3039
3040                    if (deprecated) {
3041                        LOGGER.warning(
3042                            "Utilities.ACTIVE_REFERENCE_QUEUE has been deprecated for " + ref.getClass() +
3043                            " use Utilities.activeReferenceQueue" // NOI18N
3044
);
3045                    }
3046
3047                    // do the cleanup
3048
try {
3049                        ((Runnable JavaDoc) ref).run();
3050                    } catch (ThreadDeath JavaDoc td) {
3051                        throw td;
3052                    } catch (Throwable JavaDoc t) {
3053                        // Should not happen.
3054
// If it happens, it is a bug in client code, notify!
3055
LOGGER.log(Level.WARNING, null, t);
3056                    } finally {
3057                        // to allow GC
3058
ref = null;
3059                    }
3060                } catch (InterruptedException JavaDoc ex) {
3061                    LOGGER.log(Level.WARNING, null, ex);
3062                }
3063
3064                synchronized (this) {
3065                    assert count > 0;
3066                    count--;
3067                    if (count == 0) {
3068                        // We have processed all we have to process (for now at least).
3069
// Could be restarted later if ping() called again.
3070
// This could also happen in case someone called activeReferenceQueue() once and tried
3071
// to use it for several references; in that case run() might never be called on
3072
// the later ones to be collected. Can't really protect against that situation.
3073
// See issue #86625 for details.
3074
LOGGER.fine("stopping thread");
3075                        break;
3076                    }
3077                }
3078            }
3079        }
3080
3081        synchronized void ping() {
3082            if (count == 0) {
3083                Thread JavaDoc t = new Thread JavaDoc(this, "Active Reference Queue Daemon"); // NOI18N
3084
t.setPriority(Thread.MIN_PRIORITY);
3085                t.setDaemon(true); // to not prevent exit of VM
3086
t.start();
3087                // Note that this will not be printed during IDE startup because
3088
// it happens before logging is even initialized.
3089
LOGGER.fine("starting thread");
3090            } else {
3091                LOGGER.finer("enqueuing reference");
3092            }
3093            count++;
3094        }
3095
3096    }
3097}
3098
Popular Tags