如何控制JavaFX Tooltip的延迟?

我正在玩JavaFX Tooltip 。 我意识到,就我个人而言,徘徊在某些东西和实际出现的工具提示之间的延迟太长了。 API中的内容显示:

通常,当鼠标在控件上移动时,工具提示会“激活”。 工具提示变为“激活”和实际显示之间通常存在一些延迟。 详细信息(例如延迟量等)留给Skin实现。

经过一些进一步的调查后,我无法找到任何控制此行为的可能性。 JavaFX CSS Reference没有关于延迟时间的信息, getCssMetaData()的运行时评估也没有帮助。

我知道,有一种方法可以通过onMouseEnteredonMouseExited手动控制工具提示,但是真的没有办法吗? 或者我错过了一个明显的选择?

现有function请求: JDK-8090477 Tooltip的可自定义可见性计时 。

function请求当前已安排集成到Java 9.附加到我链接的问题是一个可以应用的补丁,以允许您在早期Java版本中获得此function。

您的另一个选择是使用以下技术之一创建自己的弹出控件:

  • JavaFX 2自定义弹出窗格

我通过Reflection使用下一个hack

 public 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(); } } 

我发现,通过上述实现,有时我仍然无法解释。

以下内容对我有用,并完全消除了延迟:

 public static void bindTooltip(final Node node, final Tooltip tooltip){ node.setOnMouseMoved(new EventHandler(){ @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(){ @Override public void handle(MouseEvent event){ tooltip.hide(); } }); } 

扩展工具提示或放置Application类。 (只有java8)

  /** * 

* 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); } }

您好,我不能发表评论,直到我达到50的声誉,但我想纠正布鲁诺帕多给出的回应。 他发布的代码在JDK 8u121中不起作用。 问题在于它访问的声明字段。 修复很简单,将索引从1更改为0.工作代码发布如下:

 /** * 

* 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时编辑工具提示延迟的人。

确实,自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); } } 

在Java 9及更高版本中,您可以这样做

 Tooltip tooltip = new Tooltip("A tooltip"); tooltip.setShowDelay(Duration.seconds(3)); 

还有一个hideDelay属性,用于显示工具提示之间的延迟并再次隐藏它。 showDelay的默认值为1秒, showDelay的默认值为200毫秒。