JavaFX Tooltip で遊んでいました。個人的には、何かにカーソルを合わせてから実際に表示されるツールチップまでの遅延が長すぎることに気付きました。 APIを見ると次のことがわかります。
通常、マウスがコントロール上を移動すると、ツールチップが「アクティブ化」されます。通常、ツールチップが「アクティブ」になってから実際に表示されるまでに多少の遅延があります。詳細(遅延量など)は、スキンの実装に任されています。
さらに調査したところ、この動作を制御する可能性を見つけることができませんでした。 JavaFX CSS Reference には遅延時間に関する情報がなく、getCssMetaData()
のランタイム評価も役に立たなかった。
onMouseEntered
とonMouseExited
を介してツールチップを手動で制御する方法があることは知っていますが、実際には他に方法はありませんか?または、明らかなオプションがありませんか?
これには既存の機能リクエストがあります: JDK-8090477ツールチップのカスタマイズ可能な可視性のタイミング 。
現在、機能要求はJava 9への統合が予定されています。リンクした問題に添付するパッチは、以前のJavaバージョンでこの機能を利用できるように適用できるパッチです。
他のオプションは、次のいずれかの手法を使用して、独自のポップアップコントロールを作成することです。
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();
}
}
上記の実装では、説明できない遅延がまだあることがあります。
以下は私のために働いており、遅延を完全に削除しました:
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();
}
});
}
Java 9以降では、次のことができます
Tooltip tooltip = new Tooltip("A tooltip");
tooltip.setShowDelay(Duration.seconds(3));
ツールチップが表示されてから再び非表示になるまでの遅延のために、hideDelay
プロパティもあります。デフォルト値は、showDelay
の場合は1秒、hideDelay
の場合は200ミリ秒です。
ツールチップを拡張するか、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);
}
}
こんにちは、私は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を待っている間にツールチップの遅延を編集しようとしている人に役立つことを願っています。
実際、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);
}
}
JavaFx 9では、CSSを介してツールチップの遅延を設定できます。スタイルシートでこれを行うのは変に聞こえますが、おそらくこれは「詳細(遅延の量など)はスキンの実装に任されている」と言うときの意味です。
https://docs.Oracle.com/javase/9/docs/api/javafx/scene/doc-files/cssref.html#tooltip
したがって、次のようなことができます。
.tooltip {
-fx-show-delay: 250ms;
}