author | malenkov |
Tue, 29 Oct 2013 17:01:06 +0400 | |
changeset 21278 | ef8a3a2a72f2 |
parent 20455 | f6f9a0c2796b |
child 22336 | a5de9b85e983 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
9035
1255eb81cc2f
7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents:
8372
diff
changeset
|
2 |
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
package javax.swing; |
|
26 |
||
27 |
import sun.swing.SwingUtilities2; |
|
28 |
import sun.swing.UIAction; |
|
29 |
||
30 |
import java.applet.*; |
|
31 |
||
32 |
import java.awt.*; |
|
33 |
import java.awt.event.*; |
|
34 |
import java.awt.dnd.DropTarget; |
|
35 |
||
36 |
import java.util.Vector; |
|
37 |
import java.util.Hashtable; |
|
38 |
||
39 |
import java.lang.reflect.*; |
|
40 |
||
41 |
import javax.accessibility.*; |
|
42 |
import javax.swing.event.MenuDragMouseEvent; |
|
43 |
import javax.swing.plaf.UIResource; |
|
44 |
import javax.swing.text.View; |
|
45 |
import java.security.AccessController; |
|
46 |
import sun.security.action.GetPropertyAction; |
|
47 |
||
48 |
import sun.awt.AppContext; |
|
49 |
||
50 |
/** |
|
51 |
* A collection of utility methods for Swing. |
|
52 |
* |
|
53 |
* @author unknown |
|
54 |
*/ |
|
55 |
public class SwingUtilities implements SwingConstants |
|
56 |
{ |
|
57 |
// These states are system-wide, rather than AppContext wide. |
|
58 |
private static boolean canAccessEventQueue = false; |
|
59 |
private static boolean eventQueueTested = false; |
|
60 |
||
61 |
/** |
|
62 |
* Indicates if we should change the drop target when a |
|
63 |
* {@code TransferHandler} is set. |
|
64 |
*/ |
|
65 |
private static boolean suppressDropSupport; |
|
66 |
||
67 |
/** |
|
68 |
* Indiciates if we've checked the system property for suppressing |
|
69 |
* drop support. |
|
70 |
*/ |
|
71 |
private static boolean checkedSuppressDropSupport; |
|
72 |
||
73 |
||
74 |
/** |
|
75 |
* Returns true if <code>setTransferHandler</code> should change the |
|
76 |
* <code>DropTarget</code>. |
|
77 |
*/ |
|
78 |
private static boolean getSuppressDropTarget() { |
|
79 |
if (!checkedSuppressDropSupport) { |
|
80 |
suppressDropSupport = Boolean.valueOf( |
|
81 |
AccessController.doPrivileged( |
|
82 |
new GetPropertyAction("suppressSwingDropSupport"))); |
|
83 |
checkedSuppressDropSupport = true; |
|
84 |
} |
|
85 |
return suppressDropSupport; |
|
86 |
} |
|
87 |
||
88 |
/** |
|
89 |
* Installs a {@code DropTarget} on the component as necessary for a |
|
90 |
* {@code TransferHandler} change. |
|
91 |
*/ |
|
92 |
static void installSwingDropTargetAsNecessary(Component c, |
|
93 |
TransferHandler t) { |
|
94 |
||
95 |
if (!getSuppressDropTarget()) { |
|
96 |
DropTarget dropHandler = c.getDropTarget(); |
|
97 |
if ((dropHandler == null) || (dropHandler instanceof UIResource)) { |
|
98 |
if (t == null) { |
|
99 |
c.setDropTarget(null); |
|
100 |
} else if (!GraphicsEnvironment.isHeadless()) { |
|
101 |
c.setDropTarget(new TransferHandler.SwingDropTarget(c)); |
|
102 |
} |
|
103 |
} |
|
104 |
} |
|
105 |
} |
|
106 |
||
107 |
/** |
|
108 |
* Return true if <code>a</code> contains <code>b</code> |
|
109 |
*/ |
|
110 |
public static final boolean isRectangleContainingRectangle(Rectangle a,Rectangle b) { |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
111 |
return b.x >= a.x && (b.x + b.width) <= (a.x + a.width) && |
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
112 |
b.y >= a.y && (b.y + b.height) <= (a.y + a.height); |
2 | 113 |
} |
114 |
||
115 |
/** |
|
116 |
* Return the rectangle (0,0,bounds.width,bounds.height) for the component <code>aComponent</code> |
|
117 |
*/ |
|
118 |
public static Rectangle getLocalBounds(Component aComponent) { |
|
119 |
Rectangle b = new Rectangle(aComponent.getBounds()); |
|
120 |
b.x = b.y = 0; |
|
121 |
return b; |
|
122 |
} |
|
123 |
||
124 |
||
125 |
/** |
|
126 |
* Returns the first <code>Window </code> ancestor of <code>c</code>, or |
|
127 |
* {@code null} if <code>c</code> is not contained inside a <code>Window</code>. |
|
128 |
* |
|
129 |
* @param c <code>Component</code> to get <code>Window</code> ancestor |
|
130 |
* of. |
|
131 |
* @return the first <code>Window </code> ancestor of <code>c</code>, or |
|
132 |
* {@code null} if <code>c</code> is not contained inside a |
|
133 |
* <code>Window</code>. |
|
134 |
* @since 1.3 |
|
135 |
*/ |
|
136 |
public static Window getWindowAncestor(Component c) { |
|
137 |
for(Container p = c.getParent(); p != null; p = p.getParent()) { |
|
138 |
if (p instanceof Window) { |
|
139 |
return (Window)p; |
|
140 |
} |
|
141 |
} |
|
142 |
return null; |
|
143 |
} |
|
144 |
||
145 |
/** |
|
146 |
* Converts the location <code>x</code> <code>y</code> to the |
|
147 |
* parents coordinate system, returning the location. |
|
148 |
*/ |
|
149 |
static Point convertScreenLocationToParent(Container parent,int x, int y) { |
|
150 |
for (Container p = parent; p != null; p = p.getParent()) { |
|
151 |
if (p instanceof Window) { |
|
152 |
Point point = new Point(x, y); |
|
153 |
||
154 |
SwingUtilities.convertPointFromScreen(point, parent); |
|
155 |
return point; |
|
156 |
} |
|
157 |
} |
|
158 |
throw new Error("convertScreenLocationToParent: no window ancestor"); |
|
159 |
} |
|
160 |
||
161 |
/** |
|
162 |
* Convert a <code>aPoint</code> in <code>source</code> coordinate system to |
|
163 |
* <code>destination</code> coordinate system. |
|
164 |
* If <code>source</code> is {@code null}, <code>aPoint</code> is assumed to be in <code>destination</code>'s |
|
165 |
* root component coordinate system. |
|
166 |
* If <code>destination</code> is {@code null}, <code>aPoint</code> will be converted to <code>source</code>'s |
|
167 |
* root component coordinate system. |
|
168 |
* If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aPoint</code> |
|
169 |
* without any conversion. |
|
170 |
*/ |
|
171 |
public static Point convertPoint(Component source,Point aPoint,Component destination) { |
|
172 |
Point p; |
|
173 |
||
174 |
if(source == null && destination == null) |
|
175 |
return aPoint; |
|
176 |
if(source == null) { |
|
177 |
source = getWindowAncestor(destination); |
|
178 |
if(source == null) |
|
179 |
throw new Error("Source component not connected to component tree hierarchy"); |
|
180 |
} |
|
181 |
p = new Point(aPoint); |
|
182 |
convertPointToScreen(p,source); |
|
183 |
if(destination == null) { |
|
184 |
destination = getWindowAncestor(source); |
|
185 |
if(destination == null) |
|
186 |
throw new Error("Destination component not connected to component tree hierarchy"); |
|
187 |
} |
|
188 |
convertPointFromScreen(p,destination); |
|
189 |
return p; |
|
190 |
} |
|
191 |
||
192 |
/** |
|
193 |
* Convert the point <code>(x,y)</code> in <code>source</code> coordinate system to |
|
194 |
* <code>destination</code> coordinate system. |
|
195 |
* If <code>source</code> is {@code null}, <code>(x,y)</code> is assumed to be in <code>destination</code>'s |
|
196 |
* root component coordinate system. |
|
197 |
* If <code>destination</code> is {@code null}, <code>(x,y)</code> will be converted to <code>source</code>'s |
|
198 |
* root component coordinate system. |
|
199 |
* If both <code>source</code> and <code>destination</code> are {@code null}, return <code>(x,y)</code> |
|
200 |
* without any conversion. |
|
201 |
*/ |
|
202 |
public static Point convertPoint(Component source,int x, int y,Component destination) { |
|
203 |
Point point = new Point(x,y); |
|
204 |
return convertPoint(source,point,destination); |
|
205 |
} |
|
206 |
||
207 |
/** |
|
208 |
* Convert the rectangle <code>aRectangle</code> in <code>source</code> coordinate system to |
|
209 |
* <code>destination</code> coordinate system. |
|
210 |
* If <code>source</code> is {@code null}, <code>aRectangle</code> is assumed to be in <code>destination</code>'s |
|
211 |
* root component coordinate system. |
|
212 |
* If <code>destination</code> is {@code null}, <code>aRectangle</code> will be converted to <code>source</code>'s |
|
213 |
* root component coordinate system. |
|
214 |
* If both <code>source</code> and <code>destination</code> are {@code null}, return <code>aRectangle</code> |
|
215 |
* without any conversion. |
|
216 |
*/ |
|
217 |
public static Rectangle convertRectangle(Component source,Rectangle aRectangle,Component destination) { |
|
218 |
Point point = new Point(aRectangle.x,aRectangle.y); |
|
219 |
point = convertPoint(source,point,destination); |
|
220 |
return new Rectangle(point.x,point.y,aRectangle.width,aRectangle.height); |
|
221 |
} |
|
222 |
||
223 |
/** |
|
224 |
* Convenience method for searching above <code>comp</code> in the |
|
225 |
* component hierarchy and returns the first object of class <code>c</code> it |
|
226 |
* finds. Can return {@code null}, if a class <code>c</code> cannot be found. |
|
227 |
*/ |
|
228 |
public static Container getAncestorOfClass(Class<?> c, Component comp) |
|
229 |
{ |
|
230 |
if(comp == null || c == null) |
|
231 |
return null; |
|
232 |
||
233 |
Container parent = comp.getParent(); |
|
234 |
while(parent != null && !(c.isInstance(parent))) |
|
235 |
parent = parent.getParent(); |
|
236 |
return parent; |
|
237 |
} |
|
238 |
||
239 |
/** |
|
240 |
* Convenience method for searching above <code>comp</code> in the |
|
241 |
* component hierarchy and returns the first object of <code>name</code> it |
|
242 |
* finds. Can return {@code null}, if <code>name</code> cannot be found. |
|
243 |
*/ |
|
244 |
public static Container getAncestorNamed(String name, Component comp) { |
|
245 |
if(comp == null || name == null) |
|
246 |
return null; |
|
247 |
||
248 |
Container parent = comp.getParent(); |
|
249 |
while(parent != null && !(name.equals(parent.getName()))) |
|
250 |
parent = parent.getParent(); |
|
251 |
return parent; |
|
252 |
} |
|
253 |
||
254 |
/** |
|
255 |
* Returns the deepest visible descendent Component of <code>parent</code> |
|
256 |
* that contains the location <code>x</code>, <code>y</code>. |
|
257 |
* If <code>parent</code> does not contain the specified location, |
|
258 |
* then <code>null</code> is returned. If <code>parent</code> is not a |
|
259 |
* container, or none of <code>parent</code>'s visible descendents |
|
260 |
* contain the specified location, <code>parent</code> is returned. |
|
261 |
* |
|
262 |
* @param parent the root component to begin the search |
|
263 |
* @param x the x target location |
|
264 |
* @param y the y target location |
|
265 |
*/ |
|
266 |
public static Component getDeepestComponentAt(Component parent, int x, int y) { |
|
267 |
if (!parent.contains(x, y)) { |
|
268 |
return null; |
|
269 |
} |
|
270 |
if (parent instanceof Container) { |
|
271 |
Component components[] = ((Container)parent).getComponents(); |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
272 |
for (Component comp : components) { |
2 | 273 |
if (comp != null && comp.isVisible()) { |
274 |
Point loc = comp.getLocation(); |
|
275 |
if (comp instanceof Container) { |
|
276 |
comp = getDeepestComponentAt(comp, x - loc.x, y - loc.y); |
|
277 |
} else { |
|
278 |
comp = comp.getComponentAt(x - loc.x, y - loc.y); |
|
279 |
} |
|
280 |
if (comp != null && comp.isVisible()) { |
|
281 |
return comp; |
|
282 |
} |
|
283 |
} |
|
284 |
} |
|
285 |
} |
|
286 |
return parent; |
|
287 |
} |
|
288 |
||
289 |
||
290 |
/** |
|
291 |
* Returns a MouseEvent similar to <code>sourceEvent</code> except that its x |
|
292 |
* and y members have been converted to <code>destination</code>'s coordinate |
|
293 |
* system. If <code>source</code> is {@code null}, <code>sourceEvent</code> x and y members |
|
294 |
* are assumed to be into <code>destination</code>'s root component coordinate system. |
|
295 |
* If <code>destination</code> is <code>null</code>, the |
|
296 |
* returned MouseEvent will be in <code>source</code>'s coordinate system. |
|
297 |
* <code>sourceEvent</code> will not be changed. A new event is returned. |
|
298 |
* the <code>source</code> field of the returned event will be set |
|
299 |
* to <code>destination</code> if destination is non-{@code null} |
|
300 |
* use the translateMouseEvent() method to translate a mouse event from |
|
301 |
* one component to another without changing the source. |
|
302 |
*/ |
|
303 |
public static MouseEvent convertMouseEvent(Component source, |
|
304 |
MouseEvent sourceEvent, |
|
305 |
Component destination) { |
|
306 |
Point p = convertPoint(source,new Point(sourceEvent.getX(), |
|
307 |
sourceEvent.getY()), |
|
308 |
destination); |
|
309 |
Component newSource; |
|
310 |
||
311 |
if(destination != null) |
|
312 |
newSource = destination; |
|
313 |
else |
|
314 |
newSource = source; |
|
315 |
||
316 |
MouseEvent newEvent; |
|
317 |
if (sourceEvent instanceof MouseWheelEvent) { |
|
318 |
MouseWheelEvent sourceWheelEvent = (MouseWheelEvent)sourceEvent; |
|
319 |
newEvent = new MouseWheelEvent(newSource, |
|
320 |
sourceWheelEvent.getID(), |
|
321 |
sourceWheelEvent.getWhen(), |
|
13238
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
322 |
sourceWheelEvent.getModifiers() |
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
323 |
| sourceWheelEvent.getModifiersEx(), |
2 | 324 |
p.x,p.y, |
325 |
sourceWheelEvent.getXOnScreen(), |
|
326 |
sourceWheelEvent.getYOnScreen(), |
|
327 |
sourceWheelEvent.getClickCount(), |
|
328 |
sourceWheelEvent.isPopupTrigger(), |
|
329 |
sourceWheelEvent.getScrollType(), |
|
330 |
sourceWheelEvent.getScrollAmount(), |
|
331 |
sourceWheelEvent.getWheelRotation()); |
|
332 |
} |
|
333 |
else if (sourceEvent instanceof MenuDragMouseEvent) { |
|
334 |
MenuDragMouseEvent sourceMenuDragEvent = (MenuDragMouseEvent)sourceEvent; |
|
335 |
newEvent = new MenuDragMouseEvent(newSource, |
|
336 |
sourceMenuDragEvent.getID(), |
|
337 |
sourceMenuDragEvent.getWhen(), |
|
13238
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
338 |
sourceMenuDragEvent.getModifiers() |
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
339 |
| sourceMenuDragEvent.getModifiersEx(), |
2 | 340 |
p.x,p.y, |
341 |
sourceMenuDragEvent.getXOnScreen(), |
|
342 |
sourceMenuDragEvent.getYOnScreen(), |
|
343 |
sourceMenuDragEvent.getClickCount(), |
|
344 |
sourceMenuDragEvent.isPopupTrigger(), |
|
345 |
sourceMenuDragEvent.getPath(), |
|
346 |
sourceMenuDragEvent.getMenuSelectionManager()); |
|
347 |
} |
|
348 |
else { |
|
349 |
newEvent = new MouseEvent(newSource, |
|
350 |
sourceEvent.getID(), |
|
351 |
sourceEvent.getWhen(), |
|
13238
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
352 |
sourceEvent.getModifiers() |
b045f9da27b2
7170657: [macosx] There seems to be no keyboard/mouse action to select non-contiguous items in List
serb
parents:
12034
diff
changeset
|
353 |
| sourceEvent.getModifiersEx(), |
2 | 354 |
p.x,p.y, |
355 |
sourceEvent.getXOnScreen(), |
|
356 |
sourceEvent.getYOnScreen(), |
|
357 |
sourceEvent.getClickCount(), |
|
358 |
sourceEvent.isPopupTrigger(), |
|
15991
848515979585
7194902: [macosx] closed/java/awt/Button/DoubleActionEventTest/DoubleActionEventTest failed since jdk8b49
serb
parents:
13238
diff
changeset
|
359 |
sourceEvent.getButton()); |
2 | 360 |
} |
361 |
return newEvent; |
|
362 |
} |
|
363 |
||
364 |
||
365 |
/** |
|
366 |
* Convert a point from a component's coordinate system to |
|
367 |
* screen coordinates. |
|
368 |
* |
|
369 |
* @param p a Point object (converted to the new coordinate system) |
|
370 |
* @param c a Component object |
|
371 |
*/ |
|
372 |
public static void convertPointToScreen(Point p,Component c) { |
|
373 |
Rectangle b; |
|
374 |
int x,y; |
|
375 |
||
376 |
do { |
|
377 |
if(c instanceof JComponent) { |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
378 |
x = c.getX(); |
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
379 |
y = c.getY(); |
2 | 380 |
} else if(c instanceof java.applet.Applet || |
381 |
c instanceof java.awt.Window) { |
|
382 |
try { |
|
383 |
Point pp = c.getLocationOnScreen(); |
|
384 |
x = pp.x; |
|
385 |
y = pp.y; |
|
386 |
} catch (IllegalComponentStateException icse) { |
|
387 |
x = c.getX(); |
|
388 |
y = c.getY(); |
|
389 |
} |
|
390 |
} else { |
|
391 |
x = c.getX(); |
|
392 |
y = c.getY(); |
|
393 |
} |
|
394 |
||
395 |
p.x += x; |
|
396 |
p.y += y; |
|
397 |
||
398 |
if(c instanceof java.awt.Window || c instanceof java.applet.Applet) |
|
399 |
break; |
|
400 |
c = c.getParent(); |
|
401 |
} while(c != null); |
|
402 |
} |
|
403 |
||
404 |
/** |
|
405 |
* Convert a point from a screen coordinates to a component's |
|
406 |
* coordinate system |
|
407 |
* |
|
408 |
* @param p a Point object (converted to the new coordinate system) |
|
409 |
* @param c a Component object |
|
410 |
*/ |
|
411 |
public static void convertPointFromScreen(Point p,Component c) { |
|
412 |
Rectangle b; |
|
413 |
int x,y; |
|
414 |
||
415 |
do { |
|
416 |
if(c instanceof JComponent) { |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
417 |
x = c.getX(); |
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
418 |
y = c.getY(); |
2 | 419 |
} else if(c instanceof java.applet.Applet || |
420 |
c instanceof java.awt.Window) { |
|
421 |
try { |
|
422 |
Point pp = c.getLocationOnScreen(); |
|
423 |
x = pp.x; |
|
424 |
y = pp.y; |
|
425 |
} catch (IllegalComponentStateException icse) { |
|
426 |
x = c.getX(); |
|
427 |
y = c.getY(); |
|
428 |
} |
|
429 |
} else { |
|
430 |
x = c.getX(); |
|
431 |
y = c.getY(); |
|
432 |
} |
|
433 |
||
434 |
p.x -= x; |
|
435 |
p.y -= y; |
|
436 |
||
437 |
if(c instanceof java.awt.Window || c instanceof java.applet.Applet) |
|
438 |
break; |
|
439 |
c = c.getParent(); |
|
440 |
} while(c != null); |
|
441 |
} |
|
442 |
||
443 |
/** |
|
444 |
* Returns the first <code>Window </code> ancestor of <code>c</code>, or |
|
445 |
* {@code null} if <code>c</code> is not contained inside a <code>Window</code>. |
|
446 |
* <p> |
|
447 |
* Note: This method provides the same functionality as |
|
448 |
* <code>getWindowAncestor</code>. |
|
449 |
* |
|
450 |
* @param c <code>Component</code> to get <code>Window</code> ancestor |
|
451 |
* of. |
|
452 |
* @return the first <code>Window </code> ancestor of <code>c</code>, or |
|
453 |
* {@code null} if <code>c</code> is not contained inside a |
|
454 |
* <code>Window</code>. |
|
455 |
*/ |
|
456 |
public static Window windowForComponent(Component c) { |
|
457 |
return getWindowAncestor(c); |
|
458 |
} |
|
459 |
||
460 |
/** |
|
461 |
* Return <code>true</code> if a component <code>a</code> descends from a component <code>b</code> |
|
462 |
*/ |
|
463 |
public static boolean isDescendingFrom(Component a,Component b) { |
|
464 |
if(a == b) |
|
465 |
return true; |
|
466 |
for(Container p = a.getParent();p!=null;p=p.getParent()) |
|
467 |
if(p == b) |
|
468 |
return true; |
|
469 |
return false; |
|
470 |
} |
|
471 |
||
472 |
||
473 |
/** |
|
474 |
* Convenience to calculate the intersection of two rectangles |
|
475 |
* without allocating a new rectangle. |
|
476 |
* If the two rectangles don't intersect, |
|
477 |
* then the returned rectangle begins at (0,0) |
|
478 |
* and has zero width and height. |
|
479 |
* |
|
480 |
* @param x the X coordinate of the first rectangle's top-left point |
|
481 |
* @param y the Y coordinate of the first rectangle's top-left point |
|
482 |
* @param width the width of the first rectangle |
|
483 |
* @param height the height of the first rectangle |
|
484 |
* @param dest the second rectangle |
|
485 |
* |
|
486 |
* @return <code>dest</code>, modified to specify the intersection |
|
487 |
*/ |
|
488 |
public static Rectangle computeIntersection(int x,int y,int width,int height,Rectangle dest) { |
|
489 |
int x1 = (x > dest.x) ? x : dest.x; |
|
490 |
int x2 = ((x+width) < (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width); |
|
491 |
int y1 = (y > dest.y) ? y : dest.y; |
|
492 |
int y2 = ((y + height) < (dest.y + dest.height) ? (y+height) : (dest.y + dest.height)); |
|
493 |
||
494 |
dest.x = x1; |
|
495 |
dest.y = y1; |
|
496 |
dest.width = x2 - x1; |
|
497 |
dest.height = y2 - y1; |
|
498 |
||
499 |
// If rectangles don't intersect, return zero'd intersection. |
|
500 |
if (dest.width < 0 || dest.height < 0) { |
|
501 |
dest.x = dest.y = dest.width = dest.height = 0; |
|
502 |
} |
|
503 |
||
504 |
return dest; |
|
505 |
} |
|
506 |
||
507 |
/** |
|
508 |
* Convenience method that calculates the union of two rectangles |
|
509 |
* without allocating a new rectangle. |
|
510 |
* |
|
511 |
* @param x the x-coordinate of the first rectangle |
|
512 |
* @param y the y-coordinate of the first rectangle |
|
513 |
* @param width the width of the first rectangle |
|
514 |
* @param height the height of the first rectangle |
|
515 |
* @param dest the coordinates of the second rectangle; the union |
|
516 |
* of the two rectangles is returned in this rectangle |
|
517 |
* @return the <code>dest</code> <code>Rectangle</code> |
|
518 |
*/ |
|
519 |
public static Rectangle computeUnion(int x,int y,int width,int height,Rectangle dest) { |
|
520 |
int x1 = (x < dest.x) ? x : dest.x; |
|
521 |
int x2 = ((x+width) > (dest.x + dest.width)) ? (x+width) : (dest.x + dest.width); |
|
522 |
int y1 = (y < dest.y) ? y : dest.y; |
|
523 |
int y2 = ((y+height) > (dest.y + dest.height)) ? (y+height) : (dest.y + dest.height); |
|
524 |
||
525 |
dest.x = x1; |
|
526 |
dest.y = y1; |
|
527 |
dest.width = (x2 - x1); |
|
528 |
dest.height= (y2 - y1); |
|
529 |
return dest; |
|
530 |
} |
|
531 |
||
532 |
/** |
|
533 |
* Convenience returning an array of rect representing the regions within |
|
534 |
* <code>rectA</code> that do not overlap with <code>rectB</code>. If the |
|
535 |
* two Rects do not overlap, returns an empty array |
|
536 |
*/ |
|
537 |
public static Rectangle[] computeDifference(Rectangle rectA,Rectangle rectB) { |
|
538 |
if (rectB == null || !rectA.intersects(rectB) || isRectangleContainingRectangle(rectB,rectA)) { |
|
539 |
return new Rectangle[0]; |
|
540 |
} |
|
541 |
||
542 |
Rectangle t = new Rectangle(); |
|
543 |
Rectangle a=null,b=null,c=null,d=null; |
|
544 |
Rectangle result[]; |
|
545 |
int rectCount = 0; |
|
546 |
||
547 |
/* rectA contains rectB */ |
|
548 |
if (isRectangleContainingRectangle(rectA,rectB)) { |
|
549 |
t.x = rectA.x; t.y = rectA.y; t.width = rectB.x - rectA.x; t.height = rectA.height; |
|
550 |
if(t.width > 0 && t.height > 0) { |
|
551 |
a = new Rectangle(t); |
|
552 |
rectCount++; |
|
553 |
} |
|
554 |
||
555 |
t.x = rectB.x; t.y = rectA.y; t.width = rectB.width; t.height = rectB.y - rectA.y; |
|
556 |
if(t.width > 0 && t.height > 0) { |
|
557 |
b = new Rectangle(t); |
|
558 |
rectCount++; |
|
559 |
} |
|
560 |
||
561 |
t.x = rectB.x; t.y = rectB.y + rectB.height; t.width = rectB.width; |
|
562 |
t.height = rectA.y + rectA.height - (rectB.y + rectB.height); |
|
563 |
if(t.width > 0 && t.height > 0) { |
|
564 |
c = new Rectangle(t); |
|
565 |
rectCount++; |
|
566 |
} |
|
567 |
||
568 |
t.x = rectB.x + rectB.width; t.y = rectA.y; t.width = rectA.x + rectA.width - (rectB.x + rectB.width); |
|
569 |
t.height = rectA.height; |
|
570 |
if(t.width > 0 && t.height > 0) { |
|
571 |
d = new Rectangle(t); |
|
572 |
rectCount++; |
|
573 |
} |
|
574 |
} else { |
|
575 |
/* 1 */ |
|
576 |
if (rectB.x <= rectA.x && rectB.y <= rectA.y) { |
|
577 |
if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) { |
|
578 |
||
579 |
t.x = rectA.x; t.y = rectB.y + rectB.height; |
|
580 |
t.width = rectA.width; t.height = rectA.y + rectA.height - (rectB.y + rectB.height); |
|
581 |
if(t.width > 0 && t.height > 0) { |
|
582 |
a = t; |
|
583 |
rectCount++; |
|
584 |
} |
|
585 |
} else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) { |
|
586 |
t.setBounds((rectB.x + rectB.width), rectA.y, |
|
587 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height); |
|
588 |
if(t.width > 0 && t.height > 0) { |
|
589 |
a = t; |
|
590 |
rectCount++; |
|
591 |
} |
|
592 |
} else { |
|
593 |
t.setBounds((rectB.x + rectB.width), rectA.y, |
|
594 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), |
|
595 |
(rectB.y + rectB.height) - rectA.y); |
|
596 |
if(t.width > 0 && t.height > 0) { |
|
597 |
a = new Rectangle(t); |
|
598 |
rectCount++; |
|
599 |
} |
|
600 |
||
601 |
t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width, |
|
602 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
603 |
if(t.width > 0 && t.height > 0) { |
|
604 |
b = new Rectangle(t); |
|
605 |
rectCount++; |
|
606 |
} |
|
607 |
} |
|
608 |
} else if (rectB.x <= rectA.x && (rectB.y + rectB.height) >= (rectA.y + rectA.height)) { |
|
609 |
if ((rectB.x + rectB.width) > (rectA.x + rectA.width)) { |
|
610 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
611 |
if(t.width > 0 && t.height > 0) { |
|
612 |
a = t; |
|
613 |
rectCount++; |
|
614 |
} |
|
615 |
} else { |
|
616 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
617 |
if(t.width > 0 && t.height > 0) { |
|
618 |
a = new Rectangle(t); |
|
619 |
rectCount++; |
|
620 |
} |
|
621 |
t.setBounds((rectB.x + rectB.width), rectB.y, |
|
622 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), |
|
623 |
(rectA.y + rectA.height) - rectB.y); |
|
624 |
if(t.width > 0 && t.height > 0) { |
|
625 |
b = new Rectangle(t); |
|
626 |
rectCount++; |
|
627 |
} |
|
628 |
} |
|
629 |
} else if (rectB.x <= rectA.x) { |
|
630 |
if ((rectB.x + rectB.width) >= (rectA.x + rectA.width)) { |
|
631 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
632 |
if(t.width>0 && t.height > 0) { |
|
633 |
a = new Rectangle(t); |
|
634 |
rectCount++; |
|
635 |
} |
|
636 |
||
637 |
t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width, |
|
638 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
639 |
if(t.width > 0 && t.height > 0) { |
|
640 |
b = new Rectangle(t); |
|
641 |
rectCount++; |
|
642 |
} |
|
643 |
} else { |
|
644 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
645 |
if(t.width > 0 && t.height > 0) { |
|
646 |
a = new Rectangle(t); |
|
647 |
rectCount++; |
|
648 |
} |
|
649 |
||
650 |
t.setBounds((rectB.x + rectB.width), rectB.y, |
|
651 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), |
|
652 |
rectB.height); |
|
653 |
if(t.width > 0 && t.height > 0) { |
|
654 |
b = new Rectangle(t); |
|
655 |
rectCount++; |
|
656 |
} |
|
657 |
||
658 |
t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width, |
|
659 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
660 |
if(t.width > 0 && t.height > 0) { |
|
661 |
c = new Rectangle(t); |
|
662 |
rectCount++; |
|
663 |
} |
|
664 |
} |
|
665 |
} else if (rectB.x <= (rectA.x + rectA.width) && (rectB.x + rectB.width) > (rectA.x + rectA.width)) { |
|
666 |
if (rectB.y <= rectA.y && (rectB.y + rectB.height) > (rectA.y + rectA.height)) { |
|
667 |
t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height); |
|
668 |
if(t.width > 0 && t.height > 0) { |
|
669 |
a = t; |
|
670 |
rectCount++; |
|
671 |
} |
|
672 |
} else if (rectB.y <= rectA.y) { |
|
673 |
t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, |
|
674 |
(rectB.y + rectB.height) - rectA.y); |
|
675 |
if(t.width > 0 && t.height > 0) { |
|
676 |
a = new Rectangle(t); |
|
677 |
rectCount++; |
|
678 |
} |
|
679 |
||
680 |
t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width, |
|
681 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
682 |
if(t.width > 0 && t.height > 0) { |
|
683 |
b = new Rectangle(t); |
|
684 |
rectCount++; |
|
685 |
} |
|
686 |
} else if ((rectB.y + rectB.height) > (rectA.y + rectA.height)) { |
|
687 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
688 |
if(t.width > 0 && t.height > 0) { |
|
689 |
a = new Rectangle(t); |
|
690 |
rectCount++; |
|
691 |
} |
|
692 |
||
693 |
t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x, |
|
694 |
(rectA.y + rectA.height) - rectB.y); |
|
695 |
if(t.width > 0 && t.height > 0) { |
|
696 |
b = new Rectangle(t); |
|
697 |
rectCount++; |
|
698 |
} |
|
699 |
} else { |
|
700 |
t.setBounds(rectA.x, rectA.y, rectA.width, rectB.y - rectA.y); |
|
701 |
if(t.width > 0 && t.height > 0) { |
|
702 |
a = new Rectangle(t); |
|
703 |
rectCount++; |
|
704 |
} |
|
705 |
||
706 |
t.setBounds(rectA.x, rectB.y, rectB.x - rectA.x, |
|
707 |
rectB.height); |
|
708 |
if(t.width > 0 && t.height > 0) { |
|
709 |
b = new Rectangle(t); |
|
710 |
rectCount++; |
|
711 |
} |
|
712 |
||
713 |
t.setBounds(rectA.x, (rectB.y + rectB.height), rectA.width, |
|
714 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
715 |
if(t.width > 0 && t.height > 0) { |
|
716 |
c = new Rectangle(t); |
|
717 |
rectCount++; |
|
718 |
} |
|
719 |
} |
|
720 |
} else if (rectB.x >= rectA.x && (rectB.x + rectB.width) <= (rectA.x + rectA.width)) { |
|
721 |
if (rectB.y <= rectA.y && (rectB.y + rectB.height) > (rectA.y + rectA.height)) { |
|
722 |
t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height); |
|
723 |
if(t.width > 0 && t.height > 0) { |
|
724 |
a = new Rectangle(t); |
|
725 |
rectCount++; |
|
726 |
} |
|
727 |
t.setBounds((rectB.x + rectB.width), rectA.y, |
|
728 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height); |
|
729 |
if(t.width > 0 && t.height > 0) { |
|
730 |
b = new Rectangle(t); |
|
731 |
rectCount++; |
|
732 |
} |
|
733 |
} else if (rectB.y <= rectA.y) { |
|
734 |
t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height); |
|
735 |
if(t.width > 0 && t.height > 0) { |
|
736 |
a = new Rectangle(t); |
|
737 |
rectCount++; |
|
738 |
} |
|
739 |
||
740 |
t.setBounds(rectB.x, (rectB.y + rectB.height), |
|
741 |
rectB.width, |
|
742 |
(rectA.y + rectA.height) - (rectB.y + rectB.height)); |
|
743 |
if(t.width > 0 && t.height > 0) { |
|
744 |
b = new Rectangle(t); |
|
745 |
rectCount++; |
|
746 |
} |
|
747 |
||
748 |
t.setBounds((rectB.x + rectB.width), rectA.y, |
|
749 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height); |
|
750 |
if(t.width > 0 && t.height > 0) { |
|
751 |
c = new Rectangle(t); |
|
752 |
rectCount++; |
|
753 |
} |
|
754 |
} else { |
|
755 |
t.setBounds(rectA.x, rectA.y, rectB.x - rectA.x, rectA.height); |
|
756 |
if(t.width > 0 && t.height > 0) { |
|
757 |
a = new Rectangle(t); |
|
758 |
rectCount++; |
|
759 |
} |
|
760 |
||
761 |
t.setBounds(rectB.x, rectA.y, rectB.width, |
|
762 |
rectB.y - rectA.y); |
|
763 |
if(t.width > 0 && t.height > 0) { |
|
764 |
b = new Rectangle(t); |
|
765 |
rectCount++; |
|
766 |
} |
|
767 |
||
768 |
t.setBounds((rectB.x + rectB.width), rectA.y, |
|
769 |
(rectA.x + rectA.width) - (rectB.x + rectB.width), rectA.height); |
|
770 |
if(t.width > 0 && t.height > 0) { |
|
771 |
c = new Rectangle(t); |
|
772 |
rectCount++; |
|
773 |
} |
|
774 |
} |
|
775 |
} |
|
776 |
} |
|
777 |
||
778 |
result = new Rectangle[rectCount]; |
|
779 |
rectCount = 0; |
|
780 |
if(a != null) |
|
781 |
result[rectCount++] = a; |
|
782 |
if(b != null) |
|
783 |
result[rectCount++] = b; |
|
784 |
if(c != null) |
|
785 |
result[rectCount++] = c; |
|
786 |
if(d != null) |
|
787 |
result[rectCount++] = d; |
|
788 |
return result; |
|
789 |
} |
|
790 |
||
791 |
/** |
|
792 |
* Returns true if the mouse event specifies the left mouse button. |
|
793 |
* |
|
794 |
* @param anEvent a MouseEvent object |
|
795 |
* @return true if the left mouse button was active |
|
796 |
*/ |
|
797 |
public static boolean isLeftMouseButton(MouseEvent anEvent) { |
|
12034
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
798 |
return ((anEvent.getModifiersEx() & InputEvent.BUTTON1_DOWN_MASK) != 0 || |
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
799 |
anEvent.getButton() == MouseEvent.BUTTON1); |
2 | 800 |
} |
801 |
||
802 |
/** |
|
803 |
* Returns true if the mouse event specifies the middle mouse button. |
|
804 |
* |
|
805 |
* @param anEvent a MouseEvent object |
|
806 |
* @return true if the middle mouse button was active |
|
807 |
*/ |
|
808 |
public static boolean isMiddleMouseButton(MouseEvent anEvent) { |
|
12034
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
809 |
return ((anEvent.getModifiersEx() & InputEvent.BUTTON2_DOWN_MASK) != 0 || |
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
810 |
anEvent.getButton() == MouseEvent.BUTTON2); |
2 | 811 |
} |
812 |
||
813 |
/** |
|
814 |
* Returns true if the mouse event specifies the right mouse button. |
|
815 |
* |
|
816 |
* @param anEvent a MouseEvent object |
|
817 |
* @return true if the right mouse button was active |
|
818 |
*/ |
|
819 |
public static boolean isRightMouseButton(MouseEvent anEvent) { |
|
12034
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
820 |
return ((anEvent.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0 || |
9475d47d932e
7146377: closed/javax/swing/DataTransfer/4876520/bug4876520.java failed since b08 in jdk 8
rupashka
parents:
10582
diff
changeset
|
821 |
anEvent.getButton() == MouseEvent.BUTTON3); |
2 | 822 |
} |
823 |
||
824 |
/** |
|
825 |
* Compute the width of the string using a font with the specified |
|
826 |
* "metrics" (sizes). |
|
827 |
* |
|
828 |
* @param fm a FontMetrics object to compute with |
|
829 |
* @param str the String to compute |
|
830 |
* @return an int containing the string width |
|
831 |
*/ |
|
832 |
public static int computeStringWidth(FontMetrics fm,String str) { |
|
833 |
// You can't assume that a string's width is the sum of its |
|
834 |
// characters' widths in Java2D -- it may be smaller due to |
|
835 |
// kerning, etc. |
|
836 |
return SwingUtilities2.stringWidth(null, fm, str); |
|
837 |
} |
|
838 |
||
839 |
/** |
|
840 |
* Compute and return the location of the icons origin, the |
|
841 |
* location of origin of the text baseline, and a possibly clipped |
|
842 |
* version of the compound labels string. Locations are computed |
|
843 |
* relative to the viewR rectangle. |
|
844 |
* The JComponents orientation (LEADING/TRAILING) will also be taken |
|
845 |
* into account and translated into LEFT/RIGHT values accordingly. |
|
846 |
*/ |
|
847 |
public static String layoutCompoundLabel(JComponent c, |
|
848 |
FontMetrics fm, |
|
849 |
String text, |
|
850 |
Icon icon, |
|
851 |
int verticalAlignment, |
|
852 |
int horizontalAlignment, |
|
853 |
int verticalTextPosition, |
|
854 |
int horizontalTextPosition, |
|
855 |
Rectangle viewR, |
|
856 |
Rectangle iconR, |
|
857 |
Rectangle textR, |
|
858 |
int textIconGap) |
|
859 |
{ |
|
860 |
boolean orientationIsLeftToRight = true; |
|
861 |
int hAlign = horizontalAlignment; |
|
862 |
int hTextPos = horizontalTextPosition; |
|
863 |
||
864 |
if (c != null) { |
|
865 |
if (!(c.getComponentOrientation().isLeftToRight())) { |
|
866 |
orientationIsLeftToRight = false; |
|
867 |
} |
|
868 |
} |
|
869 |
||
870 |
// Translate LEADING/TRAILING values in horizontalAlignment |
|
871 |
// to LEFT/RIGHT values depending on the components orientation |
|
872 |
switch (horizontalAlignment) { |
|
873 |
case LEADING: |
|
874 |
hAlign = (orientationIsLeftToRight) ? LEFT : RIGHT; |
|
875 |
break; |
|
876 |
case TRAILING: |
|
877 |
hAlign = (orientationIsLeftToRight) ? RIGHT : LEFT; |
|
878 |
break; |
|
879 |
} |
|
880 |
||
881 |
// Translate LEADING/TRAILING values in horizontalTextPosition |
|
882 |
// to LEFT/RIGHT values depending on the components orientation |
|
883 |
switch (horizontalTextPosition) { |
|
884 |
case LEADING: |
|
885 |
hTextPos = (orientationIsLeftToRight) ? LEFT : RIGHT; |
|
886 |
break; |
|
887 |
case TRAILING: |
|
888 |
hTextPos = (orientationIsLeftToRight) ? RIGHT : LEFT; |
|
889 |
break; |
|
890 |
} |
|
891 |
||
892 |
return layoutCompoundLabelImpl(c, |
|
893 |
fm, |
|
894 |
text, |
|
895 |
icon, |
|
896 |
verticalAlignment, |
|
897 |
hAlign, |
|
898 |
verticalTextPosition, |
|
899 |
hTextPos, |
|
900 |
viewR, |
|
901 |
iconR, |
|
902 |
textR, |
|
903 |
textIconGap); |
|
904 |
} |
|
905 |
||
906 |
/** |
|
907 |
* Compute and return the location of the icons origin, the |
|
908 |
* location of origin of the text baseline, and a possibly clipped |
|
909 |
* version of the compound labels string. Locations are computed |
|
910 |
* relative to the viewR rectangle. |
|
911 |
* This layoutCompoundLabel() does not know how to handle LEADING/TRAILING |
|
912 |
* values in horizontalTextPosition (they will default to RIGHT) and in |
|
913 |
* horizontalAlignment (they will default to CENTER). |
|
914 |
* Use the other version of layoutCompoundLabel() instead. |
|
915 |
*/ |
|
916 |
public static String layoutCompoundLabel( |
|
917 |
FontMetrics fm, |
|
918 |
String text, |
|
919 |
Icon icon, |
|
920 |
int verticalAlignment, |
|
921 |
int horizontalAlignment, |
|
922 |
int verticalTextPosition, |
|
923 |
int horizontalTextPosition, |
|
924 |
Rectangle viewR, |
|
925 |
Rectangle iconR, |
|
926 |
Rectangle textR, |
|
927 |
int textIconGap) |
|
928 |
{ |
|
929 |
return layoutCompoundLabelImpl(null, fm, text, icon, |
|
930 |
verticalAlignment, |
|
931 |
horizontalAlignment, |
|
932 |
verticalTextPosition, |
|
933 |
horizontalTextPosition, |
|
934 |
viewR, iconR, textR, textIconGap); |
|
935 |
} |
|
936 |
||
937 |
/** |
|
938 |
* Compute and return the location of the icons origin, the |
|
939 |
* location of origin of the text baseline, and a possibly clipped |
|
940 |
* version of the compound labels string. Locations are computed |
|
941 |
* relative to the viewR rectangle. |
|
942 |
* This layoutCompoundLabel() does not know how to handle LEADING/TRAILING |
|
943 |
* values in horizontalTextPosition (they will default to RIGHT) and in |
|
944 |
* horizontalAlignment (they will default to CENTER). |
|
945 |
* Use the other version of layoutCompoundLabel() instead. |
|
946 |
*/ |
|
947 |
private static String layoutCompoundLabelImpl( |
|
948 |
JComponent c, |
|
949 |
FontMetrics fm, |
|
950 |
String text, |
|
951 |
Icon icon, |
|
952 |
int verticalAlignment, |
|
953 |
int horizontalAlignment, |
|
954 |
int verticalTextPosition, |
|
955 |
int horizontalTextPosition, |
|
956 |
Rectangle viewR, |
|
957 |
Rectangle iconR, |
|
958 |
Rectangle textR, |
|
959 |
int textIconGap) |
|
960 |
{ |
|
961 |
/* Initialize the icon bounds rectangle iconR. |
|
962 |
*/ |
|
963 |
||
964 |
if (icon != null) { |
|
965 |
iconR.width = icon.getIconWidth(); |
|
966 |
iconR.height = icon.getIconHeight(); |
|
967 |
} |
|
968 |
else { |
|
969 |
iconR.width = iconR.height = 0; |
|
970 |
} |
|
971 |
||
972 |
/* Initialize the text bounds rectangle textR. If a null |
|
973 |
* or and empty String was specified we substitute "" here |
|
974 |
* and use 0,0,0,0 for textR. |
|
975 |
*/ |
|
976 |
||
977 |
boolean textIsEmpty = (text == null) || text.equals(""); |
|
978 |
int lsb = 0; |
|
1295
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
979 |
int rsb = 0; |
2 | 980 |
/* Unless both text and icon are non-null, we effectively ignore |
981 |
* the value of textIconGap. |
|
982 |
*/ |
|
983 |
int gap; |
|
984 |
||
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
985 |
View v; |
2 | 986 |
if (textIsEmpty) { |
987 |
textR.width = textR.height = 0; |
|
988 |
text = ""; |
|
989 |
gap = 0; |
|
990 |
} |
|
991 |
else { |
|
992 |
int availTextWidth; |
|
993 |
gap = (icon == null) ? 0 : textIconGap; |
|
994 |
||
995 |
if (horizontalTextPosition == CENTER) { |
|
996 |
availTextWidth = viewR.width; |
|
997 |
} |
|
998 |
else { |
|
999 |
availTextWidth = viewR.width - (iconR.width + gap); |
|
1000 |
} |
|
1001 |
v = (c != null) ? (View) c.getClientProperty("html") : null; |
|
1002 |
if (v != null) { |
|
1003 |
textR.width = Math.min(availTextWidth, |
|
1004 |
(int) v.getPreferredSpan(View.X_AXIS)); |
|
1005 |
textR.height = (int) v.getPreferredSpan(View.Y_AXIS); |
|
1006 |
} else { |
|
1007 |
textR.width = SwingUtilities2.stringWidth(c, fm, text); |
|
1008 |
lsb = SwingUtilities2.getLeftSideBearing(c, fm, text); |
|
1009 |
if (lsb < 0) { |
|
3749
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1010 |
// If lsb is negative, add it to the width and later |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1011 |
// adjust the x location. This gives more space than is |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1012 |
// actually needed. |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1013 |
// This is done like this for two reasons: |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1014 |
// 1. If we set the width to the actual bounds all |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1015 |
// callers would have to account for negative lsb |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1016 |
// (pref size calculations ONLY look at width of |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1017 |
// textR) |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1018 |
// 2. You can do a drawString at the returned location |
d0ecbd7075b1
6797139: JButton title is truncating for some strings irrespective of preferred size.
alexp
parents:
2473
diff
changeset
|
1019 |
// and the text won't be clipped. |
2 | 1020 |
textR.width -= lsb; |
1021 |
} |
|
1022 |
if (textR.width > availTextWidth) { |
|
1023 |
text = SwingUtilities2.clipString(c, fm, text, |
|
1024 |
availTextWidth); |
|
1025 |
textR.width = SwingUtilities2.stringWidth(c, fm, text); |
|
1026 |
} |
|
1027 |
textR.height = fm.getHeight(); |
|
1028 |
} |
|
1029 |
} |
|
1030 |
||
1031 |
||
1032 |
/* Compute textR.x,y given the verticalTextPosition and |
|
1033 |
* horizontalTextPosition properties |
|
1034 |
*/ |
|
1035 |
||
1036 |
if (verticalTextPosition == TOP) { |
|
1037 |
if (horizontalTextPosition != CENTER) { |
|
1038 |
textR.y = 0; |
|
1039 |
} |
|
1040 |
else { |
|
1041 |
textR.y = -(textR.height + gap); |
|
1042 |
} |
|
1043 |
} |
|
1044 |
else if (verticalTextPosition == CENTER) { |
|
1045 |
textR.y = (iconR.height / 2) - (textR.height / 2); |
|
1046 |
} |
|
1047 |
else { // (verticalTextPosition == BOTTOM) |
|
1048 |
if (horizontalTextPosition != CENTER) { |
|
1049 |
textR.y = iconR.height - textR.height; |
|
1050 |
} |
|
1051 |
else { |
|
1052 |
textR.y = (iconR.height + gap); |
|
1053 |
} |
|
1054 |
} |
|
1055 |
||
1056 |
if (horizontalTextPosition == LEFT) { |
|
1057 |
textR.x = -(textR.width + gap); |
|
1058 |
} |
|
1059 |
else if (horizontalTextPosition == CENTER) { |
|
1060 |
textR.x = (iconR.width / 2) - (textR.width / 2); |
|
1061 |
} |
|
1062 |
else { // (horizontalTextPosition == RIGHT) |
|
1063 |
textR.x = (iconR.width + gap); |
|
1064 |
} |
|
1065 |
||
1066 |
// WARNING: DefaultTreeCellEditor uses a shortened version of |
|
1067 |
// this algorithm to position it's Icon. If you change how this |
|
1068 |
// is calculated, be sure and update DefaultTreeCellEditor too. |
|
1069 |
||
1070 |
/* labelR is the rectangle that contains iconR and textR. |
|
1071 |
* Move it to its proper position given the labelAlignment |
|
1072 |
* properties. |
|
1073 |
* |
|
1074 |
* To avoid actually allocating a Rectangle, Rectangle.union |
|
1075 |
* has been inlined below. |
|
1076 |
*/ |
|
1077 |
int labelR_x = Math.min(iconR.x, textR.x); |
|
1078 |
int labelR_width = Math.max(iconR.x + iconR.width, |
|
1079 |
textR.x + textR.width) - labelR_x; |
|
1080 |
int labelR_y = Math.min(iconR.y, textR.y); |
|
1081 |
int labelR_height = Math.max(iconR.y + iconR.height, |
|
1082 |
textR.y + textR.height) - labelR_y; |
|
1083 |
||
1084 |
int dx, dy; |
|
1085 |
||
1086 |
if (verticalAlignment == TOP) { |
|
1087 |
dy = viewR.y - labelR_y; |
|
1088 |
} |
|
1089 |
else if (verticalAlignment == CENTER) { |
|
1090 |
dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2)); |
|
1091 |
} |
|
1092 |
else { // (verticalAlignment == BOTTOM) |
|
1093 |
dy = (viewR.y + viewR.height) - (labelR_y + labelR_height); |
|
1094 |
} |
|
1095 |
||
1096 |
if (horizontalAlignment == LEFT) { |
|
1097 |
dx = viewR.x - labelR_x; |
|
1098 |
} |
|
1099 |
else if (horizontalAlignment == RIGHT) { |
|
1100 |
dx = (viewR.x + viewR.width) - (labelR_x + labelR_width); |
|
1101 |
} |
|
1102 |
else { // (horizontalAlignment == CENTER) |
|
1103 |
dx = (viewR.x + (viewR.width / 2)) - |
|
1104 |
(labelR_x + (labelR_width / 2)); |
|
1105 |
} |
|
1106 |
||
1107 |
/* Translate textR and glypyR by dx,dy. |
|
1108 |
*/ |
|
1109 |
||
1110 |
textR.x += dx; |
|
1111 |
textR.y += dy; |
|
1112 |
||
1113 |
iconR.x += dx; |
|
1114 |
iconR.y += dy; |
|
1115 |
||
1116 |
if (lsb < 0) { |
|
1117 |
// lsb is negative. Shift the x location so that the text is |
|
1118 |
// visually drawn at the right location. |
|
1119 |
textR.x -= lsb; |
|
1295
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
1120 |
|
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
1121 |
textR.width += lsb; |
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
1122 |
} |
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
1123 |
if (rsb > 0) { |
3cf2264a5743
6584657: GTK Look and Feel: Bugs in menu item layout
mlapshin
parents:
2
diff
changeset
|
1124 |
textR.width -= rsb; |
2 | 1125 |
} |
1126 |
||
1127 |
return text; |
|
1128 |
} |
|
1129 |
||
1130 |
||
1131 |
/** |
|
1132 |
* Paints a component to the specified <code>Graphics</code>. |
|
1133 |
* This method is primarily useful to render |
|
1134 |
* <code>Component</code>s that don't exist as part of the visible |
|
1135 |
* containment hierarchy, but are used for rendering. For |
|
1136 |
* example, if you are doing your own rendering and want to render |
|
1137 |
* some text (or even HTML), you could make use of |
|
1138 |
* <code>JLabel</code>'s text rendering support and have it paint |
|
1139 |
* directly by way of this method, without adding the label to the |
|
1140 |
* visible containment hierarchy. |
|
1141 |
* <p> |
|
1142 |
* This method makes use of <code>CellRendererPane</code> to handle |
|
1143 |
* the actual painting, and is only recommended if you use one |
|
1144 |
* component for rendering. If you make use of multiple components |
|
1145 |
* to handle the rendering, as <code>JTable</code> does, use |
|
1146 |
* <code>CellRendererPane</code> directly. Otherwise, as described |
|
1147 |
* below, you could end up with a <code>CellRendererPane</code> |
|
1148 |
* per <code>Component</code>. |
|
1149 |
* <p> |
|
1150 |
* If <code>c</code>'s parent is not a <code>CellRendererPane</code>, |
|
1151 |
* a new <code>CellRendererPane</code> is created, <code>c</code> is |
|
1152 |
* added to it, and the <code>CellRendererPane</code> is added to |
|
1153 |
* <code>p</code>. If <code>c</code>'s parent is a |
|
1154 |
* <code>CellRendererPane</code> and the <code>CellRendererPane</code>s |
|
1155 |
* parent is not <code>p</code>, it is added to <code>p</code>. |
|
1156 |
* <p> |
|
1157 |
* The component should either descend from <code>JComponent</code> |
|
1158 |
* or be another kind of lightweight component. |
|
1159 |
* A lightweight component is one whose "lightweight" property |
|
1160 |
* (returned by the <code>Component</code> |
|
1161 |
* <code>isLightweight</code> method) |
|
1162 |
* is true. If the Component is not lightweight, bad things map happen: |
|
1163 |
* crashes, exceptions, painting problems... |
|
1164 |
* |
|
1165 |
* @param g the <code>Graphics</code> object to draw on |
|
1166 |
* @param c the <code>Component</code> to draw |
|
1167 |
* @param p the intermediate <code>Container</code> |
|
1168 |
* @param x an int specifying the left side of the area draw in, in pixels, |
|
1169 |
* measured from the left edge of the graphics context |
|
1170 |
* @param y an int specifying the top of the area to draw in, in pixels |
|
1171 |
* measured down from the top edge of the graphics context |
|
1172 |
* @param w an int specifying the width of the area draw in, in pixels |
|
1173 |
* @param h an int specifying the height of the area draw in, in pixels |
|
1174 |
* |
|
1175 |
* @see CellRendererPane |
|
1176 |
* @see java.awt.Component#isLightweight |
|
1177 |
*/ |
|
1178 |
public static void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) { |
|
1179 |
getCellRendererPane(c, p).paintComponent(g, c, p, x, y, w, h,false); |
|
1180 |
} |
|
1181 |
||
1182 |
/** |
|
1183 |
* Paints a component to the specified <code>Graphics</code>. This |
|
1184 |
* is a cover method for |
|
1185 |
* {@link #paintComponent(Graphics,Component,Container,int,int,int,int)}. |
|
1186 |
* Refer to it for more information. |
|
1187 |
* |
|
1188 |
* @param g the <code>Graphics</code> object to draw on |
|
1189 |
* @param c the <code>Component</code> to draw |
|
1190 |
* @param p the intermediate <code>Container</code> |
|
1191 |
* @param r the <code>Rectangle</code> to draw in |
|
1192 |
* |
|
1193 |
* @see #paintComponent(Graphics,Component,Container,int,int,int,int) |
|
1194 |
* @see CellRendererPane |
|
1195 |
*/ |
|
1196 |
public static void paintComponent(Graphics g, Component c, Container p, Rectangle r) { |
|
1197 |
paintComponent(g, c, p, r.x, r.y, r.width, r.height); |
|
1198 |
} |
|
1199 |
||
1200 |
||
1201 |
/* |
|
1202 |
* Ensures that cell renderer <code>c</code> has a |
|
1203 |
* <code>ComponentShell</code> parent and that |
|
1204 |
* the shell's parent is p. |
|
1205 |
*/ |
|
1206 |
private static CellRendererPane getCellRendererPane(Component c, Container p) { |
|
1207 |
Container shell = c.getParent(); |
|
1208 |
if (shell instanceof CellRendererPane) { |
|
1209 |
if (shell.getParent() != p) { |
|
1210 |
p.add(shell); |
|
1211 |
} |
|
1212 |
} else { |
|
1213 |
shell = new CellRendererPane(); |
|
1214 |
shell.add(c); |
|
1215 |
p.add(shell); |
|
1216 |
} |
|
1217 |
return (CellRendererPane)shell; |
|
1218 |
} |
|
1219 |
||
1220 |
/** |
|
1221 |
* A simple minded look and feel change: ask each node in the tree |
|
1222 |
* to <code>updateUI()</code> -- that is, to initialize its UI property |
|
1223 |
* with the current look and feel. |
|
1224 |
*/ |
|
1225 |
public static void updateComponentTreeUI(Component c) { |
|
1226 |
updateComponentTreeUI0(c); |
|
1227 |
c.invalidate(); |
|
1228 |
c.validate(); |
|
1229 |
c.repaint(); |
|
1230 |
} |
|
1231 |
||
1232 |
private static void updateComponentTreeUI0(Component c) { |
|
1233 |
if (c instanceof JComponent) { |
|
1234 |
JComponent jc = (JComponent) c; |
|
1235 |
jc.updateUI(); |
|
1236 |
JPopupMenu jpm =jc.getComponentPopupMenu(); |
|
1237 |
if(jpm != null) { |
|
1238 |
updateComponentTreeUI(jpm); |
|
1239 |
} |
|
1240 |
} |
|
1241 |
Component[] children = null; |
|
1242 |
if (c instanceof JMenu) { |
|
1243 |
children = ((JMenu)c).getMenuComponents(); |
|
1244 |
} |
|
1245 |
else if (c instanceof Container) { |
|
1246 |
children = ((Container)c).getComponents(); |
|
1247 |
} |
|
1248 |
if (children != null) { |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1249 |
for (Component child : children) { |
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1250 |
updateComponentTreeUI0(child); |
2 | 1251 |
} |
1252 |
} |
|
1253 |
} |
|
1254 |
||
1255 |
||
1256 |
/** |
|
1257 |
* Causes <i>doRun.run()</i> to be executed asynchronously on the |
|
1258 |
* AWT event dispatching thread. This will happen after all |
|
1259 |
* pending AWT events have been processed. This method should |
|
1260 |
* be used when an application thread needs to update the GUI. |
|
1261 |
* In the following example the <code>invokeLater</code> call queues |
|
1262 |
* the <code>Runnable</code> object <code>doHelloWorld</code> |
|
1263 |
* on the event dispatching thread and |
|
1264 |
* then prints a message. |
|
1265 |
* <pre> |
|
1266 |
* Runnable doHelloWorld = new Runnable() { |
|
1267 |
* public void run() { |
|
1268 |
* System.out.println("Hello World on " + Thread.currentThread()); |
|
1269 |
* } |
|
1270 |
* }; |
|
1271 |
* |
|
1272 |
* SwingUtilities.invokeLater(doHelloWorld); |
|
1273 |
* System.out.println("This might well be displayed before the other message."); |
|
1274 |
* </pre> |
|
1275 |
* If invokeLater is called from the event dispatching thread -- |
|
1276 |
* for example, from a JButton's ActionListener -- the <i>doRun.run()</i> will |
|
1277 |
* still be deferred until all pending events have been processed. |
|
1278 |
* Note that if the <i>doRun.run()</i> throws an uncaught exception |
|
1279 |
* the event dispatching thread will unwind (not the current thread). |
|
1280 |
* <p> |
|
1281 |
* Additional documentation and examples for this method can be |
|
1282 |
* found in |
|
20455
f6f9a0c2796b
8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents:
15991
diff
changeset
|
1283 |
* <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>. |
2 | 1284 |
* <p> |
1285 |
* As of 1.3 this method is just a cover for <code>java.awt.EventQueue.invokeLater()</code>. |
|
1286 |
* <p> |
|
1287 |
* Unlike the rest of Swing, this method can be invoked from any thread. |
|
1288 |
* |
|
1289 |
* @see #invokeAndWait |
|
1290 |
*/ |
|
1291 |
public static void invokeLater(Runnable doRun) { |
|
1292 |
EventQueue.invokeLater(doRun); |
|
1293 |
} |
|
1294 |
||
1295 |
||
1296 |
/** |
|
1297 |
* Causes <code>doRun.run()</code> to be executed synchronously on the |
|
1298 |
* AWT event dispatching thread. This call blocks until |
|
1299 |
* all pending AWT events have been processed and (then) |
|
1300 |
* <code>doRun.run()</code> returns. This method should |
|
1301 |
* be used when an application thread needs to update the GUI. |
|
1302 |
* It shouldn't be called from the event dispatching thread. |
|
1303 |
* Here's an example that creates a new application thread |
|
1304 |
* that uses <code>invokeAndWait</code> to print a string from the event |
|
1305 |
* dispatching thread and then, when that's finished, print |
|
1306 |
* a string from the application thread. |
|
1307 |
* <pre> |
|
1308 |
* final Runnable doHelloWorld = new Runnable() { |
|
1309 |
* public void run() { |
|
1310 |
* System.out.println("Hello World on " + Thread.currentThread()); |
|
1311 |
* } |
|
1312 |
* }; |
|
1313 |
* |
|
1314 |
* Thread appThread = new Thread() { |
|
1315 |
* public void run() { |
|
1316 |
* try { |
|
1317 |
* SwingUtilities.invokeAndWait(doHelloWorld); |
|
1318 |
* } |
|
1319 |
* catch (Exception e) { |
|
1320 |
* e.printStackTrace(); |
|
1321 |
* } |
|
1322 |
* System.out.println("Finished on " + Thread.currentThread()); |
|
1323 |
* } |
|
1324 |
* }; |
|
1325 |
* appThread.start(); |
|
1326 |
* </pre> |
|
1327 |
* Note that if the <code>Runnable.run</code> method throws an |
|
1328 |
* uncaught exception |
|
1329 |
* (on the event dispatching thread) it's caught and rethrown, as |
|
1330 |
* an <code>InvocationTargetException</code>, on the caller's thread. |
|
1331 |
* <p> |
|
1332 |
* Additional documentation and examples for this method can be |
|
1333 |
* found in |
|
20455
f6f9a0c2796b
8020688: Broken links in documentation at http://docs.oracle.com/javase/6/docs/api/index.
mcherkas
parents:
15991
diff
changeset
|
1334 |
* <A HREF="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a>. |
2 | 1335 |
* <p> |
1336 |
* As of 1.3 this method is just a cover for |
|
1337 |
* <code>java.awt.EventQueue.invokeAndWait()</code>. |
|
1338 |
* |
|
1339 |
* @exception InterruptedException if we're interrupted while waiting for |
|
21278 | 1340 |
* the event dispatching thread to finish executing |
2 | 1341 |
* <code>doRun.run()</code> |
1342 |
* @exception InvocationTargetException if an exception is thrown |
|
1343 |
* while running <code>doRun</code> |
|
1344 |
* |
|
1345 |
* @see #invokeLater |
|
1346 |
*/ |
|
1347 |
public static void invokeAndWait(final Runnable doRun) |
|
1348 |
throws InterruptedException, InvocationTargetException |
|
1349 |
{ |
|
1350 |
EventQueue.invokeAndWait(doRun); |
|
1351 |
} |
|
1352 |
||
1353 |
/** |
|
1354 |
* Returns true if the current thread is an AWT event dispatching thread. |
|
1355 |
* <p> |
|
1356 |
* As of 1.3 this method is just a cover for |
|
1357 |
* <code>java.awt.EventQueue.isDispatchThread()</code>. |
|
1358 |
* |
|
1359 |
* @return true if the current thread is an AWT event dispatching thread |
|
1360 |
*/ |
|
1361 |
public static boolean isEventDispatchThread() |
|
1362 |
{ |
|
1363 |
return EventQueue.isDispatchThread(); |
|
1364 |
} |
|
1365 |
||
1366 |
||
1367 |
/* |
|
1368 |
* --- Accessibility Support --- |
|
1369 |
* |
|
1370 |
*/ |
|
1371 |
||
1372 |
/** |
|
1373 |
* Get the index of this object in its accessible parent.<p> |
|
1374 |
* |
|
1375 |
* Note: as of the Java 2 platform v1.3, it is recommended that developers call |
|
1376 |
* Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead |
|
1377 |
* of using this method. |
|
1378 |
* |
|
1379 |
* @return -1 of this object does not have an accessible parent. |
|
1380 |
* Otherwise, the index of the child in its accessible parent. |
|
1381 |
*/ |
|
1382 |
public static int getAccessibleIndexInParent(Component c) { |
|
1383 |
return c.getAccessibleContext().getAccessibleIndexInParent(); |
|
1384 |
} |
|
1385 |
||
1386 |
/** |
|
1387 |
* Returns the <code>Accessible</code> child contained at the |
|
1388 |
* local coordinate <code>Point</code>, if one exists. |
|
1389 |
* Otherwise returns <code>null</code>. |
|
1390 |
* |
|
1391 |
* @return the <code>Accessible</code> at the specified location, |
|
1392 |
* if it exists; otherwise <code>null</code> |
|
1393 |
*/ |
|
1394 |
public static Accessible getAccessibleAt(Component c, Point p) { |
|
1395 |
if (c instanceof Container) { |
|
1396 |
return c.getAccessibleContext().getAccessibleComponent().getAccessibleAt(p); |
|
1397 |
} else if (c instanceof Accessible) { |
|
1398 |
Accessible a = (Accessible) c; |
|
1399 |
if (a != null) { |
|
1400 |
AccessibleContext ac = a.getAccessibleContext(); |
|
1401 |
if (ac != null) { |
|
1402 |
AccessibleComponent acmp; |
|
1403 |
Point location; |
|
1404 |
int nchildren = ac.getAccessibleChildrenCount(); |
|
1405 |
for (int i=0; i < nchildren; i++) { |
|
1406 |
a = ac.getAccessibleChild(i); |
|
1407 |
if ((a != null)) { |
|
1408 |
ac = a.getAccessibleContext(); |
|
1409 |
if (ac != null) { |
|
1410 |
acmp = ac.getAccessibleComponent(); |
|
1411 |
if ((acmp != null) && (acmp.isShowing())) { |
|
1412 |
location = acmp.getLocation(); |
|
1413 |
Point np = new Point(p.x-location.x, |
|
1414 |
p.y-location.y); |
|
1415 |
if (acmp.contains(np)){ |
|
1416 |
return a; |
|
1417 |
} |
|
1418 |
} |
|
1419 |
} |
|
1420 |
} |
|
1421 |
} |
|
1422 |
} |
|
1423 |
} |
|
1424 |
return (Accessible) c; |
|
1425 |
} |
|
1426 |
return null; |
|
1427 |
} |
|
1428 |
||
1429 |
/** |
|
1430 |
* Get the state of this object. <p> |
|
1431 |
* |
|
1432 |
* Note: as of the Java 2 platform v1.3, it is recommended that developers call |
|
1433 |
* Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead |
|
1434 |
* of using this method. |
|
1435 |
* |
|
1436 |
* @return an instance of AccessibleStateSet containing the current state |
|
1437 |
* set of the object |
|
1438 |
* @see AccessibleState |
|
1439 |
*/ |
|
1440 |
public static AccessibleStateSet getAccessibleStateSet(Component c) { |
|
1441 |
return c.getAccessibleContext().getAccessibleStateSet(); |
|
1442 |
} |
|
1443 |
||
1444 |
/** |
|
1445 |
* Returns the number of accessible children in the object. If all |
|
1446 |
* of the children of this object implement Accessible, than this |
|
1447 |
* method should return the number of children of this object. <p> |
|
1448 |
* |
|
1449 |
* Note: as of the Java 2 platform v1.3, it is recommended that developers call |
|
1450 |
* Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead |
|
1451 |
* of using this method. |
|
1452 |
* |
|
1453 |
* @return the number of accessible children in the object. |
|
1454 |
*/ |
|
1455 |
public static int getAccessibleChildrenCount(Component c) { |
|
1456 |
return c.getAccessibleContext().getAccessibleChildrenCount(); |
|
1457 |
} |
|
1458 |
||
1459 |
/** |
|
1460 |
* Return the nth Accessible child of the object. <p> |
|
1461 |
* |
|
1462 |
* Note: as of the Java 2 platform v1.3, it is recommended that developers call |
|
1463 |
* Component.AccessibleAWTComponent.getAccessibleIndexInParent() instead |
|
1464 |
* of using this method. |
|
1465 |
* |
|
1466 |
* @param i zero-based index of child |
|
1467 |
* @return the nth Accessible child of the object |
|
1468 |
*/ |
|
1469 |
public static Accessible getAccessibleChild(Component c, int i) { |
|
1470 |
return c.getAccessibleContext().getAccessibleChild(i); |
|
1471 |
} |
|
1472 |
||
1473 |
/** |
|
1474 |
* Return the child <code>Component</code> of the specified |
|
1475 |
* <code>Component</code> that is the focus owner, if any. |
|
1476 |
* |
|
1477 |
* @param c the root of the <code>Component</code> hierarchy to |
|
1478 |
* search for the focus owner |
|
1479 |
* @return the focus owner, or <code>null</code> if there is no focus |
|
1480 |
* owner, or if the focus owner is not <code>comp</code>, or a |
|
1481 |
* descendant of <code>comp</code> |
|
1482 |
* |
|
1483 |
* @see java.awt.KeyboardFocusManager#getFocusOwner |
|
1484 |
* @deprecated As of 1.4, replaced by |
|
1485 |
* <code>KeyboardFocusManager.getFocusOwner()</code>. |
|
1486 |
*/ |
|
1487 |
@Deprecated |
|
1488 |
public static Component findFocusOwner(Component c) { |
|
1489 |
Component focusOwner = KeyboardFocusManager. |
|
1490 |
getCurrentKeyboardFocusManager().getFocusOwner(); |
|
1491 |
||
1492 |
// verify focusOwner is a descendant of c |
|
1493 |
for (Component temp = focusOwner; temp != null; |
|
1494 |
temp = (temp instanceof Window) ? null : temp.getParent()) |
|
1495 |
{ |
|
1496 |
if (temp == c) { |
|
1497 |
return focusOwner; |
|
1498 |
} |
|
1499 |
} |
|
1500 |
||
1501 |
return null; |
|
1502 |
} |
|
1503 |
||
1504 |
/** |
|
1505 |
* If c is a JRootPane descendant return its JRootPane ancestor. |
|
1506 |
* If c is a RootPaneContainer then return its JRootPane. |
|
1507 |
* @return the JRootPane for Component c or {@code null}. |
|
1508 |
*/ |
|
1509 |
public static JRootPane getRootPane(Component c) { |
|
1510 |
if (c instanceof RootPaneContainer) { |
|
1511 |
return ((RootPaneContainer)c).getRootPane(); |
|
1512 |
} |
|
1513 |
for( ; c != null; c = c.getParent()) { |
|
1514 |
if (c instanceof JRootPane) { |
|
1515 |
return (JRootPane)c; |
|
1516 |
} |
|
1517 |
} |
|
1518 |
return null; |
|
1519 |
} |
|
1520 |
||
1521 |
||
1522 |
/** |
|
1523 |
* Returns the root component for the current component tree. |
|
1524 |
* @return the first ancestor of c that's a Window or the last Applet ancestor |
|
1525 |
*/ |
|
1526 |
public static Component getRoot(Component c) { |
|
1527 |
Component applet = null; |
|
1528 |
for(Component p = c; p != null; p = p.getParent()) { |
|
1529 |
if (p instanceof Window) { |
|
1530 |
return p; |
|
1531 |
} |
|
1532 |
if (p instanceof Applet) { |
|
1533 |
applet = p; |
|
1534 |
} |
|
1535 |
} |
|
1536 |
return applet; |
|
1537 |
} |
|
1538 |
||
8372
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1539 |
static JComponent getPaintingOrigin(JComponent c) { |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1540 |
Container p = c; |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1541 |
while ((p = p.getParent()) instanceof JComponent) { |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1542 |
JComponent jp = (JComponent) p; |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1543 |
if (jp.isPaintingOrigin()) { |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1544 |
return jp; |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1545 |
} |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1546 |
} |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1547 |
return null; |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1548 |
} |
786e091594a0
6993171: JavaTest/JDK7b114 - no help text is shown for interview questions, JavaTest HANGS UP
alexp
parents:
7668
diff
changeset
|
1549 |
|
2 | 1550 |
/** |
1551 |
* Process the key bindings for the <code>Component</code> associated with |
|
1552 |
* <code>event</code>. This method is only useful if |
|
1553 |
* <code>event.getComponent()</code> does not descend from |
|
1554 |
* <code>JComponent</code>, or your are not invoking |
|
1555 |
* <code>super.processKeyEvent</code> from within your |
|
1556 |
* <code>JComponent</code> subclass. <code>JComponent</code> |
|
1557 |
* automatically processes bindings from within its |
|
1558 |
* <code>processKeyEvent</code> method, hence you rarely need |
|
1559 |
* to directly invoke this method. |
|
1560 |
* |
|
1561 |
* @param event KeyEvent used to identify which bindings to process, as |
|
1562 |
* well as which Component has focus. |
|
1563 |
* @return true if a binding has found and processed |
|
1564 |
* @since 1.4 |
|
1565 |
*/ |
|
1566 |
public static boolean processKeyBindings(KeyEvent event) { |
|
1567 |
if (event != null) { |
|
1568 |
if (event.isConsumed()) { |
|
1569 |
return false; |
|
1570 |
} |
|
1571 |
||
1572 |
Component component = event.getComponent(); |
|
1573 |
boolean pressed = (event.getID() == KeyEvent.KEY_PRESSED); |
|
1574 |
||
1575 |
if (!isValidKeyEventForKeyBindings(event)) { |
|
1576 |
return false; |
|
1577 |
} |
|
1578 |
// Find the first JComponent in the ancestor hierarchy, and |
|
1579 |
// invoke processKeyBindings on it |
|
1580 |
while (component != null) { |
|
1581 |
if (component instanceof JComponent) { |
|
1582 |
return ((JComponent)component).processKeyBindings( |
|
1583 |
event, pressed); |
|
1584 |
} |
|
1585 |
if ((component instanceof Applet) || |
|
1586 |
(component instanceof Window)) { |
|
1587 |
// No JComponents, if Window or Applet parent, process |
|
1588 |
// WHEN_IN_FOCUSED_WINDOW bindings. |
|
1589 |
return JComponent.processKeyBindingsForAllComponents( |
|
1590 |
event, (Container)component, pressed); |
|
1591 |
} |
|
1592 |
component = component.getParent(); |
|
1593 |
} |
|
1594 |
} |
|
1595 |
return false; |
|
1596 |
} |
|
1597 |
||
1598 |
/** |
|
1599 |
* Returns true if the <code>e</code> is a valid KeyEvent to use in |
|
1600 |
* processing the key bindings associated with JComponents. |
|
1601 |
*/ |
|
1602 |
static boolean isValidKeyEventForKeyBindings(KeyEvent e) { |
|
1603 |
return true; |
|
1604 |
} |
|
1605 |
||
1606 |
/** |
|
1607 |
* Invokes <code>actionPerformed</code> on <code>action</code> if |
|
1608 |
* <code>action</code> is enabled (and non-{@code null}). The command for the |
|
1609 |
* ActionEvent is determined by: |
|
1610 |
* <ol> |
|
1611 |
* <li>If the action was registered via |
|
1612 |
* <code>registerKeyboardAction</code>, then the command string |
|
1613 |
* passed in ({@code null} will be used if {@code null} was passed in). |
|
1614 |
* <li>Action value with name Action.ACTION_COMMAND_KEY, unless {@code null}. |
|
1615 |
* <li>String value of the KeyEvent, unless <code>getKeyChar</code> |
|
1616 |
* returns KeyEvent.CHAR_UNDEFINED.. |
|
1617 |
* </ol> |
|
1618 |
* This will return true if <code>action</code> is non-{@code null} and |
|
1619 |
* actionPerformed is invoked on it. |
|
1620 |
* |
|
1621 |
* @since 1.3 |
|
1622 |
*/ |
|
1623 |
public static boolean notifyAction(Action action, KeyStroke ks, |
|
1624 |
KeyEvent event, Object sender, |
|
1625 |
int modifiers) { |
|
1626 |
if (action == null) { |
|
1627 |
return false; |
|
1628 |
} |
|
1629 |
if (action instanceof UIAction) { |
|
1630 |
if (!((UIAction)action).isEnabled(sender)) { |
|
1631 |
return false; |
|
1632 |
} |
|
1633 |
} |
|
1634 |
else if (!action.isEnabled()) { |
|
1635 |
return false; |
|
1636 |
} |
|
1637 |
Object commandO; |
|
1638 |
boolean stayNull; |
|
1639 |
||
1640 |
// Get the command object. |
|
1641 |
commandO = action.getValue(Action.ACTION_COMMAND_KEY); |
|
1642 |
if (commandO == null && (action instanceof JComponent.ActionStandin)) { |
|
1643 |
// ActionStandin is used for historical reasons to support |
|
1644 |
// registerKeyboardAction with a null value. |
|
1645 |
stayNull = true; |
|
1646 |
} |
|
1647 |
else { |
|
1648 |
stayNull = false; |
|
1649 |
} |
|
1650 |
||
1651 |
// Convert it to a string. |
|
1652 |
String command; |
|
1653 |
||
1654 |
if (commandO != null) { |
|
1655 |
command = commandO.toString(); |
|
1656 |
} |
|
1657 |
else if (!stayNull && event.getKeyChar() != KeyEvent.CHAR_UNDEFINED) { |
|
1658 |
command = String.valueOf(event.getKeyChar()); |
|
1659 |
} |
|
1660 |
else { |
|
1661 |
// Do null for undefined chars, or if registerKeyboardAction |
|
1662 |
// was called with a null. |
|
1663 |
command = null; |
|
1664 |
} |
|
1665 |
action.actionPerformed(new ActionEvent(sender, |
|
1666 |
ActionEvent.ACTION_PERFORMED, command, event.getWhen(), |
|
1667 |
modifiers)); |
|
1668 |
return true; |
|
1669 |
} |
|
1670 |
||
1671 |
||
1672 |
/** |
|
1673 |
* Convenience method to change the UI InputMap for <code>component</code> |
|
1674 |
* to <code>uiInputMap</code>. If <code>uiInputMap</code> is {@code null}, |
|
1675 |
* this removes any previously installed UI InputMap. |
|
1676 |
* |
|
1677 |
* @since 1.3 |
|
1678 |
*/ |
|
1679 |
public static void replaceUIInputMap(JComponent component, int type, |
|
1680 |
InputMap uiInputMap) { |
|
1681 |
InputMap map = component.getInputMap(type, (uiInputMap != null)); |
|
1682 |
||
1683 |
while (map != null) { |
|
1684 |
InputMap parent = map.getParent(); |
|
1685 |
if (parent == null || (parent instanceof UIResource)) { |
|
1686 |
map.setParent(uiInputMap); |
|
1687 |
return; |
|
1688 |
} |
|
1689 |
map = parent; |
|
1690 |
} |
|
1691 |
} |
|
1692 |
||
1693 |
||
1694 |
/** |
|
1695 |
* Convenience method to change the UI ActionMap for <code>component</code> |
|
1696 |
* to <code>uiActionMap</code>. If <code>uiActionMap</code> is {@code null}, |
|
1697 |
* this removes any previously installed UI ActionMap. |
|
1698 |
* |
|
1699 |
* @since 1.3 |
|
1700 |
*/ |
|
1701 |
public static void replaceUIActionMap(JComponent component, |
|
1702 |
ActionMap uiActionMap) { |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1703 |
ActionMap map = component.getActionMap((uiActionMap != null)); |
2 | 1704 |
|
1705 |
while (map != null) { |
|
1706 |
ActionMap parent = map.getParent(); |
|
1707 |
if (parent == null || (parent instanceof UIResource)) { |
|
1708 |
map.setParent(uiActionMap); |
|
1709 |
return; |
|
1710 |
} |
|
1711 |
map = parent; |
|
1712 |
} |
|
1713 |
} |
|
1714 |
||
1715 |
||
1716 |
/** |
|
1717 |
* Returns the InputMap provided by the UI for condition |
|
1718 |
* <code>condition</code> in component <code>component</code>. |
|
1719 |
* <p>This will return {@code null} if the UI has not installed a InputMap |
|
1720 |
* of the specified type. |
|
1721 |
* |
|
1722 |
* @since 1.3 |
|
1723 |
*/ |
|
1724 |
public static InputMap getUIInputMap(JComponent component, int condition) { |
|
1725 |
InputMap map = component.getInputMap(condition, false); |
|
1726 |
while (map != null) { |
|
1727 |
InputMap parent = map.getParent(); |
|
1728 |
if (parent instanceof UIResource) { |
|
1729 |
return parent; |
|
1730 |
} |
|
1731 |
map = parent; |
|
1732 |
} |
|
1733 |
return null; |
|
1734 |
} |
|
1735 |
||
1736 |
/** |
|
1737 |
* Returns the ActionMap provided by the UI |
|
1738 |
* in component <code>component</code>. |
|
1739 |
* <p>This will return {@code null} if the UI has not installed an ActionMap. |
|
1740 |
* |
|
1741 |
* @since 1.3 |
|
1742 |
*/ |
|
1743 |
public static ActionMap getUIActionMap(JComponent component) { |
|
1744 |
ActionMap map = component.getActionMap(false); |
|
1745 |
while (map != null) { |
|
1746 |
ActionMap parent = map.getParent(); |
|
1747 |
if (parent instanceof UIResource) { |
|
1748 |
return parent; |
|
1749 |
} |
|
1750 |
map = parent; |
|
1751 |
} |
|
1752 |
return null; |
|
1753 |
} |
|
1754 |
||
1755 |
||
1756 |
// Don't use String, as it's not guaranteed to be unique in a Hashtable. |
|
1757 |
private static final Object sharedOwnerFrameKey = |
|
1758 |
new StringBuffer("SwingUtilities.sharedOwnerFrame"); |
|
1759 |
||
1760 |
static class SharedOwnerFrame extends Frame implements WindowListener { |
|
1761 |
public void addNotify() { |
|
1762 |
super.addNotify(); |
|
1763 |
installListeners(); |
|
1764 |
} |
|
1765 |
||
1766 |
/** |
|
1767 |
* Install window listeners on owned windows to watch for displayability changes |
|
1768 |
*/ |
|
1769 |
void installListeners() { |
|
1770 |
Window[] windows = getOwnedWindows(); |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1771 |
for (Window window : windows) { |
2 | 1772 |
if (window != null) { |
1773 |
window.removeWindowListener(this); |
|
1774 |
window.addWindowListener(this); |
|
1775 |
} |
|
1776 |
} |
|
1777 |
} |
|
1778 |
||
1779 |
/** |
|
1780 |
* Watches for displayability changes and disposes shared instance if there are no |
|
1781 |
* displayable children left. |
|
1782 |
*/ |
|
1783 |
public void windowClosed(WindowEvent e) { |
|
1784 |
synchronized(getTreeLock()) { |
|
1785 |
Window[] windows = getOwnedWindows(); |
|
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1786 |
for (Window window : windows) { |
2 | 1787 |
if (window != null) { |
1788 |
if (window.isDisplayable()) { |
|
1789 |
return; |
|
1790 |
} |
|
1791 |
window.removeWindowListener(this); |
|
1792 |
} |
|
1793 |
} |
|
1794 |
dispose(); |
|
1795 |
} |
|
1796 |
} |
|
1797 |
public void windowOpened(WindowEvent e) { |
|
1798 |
} |
|
1799 |
public void windowClosing(WindowEvent e) { |
|
1800 |
} |
|
1801 |
public void windowIconified(WindowEvent e) { |
|
1802 |
} |
|
1803 |
public void windowDeiconified(WindowEvent e) { |
|
1804 |
} |
|
1805 |
public void windowActivated(WindowEvent e) { |
|
1806 |
} |
|
1807 |
public void windowDeactivated(WindowEvent e) { |
|
1808 |
} |
|
1809 |
||
1810 |
public void show() { |
|
1811 |
// This frame can never be shown |
|
1812 |
} |
|
1813 |
public void dispose() { |
|
1814 |
try { |
|
1815 |
getToolkit().getSystemEventQueue(); |
|
1816 |
super.dispose(); |
|
1817 |
} catch (Exception e) { |
|
1818 |
// untrusted code not allowed to dispose |
|
1819 |
} |
|
1820 |
} |
|
1821 |
} |
|
1822 |
||
1823 |
/** |
|
1824 |
* Returns a toolkit-private, shared, invisible Frame |
|
1825 |
* to be the owner for JDialogs and JWindows created with |
|
1826 |
* {@code null} owners. |
|
1827 |
* @exception HeadlessException if GraphicsEnvironment.isHeadless() |
|
1828 |
* returns true. |
|
1829 |
* @see java.awt.GraphicsEnvironment#isHeadless |
|
1830 |
*/ |
|
1831 |
static Frame getSharedOwnerFrame() throws HeadlessException { |
|
1832 |
Frame sharedOwnerFrame = |
|
1833 |
(Frame)SwingUtilities.appContextGet(sharedOwnerFrameKey); |
|
1834 |
if (sharedOwnerFrame == null) { |
|
1835 |
sharedOwnerFrame = new SharedOwnerFrame(); |
|
1836 |
SwingUtilities.appContextPut(sharedOwnerFrameKey, |
|
1837 |
sharedOwnerFrame); |
|
1838 |
} |
|
1839 |
return sharedOwnerFrame; |
|
1840 |
} |
|
1841 |
||
1842 |
/** |
|
1843 |
* Returns a SharedOwnerFrame's shutdown listener to dispose the SharedOwnerFrame |
|
1844 |
* if it has no more displayable children. |
|
1845 |
* @exception HeadlessException if GraphicsEnvironment.isHeadless() |
|
1846 |
* returns true. |
|
1847 |
* @see java.awt.GraphicsEnvironment#isHeadless |
|
1848 |
*/ |
|
1849 |
static WindowListener getSharedOwnerFrameShutdownListener() throws HeadlessException { |
|
1850 |
Frame sharedOwnerFrame = getSharedOwnerFrame(); |
|
1851 |
return (WindowListener)sharedOwnerFrame; |
|
1852 |
} |
|
1853 |
||
1854 |
/* Don't make these AppContext accessors public or protected -- |
|
1855 |
* since AppContext is in sun.awt in 1.2, we shouldn't expose it |
|
1856 |
* even indirectly with a public API. |
|
1857 |
*/ |
|
1858 |
// REMIND(aim): phase out use of 4 methods below since they |
|
1859 |
// are just private covers for AWT methods (?) |
|
1860 |
||
1861 |
static Object appContextGet(Object key) { |
|
1862 |
return AppContext.getAppContext().get(key); |
|
1863 |
} |
|
1864 |
||
1865 |
static void appContextPut(Object key, Object value) { |
|
1866 |
AppContext.getAppContext().put(key, value); |
|
1867 |
} |
|
1868 |
||
1869 |
static void appContextRemove(Object key) { |
|
1870 |
AppContext.getAppContext().remove(key); |
|
1871 |
} |
|
1872 |
||
1873 |
||
1301
15e81207e1f2
6727662: Code improvement and warnings removing from swing packages
rupashka
parents:
1295
diff
changeset
|
1874 |
static Class<?> loadSystemClass(String className) throws ClassNotFoundException { |
2 | 1875 |
return Class.forName(className, true, Thread.currentThread(). |
1876 |
getContextClassLoader()); |
|
1877 |
} |
|
1878 |
||
1879 |
||
1880 |
/* |
|
1881 |
* Convenience function for determining ComponentOrientation. Helps us |
|
1882 |
* avoid having Munge directives throughout the code. |
|
1883 |
*/ |
|
1884 |
static boolean isLeftToRight( Component c ) { |
|
1885 |
return c.getComponentOrientation().isLeftToRight(); |
|
1886 |
} |
|
1887 |
private SwingUtilities() { |
|
1888 |
throw new Error("SwingUtilities is just a container for static methods"); |
|
1889 |
} |
|
1890 |
||
1891 |
/** |
|
1892 |
* Returns true if the Icon <code>icon</code> is an instance of |
|
1893 |
* ImageIcon, and the image it contains is the same as <code>image</code>. |
|
1894 |
*/ |
|
1895 |
static boolean doesIconReferenceImage(Icon icon, Image image) { |
|
1896 |
Image iconImage = (icon != null && (icon instanceof ImageIcon)) ? |
|
1897 |
((ImageIcon)icon).getImage() : null; |
|
1898 |
return (iconImage == image); |
|
1899 |
} |
|
1900 |
||
1901 |
/** |
|
1902 |
* Returns index of the first occurrence of <code>mnemonic</code> |
|
1903 |
* within string <code>text</code>. Matching algorithm is not |
|
1904 |
* case-sensitive. |
|
1905 |
* |
|
1906 |
* @param text The text to search through, may be {@code null} |
|
1907 |
* @param mnemonic The mnemonic to find the character for. |
|
1908 |
* @return index into the string if exists, otherwise -1 |
|
1909 |
*/ |
|
1910 |
static int findDisplayedMnemonicIndex(String text, int mnemonic) { |
|
1911 |
if (text == null || mnemonic == '\0') { |
|
1912 |
return -1; |
|
1913 |
} |
|
1914 |
||
1915 |
char uc = Character.toUpperCase((char)mnemonic); |
|
1916 |
char lc = Character.toLowerCase((char)mnemonic); |
|
1917 |
||
1918 |
int uci = text.indexOf(uc); |
|
1919 |
int lci = text.indexOf(lc); |
|
1920 |
||
1921 |
if (uci == -1) { |
|
1922 |
return lci; |
|
1923 |
} else if(lci == -1) { |
|
1924 |
return uci; |
|
1925 |
} else { |
|
1926 |
return (lci < uci) ? lci : uci; |
|
1927 |
} |
|
1928 |
} |
|
1929 |
||
1930 |
/** |
|
1931 |
* Stores the position and size of |
|
1932 |
* the inner painting area of the specified component |
|
1933 |
* in <code>r</code> and returns <code>r</code>. |
|
1934 |
* The position and size specify the bounds of the component, |
|
1935 |
* adjusted so as not to include the border area (the insets). |
|
1936 |
* This method is useful for classes |
|
1937 |
* that implement painting code. |
|
1938 |
* |
|
1939 |
* @param c the JComponent in question; if {@code null}, this method returns {@code null} |
|
1940 |
* @param r the Rectangle instance to be modified; |
|
1941 |
* may be {@code null} |
|
1942 |
* @return {@code null} if the Component is {@code null}; |
|
1943 |
* otherwise, returns the passed-in rectangle (if non-{@code null}) |
|
1944 |
* or a new rectangle specifying position and size information |
|
1945 |
* |
|
1946 |
* @since 1.4 |
|
1947 |
*/ |
|
1948 |
public static Rectangle calculateInnerArea(JComponent c, Rectangle r) { |
|
1949 |
if (c == null) { |
|
1950 |
return null; |
|
1951 |
} |
|
1952 |
Rectangle rect = r; |
|
1953 |
Insets insets = c.getInsets(); |
|
1954 |
||
1955 |
if (rect == null) { |
|
1956 |
rect = new Rectangle(); |
|
1957 |
} |
|
1958 |
||
1959 |
rect.x = insets.left; |
|
1960 |
rect.y = insets.top; |
|
1961 |
rect.width = c.getWidth() - insets.left - insets.right; |
|
1962 |
rect.height = c.getHeight() - insets.top - insets.bottom; |
|
1963 |
||
1964 |
return rect; |
|
1965 |
} |
|
1966 |
||
1967 |
static void updateRendererOrEditorUI(Object rendererOrEditor) { |
|
1968 |
if (rendererOrEditor == null) { |
|
1969 |
return; |
|
1970 |
} |
|
1971 |
||
1972 |
Component component = null; |
|
1973 |
||
1974 |
if (rendererOrEditor instanceof Component) { |
|
1975 |
component = (Component)rendererOrEditor; |
|
1976 |
} |
|
1977 |
if (rendererOrEditor instanceof DefaultCellEditor) { |
|
1978 |
component = ((DefaultCellEditor)rendererOrEditor).getComponent(); |
|
1979 |
} |
|
1980 |
||
1981 |
if (component != null) { |
|
1982 |
SwingUtilities.updateComponentTreeUI(component); |
|
1983 |
} |
|
1984 |
} |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
1985 |
|
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
1986 |
/** |
5449 | 1987 |
* Returns the first ancestor of the {@code component} |
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
1988 |
* which is not an instance of {@link JLayer}. |
5449 | 1989 |
* |
1990 |
* @param component {@code Component} to get |
|
1991 |
* the first ancestor of, which is not a {@link JLayer} instance. |
|
1992 |
* |
|
1993 |
* @return the first ancestor of the {@code component} |
|
1994 |
* which is not an instance of {@link JLayer}. |
|
1995 |
* If such an ancestor can not be found, {@code null} is returned. |
|
1996 |
* |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
1997 |
* @throws NullPointerException if {@code component} is {@code null} |
5449 | 1998 |
* @see JLayer |
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
1999 |
* |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2000 |
* @since 1.7 |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2001 |
*/ |
5449 | 2002 |
public static Container getUnwrappedParent(Component component) { |
2003 |
Container parent = component.getParent(); |
|
2004 |
while(parent instanceof JLayer) { |
|
2005 |
parent = parent.getParent(); |
|
2006 |
} |
|
2007 |
return parent; |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2008 |
} |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2009 |
|
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2010 |
/** |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2011 |
* Returns the first {@code JViewport}'s descendant |
5449 | 2012 |
* which is not an instance of {@code JLayer}. |
2013 |
* If such a descendant can not be found, {@code null} is returned. |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2014 |
* |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2015 |
* If the {@code viewport}'s view component is not a {@code JLayer}, |
5449 | 2016 |
* this method is equivalent to {@link JViewport#getView()} |
2017 |
* otherwise {@link JLayer#getView()} will be recursively |
|
2018 |
* called on all descending {@code JLayer}s. |
|
2019 |
* |
|
2020 |
* @param viewport {@code JViewport} to get the first descendant of, |
|
2021 |
* which in not a {@code JLayer} instance. |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2022 |
* |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2023 |
* @return the first {@code JViewport}'s descendant |
5449 | 2024 |
* which is not an instance of {@code JLayer}. |
2025 |
* If such a descendant can not be found, {@code null} is returned. |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2026 |
* |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2027 |
* @throws NullPointerException if {@code viewport} is {@code null} |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2028 |
* @see JViewport#getView() |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2029 |
* @see JLayer |
5449 | 2030 |
* |
2031 |
* @since 1.7 |
|
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2032 |
*/ |
5449 | 2033 |
public static Component getUnwrappedView(JViewport viewport) { |
4278
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2034 |
Component view = viewport.getView(); |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2035 |
while (view instanceof JLayer) { |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2036 |
view = ((JLayer)view).getView(); |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2037 |
} |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2038 |
return view; |
b7a976422d27
6878399: public SwingUtilities.getParentViewport() is required
alexp
parents:
3749
diff
changeset
|
2039 |
} |
4284 | 2040 |
|
2041 |
/** |
|
4261 | 2042 |
* Retrieves the validate root of a given container. |
2043 |
* |
|
2044 |
* If the container is contained within a {@code CellRendererPane}, this |
|
2045 |
* method returns {@code null} due to the synthetic nature of the {@code |
|
2046 |
* CellRendererPane}. |
|
2047 |
* <p> |
|
2048 |
* The component hierarchy must be displayable up to the toplevel component |
|
2049 |
* (either a {@code Frame} or an {@code Applet} object.) Otherwise this |
|
2050 |
* method returns {@code null}. |
|
2051 |
* <p> |
|
2052 |
* If the {@code visibleOnly} argument is {@code true}, the found validate |
|
2053 |
* root and all its parents up to the toplevel component must also be |
|
2054 |
* visible. Otherwise this method returns {@code null}. |
|
2055 |
* |
|
2056 |
* @return the validate root of the given container or null |
|
2057 |
* @see java.awt.Component#isDisplayable() |
|
2058 |
* @see java.awt.Component#isVisible() |
|
2059 |
* @since 1.7 |
|
2060 |
*/ |
|
2061 |
static Container getValidateRoot(Container c, boolean visibleOnly) { |
|
2062 |
Container root = null; |
|
2063 |
||
2064 |
for (; c != null; c = c.getParent()) |
|
2065 |
{ |
|
2066 |
if (!c.isDisplayable() || c instanceof CellRendererPane) { |
|
2067 |
return null; |
|
2068 |
} |
|
2069 |
if (c.isValidateRoot()) { |
|
2070 |
root = c; |
|
2071 |
break; |
|
2072 |
} |
|
2073 |
} |
|
2074 |
||
2075 |
if (root == null) { |
|
2076 |
return null; |
|
2077 |
} |
|
2078 |
||
2079 |
for (; c != null; c = c.getParent()) { |
|
2080 |
if (!c.isDisplayable() || (visibleOnly && !c.isVisible())) { |
|
2081 |
return null; |
|
2082 |
} |
|
2083 |
if (c instanceof Window || c instanceof Applet) { |
|
2084 |
return root; |
|
2085 |
} |
|
2086 |
} |
|
2087 |
||
2088 |
return null; |
|
2089 |
} |
|
2 | 2090 |
} |