Issue
Is there any way to increase the amount of time a Tooltip stays up, when tooltips are inside FXML created by Scene Builder?
There is something called a "href="https://docs.oracle.com/javase/10/docs/api/javafx/scene/control/Tooltip.html#setShowDuration(javafx.util.Duration)" rel="nofollow noreferrer">show duration" since Java 9 if you're creating Tooltips in code, but there doesn't seem to be a way to adjust this for FXML tooltips.
Disabling the auto-hide entirely would also be helpful (so it only hides when the mouse moves off the node), but even with the auto-hide checkbox unchecked in Scene Builder, the things still auto hide after what should be 5000ms.
Interestingly/strangely I did find that if you do this in css:
.tooltip {
-fx-show-duration: 10000;
}
...it seems to try, but you get an exception (it's a shame they didn't make this parameter a double in milliseconds, maybe this would work then...)
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: class java.lang.Double cannot be cast to class javafx.util.Duration (java.lang.Double is in module java.base of loader 'bootstrap'; javafx.util.Duration is in unnamed module of loader 'app')
at javafx.scene.control.Tooltip.getShowDuration(Tooltip.java:363)
at javafx.scene.control.Tooltip$TooltipBehavior.lambda$new$0(Tooltip.java:923)
at javafx.animation.Animation.finished(Animation.java:1131)
at javafx.animation.AnimationAccessorImpl.finished(AnimationAccessorImpl.java:49)
at com.sun.scenario.animation.shared.SingleLoopClipEnvelope.timePulse(SingleLoopClipEnvelope.java:103)
at javafx.animation.Animation.doTimePulse(Animation.java:1101)
at javafx.animation.Animation$1.lambda$timePulse$0(Animation.java:186)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.Animation$1.timePulse(Animation.java:185)
at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:515)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:499)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:492)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:320)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
at java.base/java.lang.Thread.run(Thread.java:834)
Solution
The PopupWindow#autoHide
property does not control whether or not a Tooltip
will hide after a certain amount of time. What that property does is control whether or not a popup will close if it loses focus.
I don't think you can disable the hide-after-show-duration feature of tooltips. At least, not unless you handle showing and hiding them yourself. When a tooltip is installed, a number of mouse event handlers are added to the target node. It's these handlers that implement, via animations used as timers, the showing and hiding of the tooltip. As far as I can tell, you can't prevent the hide-after-show-duration timer from starting.
As for setting the show duration via CSS, you're on the right track. The Tooltip#showDuration
property is styleable. That means if you add your stylesheet to the scene, then every tooltip shown by hovering over nodes in that scene will have the new duration. The only problem is that you specified a number in your stylesheet, not a duration. From the JavaFX CSS Reference Guide, the syntax for durations is:
<duration>
A duration is a
<number>
with second or millisecond units, or the valueindefinite
.[<number>[ s | ms ]] | indefinite
s
: duration in secondsms
: duration in milliseconds. One second is 1000 milliseconds.indefinite
: SeeDuration.INDEFINITE
For example:
.tooltip {
-fx-show-duration: 10000ms; /* or 10s */
}
I'm honestly a little surprised it's not defined to default to a unit if none is given. I'm also surprised the CSS parser doesn't catch that the parsed type is not the correct type, and instead lets other code error out by implicitly trying to cast to Duration
when grabbing the value from the generic property.
Answered By - Slaw
Answer Checked By - Mary Flores (JavaFixing Volunteer)