37 |
|
|
38 |
package javax.swing; |
package javax.swing; |
39 |
|
|
40 |
|
import java.awt.AWTEvent; |
41 |
|
import java.awt.Component; |
42 |
|
import java.awt.Container; |
43 |
|
import java.awt.Dimension; |
44 |
|
import java.awt.FlowLayout; |
45 |
|
import java.awt.Insets; |
46 |
|
import java.awt.LayoutManager; |
47 |
|
import java.awt.Panel; |
48 |
|
import java.awt.Point; |
49 |
|
import java.awt.Rectangle; |
50 |
|
import java.awt.event.*; |
51 |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionEvent; |
52 |
import java.awt.event.ActionListener; |
import java.awt.event.ActionListener; |
53 |
import java.awt.event.MouseAdapter; |
import java.awt.event.MouseAdapter; |
54 |
import java.awt.event.MouseEvent; |
import java.awt.event.MouseEvent; |
55 |
import java.awt.event.MouseMotionListener; |
import java.awt.event.MouseMotionListener; |
56 |
|
import javax.swing.JComponent; |
57 |
|
import javax.swing.Popup; |
58 |
|
import javax.swing.PopupFactory; |
59 |
|
import javax.swing.SwingUtilities; |
60 |
|
import javax.swing.Timer; |
61 |
|
|
62 |
|
|
63 |
/** |
/** |
64 |
* ToolTipManager |
* This class is responsible for the registration of JToolTips to Components |
65 |
* |
* and for displaying them when appropriate. |
|
* @author Andrew Selkirk |
|
66 |
*/ |
*/ |
67 |
public class ToolTipManager extends MouseAdapter |
public class ToolTipManager extends MouseAdapter implements MouseMotionListener |
|
implements MouseMotionListener |
|
68 |
{ |
{ |
69 |
/** |
/** |
70 |
* stillInsideTimerAction |
* This ActionListener is associated with the Timer that listens to whether |
71 |
*/ |
* the JToolTip can be hidden after four seconds. |
72 |
protected class stillInsideTimerAction |
*/ |
73 |
implements ActionListener |
protected class stillInsideTimerAction implements ActionListener |
74 |
{ |
{ |
75 |
/** |
/** |
76 |
* Constructor stillInsideTimerAction |
* This method creates a new stillInsideTimerAction object. |
77 |
*/ |
*/ |
78 |
protected stillInsideTimerAction() |
protected stillInsideTimerAction() |
79 |
{ |
{ |
|
// TODO |
|
80 |
} |
} |
81 |
|
|
82 |
/** |
/** |
83 |
* actionPerformed |
* This method hides the JToolTip when the Timer has finished. |
84 |
* @param event TODO |
* |
85 |
*/ |
* @param event The ActionEvent. |
86 |
|
*/ |
87 |
public void actionPerformed(ActionEvent event) |
public void actionPerformed(ActionEvent event) |
88 |
{ |
{ |
89 |
// TODO |
hideTip(); |
90 |
} |
} |
91 |
} |
} |
92 |
|
|
93 |
/** |
/** |
94 |
* outsideTimerAction |
* This Actionlistener is associated with the Timer that listens to whether |
95 |
*/ |
* the mouse cursor has re-entered the JComponent in time for an immediate |
96 |
protected class outsideTimerAction |
* redisplay of the JToolTip. |
97 |
implements ActionListener |
*/ |
98 |
{ |
protected class outsideTimerAction implements ActionListener |
99 |
/** |
{ |
100 |
* Constructor outsideTimerAction |
/** |
101 |
*/ |
* This method creates a new outsideTimerAction object. |
102 |
|
*/ |
103 |
protected outsideTimerAction() |
protected outsideTimerAction() |
104 |
{ |
{ |
|
// TODO |
|
105 |
} |
} |
106 |
|
|
107 |
/** |
/** |
108 |
* actionPerformed |
* This method is called when the Timer that listens to whether the mouse |
109 |
* @param value0 TODO |
* cursor has re-entered the JComponent has run out. |
110 |
*/ |
* |
111 |
|
* @param event The ActionEvent. |
112 |
|
*/ |
113 |
public void actionPerformed(ActionEvent event) |
public void actionPerformed(ActionEvent event) |
114 |
{ |
{ |
|
// TODO |
|
115 |
} |
} |
116 |
} |
} |
117 |
|
|
118 |
/** |
/** |
119 |
* insideTimerAction |
* This ActionListener is associated with the Timer that listens to whether |
120 |
*/ |
* it is time for the JToolTip to be displayed after the mouse has entered |
121 |
protected class insideTimerAction |
* the JComponent. |
122 |
implements ActionListener |
*/ |
123 |
{ |
protected class insideTimerAction implements ActionListener |
124 |
/** |
{ |
125 |
* Constructor insideTimerAction |
/** |
126 |
*/ |
* This method creates a new insideTimerAction object. |
127 |
|
*/ |
128 |
protected insideTimerAction() |
protected insideTimerAction() |
129 |
{ |
{ |
|
// TODO |
|
130 |
} |
} |
131 |
|
|
132 |
/** |
/** |
133 |
* actionPerformed |
* This method displays the JToolTip when the Mouse has been still for the |
134 |
* @param event TODO |
* delay. |
135 |
*/ |
* |
136 |
|
* @param event The ActionEvent. |
137 |
|
*/ |
138 |
public void actionPerformed(ActionEvent event) |
public void actionPerformed(ActionEvent event) |
139 |
{ |
{ |
140 |
// TODO |
showTip(); |
141 |
|
if (insideTimer != null) |
142 |
|
insideTimer.start(); |
143 |
} |
} |
144 |
} |
} |
145 |
|
|
146 |
/** |
/** |
147 |
* enterTimer |
* The Timer that determines whether the Mouse has been still long enough |
148 |
*/ |
* for the JToolTip to be displayed. |
149 |
Timer enterTimer; |
*/ |
150 |
|
Timer enterTimer; |
151 |
/** |
|
152 |
* exitTimer |
/** |
153 |
*/ |
* The Timer that determines whether the Mouse has re-entered the JComponent |
154 |
Timer exitTimer; |
* quickly enough for the JToolTip to be displayed immediately. |
155 |
|
*/ |
156 |
/** |
Timer exitTimer; |
157 |
* insideTimer |
|
158 |
*/ |
/** |
159 |
Timer insideTimer; |
* The Timer that determines whether the JToolTip has been displayed long |
160 |
|
* enough for it to be hidden. |
161 |
/** |
*/ |
162 |
* toolTipText |
Timer insideTimer; |
163 |
*/ |
|
164 |
String toolTipText; |
/** A global enabled setting for the ToolTipManager. */ |
165 |
|
private transient boolean enabled = true; |
166 |
/** |
|
167 |
* mouseEvent |
/** lightWeightPopupEnabled */ |
168 |
*/ |
protected boolean lightWeightPopupEnabled = true; |
169 |
MouseEvent mouseEvent; |
|
170 |
|
/** heavyWeightPopupEnabled */ |
171 |
/** |
protected boolean heavyWeightPopupEnabled = false; |
172 |
* showImmediately |
|
173 |
*/ |
/** The shared instance of the ToolTipManager. */ |
174 |
boolean showImmediately; |
private static ToolTipManager shared; |
175 |
|
|
176 |
/** |
/** The current component the tooltip is being displayed for. */ |
177 |
* tip |
private static Component currentComponent; |
178 |
*/ |
|
179 |
JToolTip tip; |
/** The current tooltip. */ |
180 |
|
private static JToolTip currentTip; |
181 |
/** |
|
182 |
* enabled |
/** The last known position of the mouse cursor. */ |
183 |
*/ |
private static Point currentPoint; |
184 |
boolean enabled; |
|
185 |
|
/** |
186 |
/** |
* The panel that holds the tooltip when the tooltip is displayed fully |
187 |
* timerEnter |
* inside the current container. |
188 |
*/ |
*/ |
189 |
private long timerEnter; |
private static Container containerPanel; |
190 |
|
|
191 |
/** |
/** |
192 |
* lightWeightPopupEnabled |
* The window used when the tooltip doesn't fit inside the current |
193 |
*/ |
* container. |
194 |
protected boolean lightWeightPopupEnabled; |
*/ |
195 |
|
private static JWindow tooltipWindow; |
196 |
/** |
|
197 |
* heavyWeightPopupEnabled |
/** |
198 |
*/ |
* Creates a new ToolTipManager and sets up the timers. |
199 |
protected boolean heavyWeightPopupEnabled; |
*/ |
|
|
|
|
/** |
|
|
* Constructor ToolTipManager |
|
|
*/ |
|
200 |
ToolTipManager() |
ToolTipManager() |
201 |
{ |
{ |
202 |
// TODO |
enterTimer = new Timer(750, new insideTimerAction()); |
203 |
|
enterTimer.setRepeats(false); |
204 |
|
|
205 |
|
insideTimer = new Timer(4000, new stillInsideTimerAction()); |
206 |
|
insideTimer.setRepeats(false); |
207 |
|
|
208 |
|
exitTimer = new Timer(500, new outsideTimerAction()); |
209 |
|
exitTimer.setRepeats(false); |
210 |
} |
} |
211 |
|
|
212 |
/** |
/** |
213 |
* sharedInstance |
* This method returns the shared instance of ToolTipManager used by all |
214 |
* @return ToolTipManager |
* JComponents. |
215 |
*/ |
* |
216 |
|
* @return The shared instance of ToolTipManager. |
217 |
|
*/ |
218 |
public static ToolTipManager sharedInstance() |
public static ToolTipManager sharedInstance() |
219 |
{ |
{ |
220 |
return null; // TODO |
if (shared == null) |
221 |
|
shared = new ToolTipManager(); |
222 |
|
|
223 |
|
return shared; |
224 |
} |
} |
225 |
|
|
226 |
/** |
/** |
227 |
* setEnabled |
* This method sets whether ToolTips are enabled or disabled for all |
228 |
* @param enabled TODO |
* JComponents. |
229 |
*/ |
* |
230 |
|
* @param enabled Whether ToolTips are enabled or disabled for all |
231 |
|
* JComponents. |
232 |
|
*/ |
233 |
public void setEnabled(boolean enabled) |
public void setEnabled(boolean enabled) |
234 |
{ |
{ |
235 |
// TODO |
if (! enabled) |
236 |
|
{ |
237 |
|
enterTimer.stop(); |
238 |
|
exitTimer.stop(); |
239 |
|
insideTimer.stop(); |
240 |
|
} |
241 |
|
|
242 |
|
this.enabled = enabled; |
243 |
} |
} |
244 |
|
|
245 |
/** |
/** |
246 |
* isEnabled |
* This method returns whether ToolTips are enabled. |
247 |
* @return boolean |
* |
248 |
*/ |
* @return Whether ToolTips are enabled. |
249 |
|
*/ |
250 |
public boolean isEnabled() |
public boolean isEnabled() |
251 |
{ |
{ |
252 |
return false; // TODO |
return enabled; |
253 |
} |
} |
254 |
|
|
255 |
/** |
/** |
256 |
* isLightWeightPopupEnabled |
* This method returns whether LightweightToolTips are enabled. |
257 |
* @return boolean |
* |
258 |
*/ |
* @return Whether LighweightToolTips are enabled. |
259 |
|
*/ |
260 |
public boolean isLightWeightPopupEnabled() |
public boolean isLightWeightPopupEnabled() |
261 |
{ |
{ |
262 |
return false; // TODO |
return lightWeightPopupEnabled; |
263 |
} |
} |
264 |
|
|
265 |
/** |
/** |
266 |
* setLightWeightPopupEnabled |
* This method sets whether LightweightToolTips are enabled. If you mix |
267 |
* @param enabled TODO |
* Lightweight and Heavyweight components, you must set this to false to |
268 |
*/ |
* ensure that the ToolTips popup above all other components. |
269 |
|
* |
270 |
|
* @param enabled Whether LightweightToolTips will be enabled. |
271 |
|
*/ |
272 |
public void setLightWeightPopupEnabled(boolean enabled) |
public void setLightWeightPopupEnabled(boolean enabled) |
273 |
{ |
{ |
274 |
// TODO |
lightWeightPopupEnabled = enabled; |
275 |
|
heavyWeightPopupEnabled = ! enabled; |
276 |
} |
} |
277 |
|
|
278 |
/** |
/** |
279 |
* getInitialDelay |
* This method returns the initial delay before the ToolTip is shown when |
280 |
* @return int |
* the mouse enters a Component. |
281 |
*/ |
* |
282 |
|
* @return The initial delay before the ToolTip is shown. |
283 |
|
*/ |
284 |
public int getInitialDelay() |
public int getInitialDelay() |
285 |
{ |
{ |
286 |
return 0; // TODO |
return enterTimer.getDelay(); |
287 |
} |
} |
288 |
|
|
289 |
/** |
/** |
290 |
* setInitialDelay |
* This method sets the initial delay before the ToolTip is shown when the |
291 |
* @param delay TODO |
* mouse enters a Component. |
292 |
*/ |
* |
293 |
|
* @param delay The initial delay before the ToolTip is shown. |
294 |
|
*/ |
295 |
public void setInitialDelay(int delay) |
public void setInitialDelay(int delay) |
296 |
{ |
{ |
297 |
// TODO |
enterTimer.setDelay(delay); |
298 |
} |
} |
299 |
|
|
300 |
/** |
/** |
301 |
* getDismissDelay |
* This method returns the time the ToolTip will be shown before being |
302 |
* @return int |
* hidden. |
303 |
*/ |
* |
304 |
|
* @return The time the ToolTip will be shown before being hidden. |
305 |
|
*/ |
306 |
public int getDismissDelay() |
public int getDismissDelay() |
307 |
{ |
{ |
308 |
return 0; // TODO |
return insideTimer.getDelay(); |
309 |
} |
} |
310 |
|
|
311 |
/** |
/** |
312 |
* setDismissDelay |
* This method sets the time the ToolTip will be shown before being hidden. |
313 |
* @param delay TODO |
* |
314 |
*/ |
* @param delay The time the ToolTip will be shown before being hidden. |
315 |
|
*/ |
316 |
public void setDismissDelay(int delay) |
public void setDismissDelay(int delay) |
317 |
{ |
{ |
318 |
// TODO |
insideTimer.setDelay(delay); |
319 |
} |
} |
320 |
|
|
321 |
/** |
/** |
322 |
* getReshowDelay |
* This method returns the amount of delay where if the mouse re-enters a |
323 |
* @return int |
* Component, the tooltip will be shown immediately. |
324 |
*/ |
* |
325 |
|
* @return The reshow delay. |
326 |
|
*/ |
327 |
public int getReshowDelay() |
public int getReshowDelay() |
328 |
{ |
{ |
329 |
return 0; // TODO |
return exitTimer.getDelay(); |
330 |
} |
} |
331 |
|
|
332 |
/** |
/** |
333 |
* setReshowDelay |
* This method sets the amount of delay where if the mouse re-enters a |
334 |
* @param delay TODO |
* Component, the tooltip will be shown immediately. |
335 |
*/ |
* |
336 |
|
* @param delay The reshow delay. |
337 |
|
*/ |
338 |
public void setReshowDelay(int delay) |
public void setReshowDelay(int delay) |
339 |
{ |
{ |
340 |
// TODO |
exitTimer.setDelay(delay); |
341 |
} |
} |
342 |
|
|
343 |
/** |
/** |
344 |
* registerComponent |
* This method registers a JComponent with the ToolTipManager. |
345 |
* @param component TODO |
* |
346 |
*/ |
* @param component The JComponent to register with the ToolTipManager. |
347 |
|
*/ |
348 |
public void registerComponent(JComponent component) |
public void registerComponent(JComponent component) |
349 |
{ |
{ |
350 |
// TODO |
component.addMouseListener(this); |
351 |
|
component.addMouseMotionListener(this); |
352 |
} |
} |
353 |
|
|
354 |
/** |
/** |
355 |
* unregisterComponent |
* This method unregisters a JComponent with the ToolTipManager. |
356 |
* @param component TODO |
* |
357 |
*/ |
* @param component The JComponent to unregister with the ToolTipManager. |
358 |
|
*/ |
359 |
public void unregisterComponent(JComponent component) |
public void unregisterComponent(JComponent component) |
360 |
{ |
{ |
361 |
// TODO |
component.removeMouseMotionListener(this); |
362 |
|
component.removeMouseListener(this); |
363 |
} |
} |
364 |
|
|
365 |
/** |
/** |
366 |
* mouseEntered |
* This method is called whenever the mouse enters a JComponent registered |
367 |
* @param event TODO |
* with the ToolTipManager. When the mouse enters within the period of time |
368 |
*/ |
* specified by the reshow delay, the tooltip will be displayed |
369 |
|
* immediately. Otherwise, it must wait for the initial delay before |
370 |
|
* displaying the tooltip. |
371 |
|
* |
372 |
|
* @param event The MouseEvent. |
373 |
|
*/ |
374 |
public void mouseEntered(MouseEvent event) |
public void mouseEntered(MouseEvent event) |
375 |
{ |
{ |
376 |
// TODO |
if (currentComponent != null |
377 |
} |
&& getContentPaneDeepestComponent(event) == currentComponent) |
378 |
|
return; |
379 |
/** |
currentPoint = event.getPoint(); |
380 |
* mouseExited |
currentComponent = (Component) event.getSource(); |
381 |
* @param event TODO |
|
382 |
*/ |
if (exitTimer.isRunning()) |
383 |
|
{ |
384 |
|
exitTimer.stop(); |
385 |
|
showTip(); |
386 |
|
insideTimer.start(); |
387 |
|
return; |
388 |
|
} |
389 |
|
|
390 |
|
// This should always be stopped unless we have just fake-exited. |
391 |
|
if (! enterTimer.isRunning()) |
392 |
|
enterTimer.start(); |
393 |
|
} |
394 |
|
|
395 |
|
/** |
396 |
|
* This method is called when the mouse exits a JComponent registered with |
397 |
|
* the ToolTipManager. When the mouse exits, the tooltip should be hidden |
398 |
|
* immediately. |
399 |
|
* |
400 |
|
* @param event The MouseEvent. |
401 |
|
*/ |
402 |
public void mouseExited(MouseEvent event) |
public void mouseExited(MouseEvent event) |
403 |
{ |
{ |
404 |
// TODO |
if (getContentPaneDeepestComponent(event) == currentComponent) |
405 |
} |
return; |
406 |
|
|
407 |
/** |
currentPoint = event.getPoint(); |
408 |
* mousePressed |
currentComponent = null; |
409 |
* @param event TODO |
hideTip(); |
410 |
*/ |
|
411 |
|
if (! enterTimer.isRunning() && insideTimer.isRunning()) |
412 |
|
exitTimer.start(); |
413 |
|
if (enterTimer.isRunning()) |
414 |
|
enterTimer.stop(); |
415 |
|
if (insideTimer.isRunning()) |
416 |
|
insideTimer.stop(); |
417 |
|
} |
418 |
|
|
419 |
|
/** |
420 |
|
* This method is called when the mouse is pressed on a JComponent |
421 |
|
* registered with the ToolTipManager. When the mouse is pressed, the |
422 |
|
* tooltip (if it is shown) must be hidden immediately. |
423 |
|
* |
424 |
|
* @param event The MouseEvent. |
425 |
|
*/ |
426 |
public void mousePressed(MouseEvent event) |
public void mousePressed(MouseEvent event) |
427 |
{ |
{ |
428 |
// TODO |
currentPoint = event.getPoint(); |
429 |
} |
if (enterTimer.isRunning()) |
430 |
|
enterTimer.restart(); |
431 |
/** |
else if (insideTimer.isRunning()) |
432 |
* mouseDragged |
{ |
433 |
* @param event TODO |
insideTimer.stop(); |
434 |
*/ |
hideTip(); |
435 |
|
} |
436 |
|
currentComponent.invalidate(); |
437 |
|
currentComponent.validate(); |
438 |
|
currentComponent.repaint(); |
439 |
|
} |
440 |
|
|
441 |
|
/** |
442 |
|
* This method is called when the mouse is dragged in a JComponent |
443 |
|
* registered with the ToolTipManager. |
444 |
|
* |
445 |
|
* @param event The MouseEvent. |
446 |
|
*/ |
447 |
public void mouseDragged(MouseEvent event) |
public void mouseDragged(MouseEvent event) |
448 |
{ |
{ |
449 |
// TODO |
currentPoint = event.getPoint(); |
450 |
|
if (enterTimer.isRunning()) |
451 |
|
enterTimer.restart(); |
452 |
} |
} |
453 |
|
|
454 |
/** |
/** |
455 |
* mouseMoved |
* This method is called when the mouse is moved in a JComponent registered |
456 |
* @param event TODO |
* with the ToolTipManager. |
457 |
*/ |
* |
458 |
|
* @param event The MouseEvent. |
459 |
|
*/ |
460 |
public void mouseMoved(MouseEvent event) |
public void mouseMoved(MouseEvent event) |
461 |
{ |
{ |
462 |
// TODO |
currentPoint = event.getPoint(); |
463 |
|
if (enterTimer.isRunning()) |
464 |
|
enterTimer.restart(); |
465 |
|
} |
466 |
|
|
467 |
|
/** |
468 |
|
* This method displays the ToolTip. It can figure out the method needed to |
469 |
|
* show it as well (whether to display it in heavyweight/lightweight panel |
470 |
|
* or a window.) |
471 |
|
*/ |
472 |
|
private void showTip() |
473 |
|
{ |
474 |
|
if (! enabled) |
475 |
|
return; |
476 |
|
|
477 |
|
if (currentTip == null |
478 |
|
|| currentTip.getComponent() != currentComponent |
479 |
|
&& currentComponent instanceof JComponent) |
480 |
|
currentTip = ((JComponent) currentComponent).createToolTip(); |
481 |
|
Point p = currentPoint; |
482 |
|
Dimension dims = currentTip.getPreferredSize(); |
483 |
|
if (canToolTipFit(currentTip)) |
484 |
|
{ |
485 |
|
JLayeredPane pane = ((JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class, |
486 |
|
currentComponent)) |
487 |
|
.getLayeredPane(); |
488 |
|
|
489 |
|
// This should never happen, but just in case. |
490 |
|
if (pane == null) |
491 |
|
return; |
492 |
|
|
493 |
|
if (containerPanel != null) |
494 |
|
hideTip(); |
495 |
|
if (isLightWeightPopupEnabled()) |
496 |
|
{ |
497 |
|
containerPanel = new Panel(); |
498 |
|
JRootPane root = new JRootPane(); |
499 |
|
root.getContentPane().add(currentTip); |
500 |
|
containerPanel.add(root); |
501 |
|
} |
502 |
|
else |
503 |
|
{ |
504 |
|
containerPanel = new JPanel(); |
505 |
|
containerPanel.add(currentTip); |
506 |
|
} |
507 |
|
LayoutManager lm = containerPanel.getLayout(); |
508 |
|
if (lm instanceof FlowLayout) |
509 |
|
{ |
510 |
|
FlowLayout fm = (FlowLayout) lm; |
511 |
|
fm.setVgap(0); |
512 |
|
fm.setHgap(0); |
513 |
|
} |
514 |
|
|
515 |
|
p = getGoodPoint(p, pane, currentTip, dims); |
516 |
|
|
517 |
|
pane.add(containerPanel); |
518 |
|
containerPanel.setBounds(p.x, p.y, dims.width, dims.height); |
519 |
|
currentTip.setBounds(0, 0, dims.width, dims.height); |
520 |
|
|
521 |
|
pane.revalidate(); |
522 |
|
pane.repaint(); |
523 |
|
} |
524 |
|
else |
525 |
|
{ |
526 |
|
SwingUtilities.convertPointToScreen(p, currentComponent); |
527 |
|
tooltipWindow = new JWindow(); |
528 |
|
tooltipWindow.getContentPane().add(currentTip); |
529 |
|
tooltipWindow.setFocusable(false); |
530 |
|
tooltipWindow.pack(); |
531 |
|
tooltipWindow.setBounds(p.x, p.y, dims.width, dims.height); |
532 |
|
tooltipWindow.show(); |
533 |
|
} |
534 |
|
currentTip.setVisible(true); |
535 |
|
} |
536 |
|
|
537 |
|
/** |
538 |
|
* This method hides the ToolTip. |
539 |
|
*/ |
540 |
|
private void hideTip() |
541 |
|
{ |
542 |
|
if (currentTip == null || ! currentTip.isVisible() || ! enabled) |
543 |
|
return; |
544 |
|
currentTip.setVisible(false); |
545 |
|
if (containerPanel != null) |
546 |
|
{ |
547 |
|
Container parent = containerPanel.getParent(); |
548 |
|
if (parent == null) |
549 |
|
return; |
550 |
|
parent.remove(containerPanel); |
551 |
|
parent.invalidate(); |
552 |
|
parent.validate(); |
553 |
|
parent.repaint(); |
554 |
|
|
555 |
|
parent = currentTip.getParent(); |
556 |
|
if (parent == null) |
557 |
|
return; |
558 |
|
parent.remove(currentTip); |
559 |
|
|
560 |
|
containerPanel = null; |
561 |
|
} |
562 |
|
if (tooltipWindow != null) |
563 |
|
{ |
564 |
|
tooltipWindow.hide(); |
565 |
|
tooltipWindow.dispose(); |
566 |
|
tooltipWindow = null; |
567 |
|
} |
568 |
|
} |
569 |
|
|
570 |
|
/** |
571 |
|
* This method returns a point in the LayeredPane where the ToolTip can be |
572 |
|
* shown. The point returned (if the ToolTip is to be displayed at the |
573 |
|
* preferred dimensions) will always place the ToolTip inside the |
574 |
|
* currentComponent if possible. |
575 |
|
* |
576 |
|
* @param p The last known good point for the mouse. |
577 |
|
* @param c The JLayeredPane in the first RootPaneContainer up from the |
578 |
|
* currentComponent. |
579 |
|
* @param tip The ToolTip to display. |
580 |
|
* @param dims The ToolTip preferred dimensions (can be null). |
581 |
|
* |
582 |
|
* @return A good point to place the ToolTip. |
583 |
|
*/ |
584 |
|
private Point getGoodPoint(Point p, JLayeredPane c, JToolTip tip, |
585 |
|
Dimension dims) |
586 |
|
{ |
587 |
|
if (dims == null) |
588 |
|
dims = tip.getPreferredSize(); |
589 |
|
Rectangle bounds = currentComponent.getBounds(); |
590 |
|
if (p.x + dims.width > bounds.width) |
591 |
|
p.x = bounds.width - dims.width; |
592 |
|
if (p.y + dims.height > bounds.height) |
593 |
|
p.y = bounds.height - dims.height; |
594 |
|
|
595 |
|
p = SwingUtilities.convertPoint(currentComponent, p, c); |
596 |
|
return p; |
597 |
|
} |
598 |
|
|
599 |
|
/** |
600 |
|
* This method returns the deepest component in the content pane for the |
601 |
|
* first RootPaneContainer up from the currentComponent. This method is |
602 |
|
* used in conjunction with one of the mouseXXX methods. |
603 |
|
* |
604 |
|
* @param e The MouseEvent. |
605 |
|
* |
606 |
|
* @return The deepest component in the content pane. |
607 |
|
*/ |
608 |
|
private Component getContentPaneDeepestComponent(MouseEvent e) |
609 |
|
{ |
610 |
|
Component source = (Component) e.getSource(); |
611 |
|
Container parent = (Container) SwingUtilities.getAncestorOfClass(JRootPane.class, |
612 |
|
currentComponent); |
613 |
|
if (parent == null) |
614 |
|
return null; |
615 |
|
parent = ((JRootPane) parent).getContentPane(); |
616 |
|
Point p = e.getPoint(); |
617 |
|
p = SwingUtilities.convertPoint(source, p, parent); |
618 |
|
Component target = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y); |
619 |
|
return target; |
620 |
|
} |
621 |
|
|
622 |
|
/** |
623 |
|
* This method returns whether the ToolTip can fit in the first |
624 |
|
* RootPaneContainer up from the currentComponent. |
625 |
|
* |
626 |
|
* @param tip The ToolTip. |
627 |
|
* |
628 |
|
* @return Whether the ToolTip can fit. |
629 |
|
*/ |
630 |
|
private boolean canToolTipFit(JToolTip tip) |
631 |
|
{ |
632 |
|
JRootPane root = (JRootPane) SwingUtilities.getAncestorOfClass(JRootPane.class, |
633 |
|
currentComponent); |
634 |
|
if (root == null) |
635 |
|
return false; |
636 |
|
Dimension pref = tip.getPreferredSize(); |
637 |
|
Dimension rootSize = root.getSize(); |
638 |
|
if (rootSize.width > pref.width && rootSize.height > pref.height) |
639 |
|
return true; |
640 |
|
return false; |
641 |
} |
} |
642 |
} |
} |