我正在玩JavaFX Tooltip。我意识到,就个人而言,徘徊在某些东西和实际出现的工具提示之间的延迟太长了。 API中的内容显示:
通常,工具提示已被激活"当鼠标移动到控件上时。在Tooltip变为"激活"之间通常存在一些延迟。当它实际显示时。详细信息(例如延迟量等)留给了Skin实现。
经过一些进一步调查后,我无法找到任何控制此行为的可能性。 JavaFX CSS Reference没有关于延迟时间的信息,getCssMetaData()
的运行时评估也没有帮助。
我知道,有一种方法可以通过onMouseEntered
和onMouseExited
手动控制工具提示,但是真的没有办法吗?或者我错过了一个明显的选择?
答案 0 :(得分:42)
我通过Reflection
使用下一个hackpublic static void hackTooltipStartTiming(Tooltip tooltip) {
try {
Field fieldBehavior = tooltip.getClass().getDeclaredField("BEHAVIOR");
fieldBehavior.setAccessible(true);
Object objBehavior = fieldBehavior.get(tooltip);
Field fieldTimer = objBehavior.getClass().getDeclaredField("activationTimer");
fieldTimer.setAccessible(true);
Timeline objTimer = (Timeline) fieldTimer.get(objBehavior);
objTimer.getKeyFrames().clear();
objTimer.getKeyFrames().add(new KeyFrame(new Duration(250)));
} catch (Exception e) {
e.printStackTrace();
}
}
答案 1 :(得分:16)
现有功能请求:JDK-8090477 Customizable visibility timing for Tooltip。
功能请求当前已安排集成到Java 9.附加到我链接的问题是一个可以应用的补丁,允许您在早期Java版本中获得此功能。
您的另一个选择是使用以下技术之一创建自己的弹出控件:
答案 2 :(得分:6)
I find that with the above implementation there's still a delay sometimes that I cannot explain.
The following has worked for me and removed the delay entirely:
public static void bindTooltip(final Node node, final Tooltip tooltip){
node.setOnMouseMoved(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
// +15 moves the tooltip 15 pixels below the mouse cursor;
// if you don't change the y coordinate of the tooltip, you
// will see constant screen flicker
tooltip.show(node, event.getScreenX(), event.getScreenY() + 15);
}
});
node.setOnMouseExited(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event){
tooltip.hide();
}
});
}
答案 3 :(得分:6)
在Java 9及更高版本中,您可以执行
Tooltip tooltip = new Tooltip("A tooltip");
tooltip.setShowDelay(Duration.seconds(3));
还有hideDelay
属性,用于显示工具提示之间的延迟并再次隐藏。 showDelay
的默认值为1秒,hideDelay
的默认值为200毫秒。
答案 4 :(得分:3)
扩展工具提示或放置Application类。 (只有java8)
/**
* <p>
* Hack TooltipBehavior
*/
static {
try {
Tooltip obj = new Tooltip();
Class<?> clazz = obj.getClass().getDeclaredClasses()[1];
Constructor<?> constructor = clazz.getDeclaredConstructor(
Duration.class,
Duration.class,
Duration.class,
boolean.class);
constructor.setAccessible(true);
Object tooltipBehavior = constructor.newInstance(
new Duration(250), //open
new Duration(5000), //visible
new Duration(200), //close
false);
Field fieldBehavior = obj.getClass().getDeclaredField("BEHAVIOR");
fieldBehavior.setAccessible(true);
fieldBehavior.set(obj, tooltipBehavior);
}
catch (Exception e) {
Logger.error(e);
}
}
答案 5 :(得分:3)
您好,我无法发表评论,直到我达到50的声誉,但我想纠正Bruno Pado给出的回复。他发布的代码在JDK 8u121中不起作用。问题在于它所访问的声明字段。修复很简单,将索引从1更改为0.下面发布的工作代码:
/**
* <p>
* Hack TooltipBehavior
*/
static {
try {
Tooltip obj = new Tooltip();
Class<?> clazz = obj.getClass().getDeclaredClasses()[0];
Constructor<?> constructor = clazz.getDeclaredConstructor(
Duration.class,
Duration.class,
Duration.class,
boolean.class);
constructor.setAccessible(true);
Object tooltipBehavior = constructor.newInstance(
new Duration(250), //open
new Duration(5000), //visible
new Duration(200), //close
false);
Field fieldBehavior = obj.getClass().getDeclaredField("BEHAVIOR");
fieldBehavior.setAccessible(true);
fieldBehavior.set(obj, tooltipBehavior);
}
catch (Exception e) {
Logger.error(e);
}
}
希望这可以帮助那些在我们等待JFX9时编辑工具提示延迟的人。
答案 6 :(得分:2)
确实,自JavaFX 2以来,工具提示的行为在类Tooltip
内部由静态字段BEHAVIOR
内部管理,无法使用特定的公共方法进行修改,所以现在如果你不这样做。我想重新发明轮子或等待Java 9,唯一的方法是使用Reflection API作为下一个:
/**
* Hack allowing to modify the default behavior of the tooltips.
* @param openDelay The open delay, knowing that by default it is set to 1000.
* @param visibleDuration The visible duration, knowing that by default it is set to 5000.
* @param closeDelay The close delay, knowing that by default it is set to 200.
* @param hideOnExit Indicates whether the tooltip should be hide on exit,
* knowing that by default it is set to false.
*/
private static void updateTooltipBehavior(double openDelay, double visibleDuration,
double closeDelay, boolean hideOnExit) {
try {
// Get the non public field "BEHAVIOR"
Field fieldBehavior = Tooltip.class.getDeclaredField("BEHAVIOR");
// Make the field accessible to be able to get and set its value
fieldBehavior.setAccessible(true);
// Get the value of the static field
Object objBehavior = fieldBehavior.get(null);
// Get the constructor of the private static inner class TooltipBehavior
Constructor<?> constructor = objBehavior.getClass().getDeclaredConstructor(
Duration.class, Duration.class, Duration.class, boolean.class
);
// Make the constructor accessible to be able to invoke it
constructor.setAccessible(true);
// Create a new instance of the private static inner class TooltipBehavior
Object tooltipBehavior = constructor.newInstance(
new Duration(openDelay), new Duration(visibleDuration),
new Duration(closeDelay), hideOnExit
);
// Set the new instance of TooltipBehavior
fieldBehavior.set(null, tooltipBehavior);
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
答案 7 :(得分:1)
在JavaFx 9中,可以通过CSS设置工具提示延迟。在样式表中执行此操作听起来很变态,但是当他们说“细节(如延迟量等)留给Skin实现时”时,这可能是它们的意思。
https://docs.oracle.com/javase/9/docs/api/javafx/scene/doc-files/cssref.html#tooltip
因此您可以执行以下操作:
.tooltip {
-fx-show-delay: 250ms;
}