web-dev-qa-db-ja.com

JavaFX Tooltipの遅延を制御する方法は?

JavaFX Tooltip で遊んでいました。個人的には、何かにカーソルを合わせてから実際に表示されるツールチップまでの遅延が長すぎることに気付きました。 APIを見ると次のことがわかります。

通常、マウスがコントロール上を移動すると、ツールチップが「アクティブ化」されます。通常、ツールチップが「アクティブ」になってから実際に表示されるまでに多少の遅延があります。詳細(遅延量など)は、スキンの実装に任されています。

さらに調査したところ、この動作を制御する可能性を見つけることができませんでした。 JavaFX CSS Reference には遅延時間に関する情報がなく、getCssMetaData()のランタイム評価も役に立たなかった。

onMouseEnteredonMouseExitedを介してツールチップを手動で制御する方法があることは知っていますが、実際には他に方法はありませんか?または、明らかなオプションがありませんか?

28
Turing85

これには既存の機能リクエストがあります: JDK-8090477ツールチップのカスタマイズ可能な可視性のタイミング

現在、機能要求はJava 9への統合が予定されています。リンクした問題に添付するパッチは、以前のJavaバージョンでこの機能を利用できるように適用できるパッチです。

他のオプションは、次のいずれかの手法を使用して、独自のポップアップコントロールを作成することです。

16
jewelsea

Reflection経由でこれに次のハックを使用します

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();
    }
}
42
Igor Luzhanov

上記の実装では、説明できない遅延がまだあることがあります。

以下は私のために働いており、遅延を完全に削除しました:

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();
      }
   });
}
8
Aleks Messier

Java 9以降では、次のことができます

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

ツールチップが表示されてから再び非表示になるまでの遅延のために、hideDelayプロパティもあります。デフォルト値は、showDelayの場合は1秒、hideDelayの場合は200ミリ秒です。

7
James_D

ツールチップを拡張するか、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);
        }
    }
4
Bruno Prado

こんにちは、私は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);
    }
}

これがJFX9を待っている間にツールチップの遅延を編集しようとしている人に役立つことを願っています。

3
d_scalzi

実際、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);
    }
}
2
Nicolas Filotto

JavaFx 9では、CSSを介してツールチップの遅延を設定できます。スタイルシートでこれを行うのは変に聞こえますが、おそらくこれは「詳細(遅延の量など)はスキンの実装に任されている」と言うときの意味です。

https://docs.Oracle.com/javase/9​​/docs/api/javafx/scene/doc-files/cssref.html#tooltip

したがって、次のようなことができます。

.tooltip {
    -fx-show-delay: 250ms;
}
1
Franz Deschler