Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何控制JavaFX工具提示';什么事耽搁了?_Java_Css_Javafx 8_Fxml - Fatal编程技术网

如何控制JavaFX工具提示';什么事耽搁了?

如何控制JavaFX工具提示';什么事耽搁了?,java,css,javafx-8,fxml,Java,Css,Javafx 8,Fxml,我在和他玩。我意识到,对我个人来说,悬停在某物上和工具提示实际出现之间的延迟太长了。查看API可以发现: 通常,当鼠标移动到控件上时,工具提示被“激活”。工具提示变为“激活”与实际显示之间通常会有一些延迟。细节(如延迟量等)留给皮肤实现 经过进一步调查,我无法找到任何控制延误的可能性。没有关于延迟时间的信息,运行时对getCssMetaData()的评估也没有帮助 我知道有一种方法可以通过鼠标输入(…)和鼠标退出(…)手动控制工具提示,但真的没有其他方法吗?还是我缺少一个明显的解决方案?有一个针

我在和他玩。我意识到,对我个人来说,悬停在某物上和工具提示实际出现之间的延迟太长了。查看API可以发现:

通常,当鼠标移动到控件上时,工具提示被“激活”。工具提示变为“激活”与实际显示之间通常会有一些延迟。细节(如延迟量等)留给皮肤实现

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


我知道有一种方法可以通过鼠标输入(…)和鼠标退出(…)手动控制工具提示,但真的没有其他方法吗?还是我缺少一个明显的解决方案?

有一个针对此的现有功能请求:

该功能请求目前计划集成到Java 9中。我链接的问题附带了一个补丁,您可以应用它,以便在早期的Java版本中获得此功能

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


我通过反射使用下一个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<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();
      }
   });
}
公共静态工具提示(最终节点,最终工具提示工具提示){
setOnMouseMoved(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
//+15将工具提示移动到鼠标光标下方15个像素处;
//如果不更改工具提示的y坐标,则
//将看到屏幕持续闪烁
show(节点,event.getScreenX(),event.getScreenY()+15);
}
});  
setOnMouseExited(新的EventHandler(){
@凌驾
公共无效句柄(MouseeEvent事件){
tooltip.hide();
}
});
}

扩展工具提示或添加应用程序类。(仅限java8)

/**
*
*黑客工具提示行为
*/
静止的{
试一试{
工具提示obj=新工具提示();
Class clazz=obj.getClass().getDeclaredClasses()[1];
构造函数=clazz.getDeclaredConstructor(
上课时间,
上课时间,
上课时间,
布尔类);
constructor.setAccessible(true);
对象tooltipBehavior=constructor.newInstance(
新的持续时间(250),//打开
新持续时间(5000),//可见
新的持续时间(200),//关闭
假);
fieldBehavior=obj.getClass().getDeclaredField(“行为”);
fieldBehavior.setAccessible(true);
fieldBehavior.set(对象,工具提示行为);
}
捕获(例外e){
错误(e);
}
}

事实上,自JavaFX2以来,工具提示的行为在类
工具提示
内部由静态字段
行为
进行管理,该字段不能使用特定的公共方法进行修改,因此目前,如果您不想重新发明控制盘或等待Java 9,唯一的方法是使用as next:

/**
*允许修改工具提示的默认行为的Hack。
*@param openDelay打开延迟,知道默认设置为1000。
*@param visibleDuration可见持续时间,知道默认设置为5000。
*@param closeDelay关闭延迟,知道默认设置为200。
*@param hideOnExit指示工具提示是否应在退出时隐藏,
*知道默认情况下它被设置为false。
*/
私有静态void updatetoltipbehavior(双openDelay、双visibleDuration、,
双关闭延迟,布尔hideOnExit){
试一试{
//获取非公共字段“行为”
fieldBehavior=Tooltip.class.getDeclaredField(“行为”);
//使字段可访问,以便能够获取和设置其值
fieldBehavior.setAccessible(true);
//获取静态字段的值
Object objBehavior=fieldBehavior.get(null);
//获取私有静态内部类TooltipBehavior的构造函数
构造函数构造函数=objBehavior.getClass().getDeclaredConstructor(
Duration.class,Duration.class,Duration.class,boolean.class
);
//使构造函数可访问,以便能够调用它
constructor.setAccessible(true);
//创建私有静态内部类TooltipBehavior的新实例
对象tooltipBehavior=constructor.newInstance(
新持续时间(openDelay),新持续时间(visibleDuration),
新持续时间(关闭延迟),hideOnExit
);
//设置TooltipBehavior的新实例
fieldBehavior.set(null,tooltipBehavior);
}捕获(例外e){
抛出新的非法状态异常(e);
}
}

您好,在我的声誉达到50之前,我无法发表评论,但我想纠正布鲁诺·帕多的回答。他发布的代码在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);
    }
}
/**
*
*黑客工具提示行为
*/
静止的{
试一试{
工具提示obj=新工具提示();
Class clazz=obj.getClass().getDeclaredClasses()[0];
构造函数=clazz.getDeclaredConstructor(
上课时间,
上课时间,
上课时间,
布尔类);
constructor.setAccessible(true);
对象tooltipBehavior=constructor.newInsta
/**
 * 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);
    }
}
/**
 * <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);
    }
}
Tooltip tooltip = new Tooltip("A tooltip");
tooltip.setShowDelay(Duration.seconds(3));
.tooltip {
    -fx-show-delay: 250ms;
}