# This patch file was generated by NetBeans IDE # Following Index: paths are relative to: /home/user/openjfx/rt # This patch can be applied using context Tools: Patch action on respective folder. # It uses platform neutral UTF-8 encoding and \n newlines. # Above lines and this line are ignored by the patching process. Index: modules/controls/src/main/java/javafx/scene/control/Tooltip.java --- modules/controls/src/main/java/javafx/scene/control/Tooltip.java +++ modules/controls/src/main/java/javafx/scene/control/Tooltip.java @@ -37,6 +37,7 @@ import javafx.css.StyleableStringProperty; import com.sun.javafx.css.converters.BooleanConverter; +import com.sun.javafx.css.converters.DurationConverter; import com.sun.javafx.css.converters.EnumConverter; import com.sun.javafx.css.converters.SizeConverter; import com.sun.javafx.css.converters.StringConverter; @@ -48,6 +49,8 @@ import javafx.animation.KeyFrame; import javafx.animation.Timeline; +import javafx.beans.InvalidationListener; +import javafx.beans.Observable; import javafx.beans.property.*; import javafx.beans.value.WritableValue; import javafx.css.CssMetaData; @@ -106,6 +109,16 @@ * Button button = new Button("Hover Over Me"); * button.setTooltip(new Tooltip("Tooltip for Button")); * + * + *

The duration that the tooltips are shown, hide on over and hide on exit are + * applied globally. + *

+ * Tooltip.setShowDelay(new Duration(200));
+ * Tooltip.setShowDurationOnOver(new Duration(10000));
+ * Tooltip.setShowDurationOnExit(new Duration(100));
+ * 
+ * Show delay default value is 1 second, show duration on over is 5 second and + * show duration on exit is 200 milliseconds. * @since JavaFX 2.0 */ @IDProperty("id") @@ -121,8 +134,7 @@ private static int TOOLTIP_XOFFSET = 10; private static int TOOLTIP_YOFFSET = 7; - private static TooltipBehavior BEHAVIOR = new TooltipBehavior( - new Duration(1000), new Duration(5000), new Duration(200), false); + private static TooltipBehavior BEHAVIOR = new TooltipBehavior(false); /** * Associates the given {@link Tooltip} with the given {@link Node}. The tooltip @@ -303,8 +315,56 @@ return "font"; } }; + /** + * The duration since tooltips are activated to be shown. + * @since JavaFX 8u40 + */ + public final void setShowDelay(Duration showDelay) { + showDelayProperty.set(showDelay); + } + public final Duration getShowDelay() { + return showDelayProperty.get(); + } + public final ObjectProperty showDelayProperty() { + return showDelayProperty; + } + private final ObjectProperty showDelayProperty + = new SimpleStyleableObjectProperty<>(SHOW_DELAY, this, "showDelay", new Duration(1000)); /** + * The duration since mouse stops moving to hide the tooltip. + * @since JavaFX 8u40 + */ + public final void setShowDurationOnOver(Duration showDelay) { + showDurationOnOverProperty.set(showDelay); + } + public final Duration getShowDurationOnOver() { + return showDurationOnOverProperty.get(); + } + public final ObjectProperty showDurationOnOverProperty() { + return showDurationOnOverProperty; + } + private final ObjectProperty showDurationOnOverProperty + = new SimpleStyleableObjectProperty<>(SHOW_DURATION_ON_OVER, this, "showDurationOnOver", new Duration(5000)); + + /** + * The duration since mouse exits to hide the tooltip. + * @since JavaFX 8u40 + */ + public final void setShowDurationOnExit(Duration showDelay) { + showDurationOnExitProperty.set(showDelay); + } + public final Duration getShowDurationOnExit() { + return showDurationOnExitProperty.get(); + } + public final ObjectProperty showDurationOnExitProperty() { + return showDurationOnExitProperty; + } + private final ObjectProperty showDurationOnExitProperty + = new SimpleStyleableObjectProperty<>(SHOW_DURATION_ON_EXIT, this, "showDurationOnExit", new Duration(200)); + + + /** * An optional icon for the Tooltip. This can be positioned relative to the * text by using the {@link #contentDisplayProperty() content display} * property. @@ -607,6 +667,51 @@ } }; + private static final CssMetaData SHOW_DELAY = + new CssMetaData("-fx-show-delay", + DurationConverter.getInstance(), new Duration(1000)) { + + @Override + public boolean isSettable(Tooltip.CSSBridge cssBridge) { + return !cssBridge.tooltip.showDelayProperty().isBound(); + } + + @Override + public StyleableProperty getStyleableProperty(Tooltip.CSSBridge cssBridge) { + return (StyleableProperty)(WritableValue)cssBridge.tooltip.showDelayProperty(); + } + }; + + private static final CssMetaData SHOW_DURATION_ON_OVER = + new CssMetaData("-fx-show-duration-on-over", + DurationConverter.getInstance(), new Duration(5000)) { + + @Override + public boolean isSettable(Tooltip.CSSBridge cssBridge) { + return !cssBridge.tooltip.showDurationOnOverProperty().isBound(); + } + + @Override + public StyleableProperty getStyleableProperty(Tooltip.CSSBridge cssBridge) { + return (StyleableProperty)(WritableValue)cssBridge.tooltip.showDurationOnOverProperty(); + } + }; + + private static final CssMetaData SHOW_DURATION_ON_EXIT = + new CssMetaData("-fx-show-duration-on-exit", + DurationConverter.getInstance(), new Duration(200)) { + + @Override + public boolean isSettable(Tooltip.CSSBridge cssBridge) { + return !cssBridge.tooltip.showDurationOnExitProperty().isBound(); + } + + @Override + public StyleableProperty getStyleableProperty(Tooltip.CSSBridge cssBridge) { + return (StyleableProperty)(WritableValue)cssBridge.tooltip.showDurationOnExitProperty(); + } + }; + private static final List> STYLEABLES; static { final List> styleables = @@ -618,6 +723,9 @@ styleables.add(GRAPHIC); styleables.add(CONTENT_DISPLAY); styleables.add(GRAPHIC_TEXT_GAP); + styleables.add(SHOW_DELAY); + styleables.add(SHOW_DURATION_ON_OVER); + styleables.add(SHOW_DURATION_ON_EXIT); STYLEABLES = Collections.unmodifiableList(styleables); } @@ -670,11 +778,11 @@ * is activated as soon as a mouse move occurs over the target node. When it * becomes activated, we start off the ACTIVATION_TIMER. If the * ACTIVATION_TIMER expires before another mouse event occurs, then we will - * show the popup. This timer typically lasts about 1 second. + * show the popup. This timer by default lasts about 1 second. * * Once visible, we reset the ACTIVATION_TIMER and start the HIDE_TIMER. * This second timer will allow the tooltip to remain visible for some time - * period (such as 5 seconds). If the mouse hasn't moved, and the HIDE_TIMER + * period (by default 5 seconds). If the mouse hasn't moved, and the HIDE_TIMER * expires, then the tooltip is hidden and the tooltip is no longer * activated. * @@ -682,8 +790,8 @@ * same rules apply as above. * * If a mouse exit event occurs while the HIDE_TIMER is ticking, we reset - * the HIDE_TIMER. Thus, the tooltip disappears after 5 seconds from the - * last mouse move. + * the HIDE_TIMER. Thus, the tooltip disappears, by default, after 5 seconds + * from the last mouse move. * * If some other mouse event occurs while the HIDE_TIMER is running, other * than mouse move or mouse enter/exit (such as a click), then the tooltip @@ -691,7 +799,7 @@ * * If a mouse exit occurs while the HIDE_TIMER is running, we stop the * HIDE_TIMER and start the LEFT_TIMER, and immediately hide the tooltip. - * This timer is very short, maybe about a 1/2 second. If the mouse enters a + * This timer is very short, by default, 200 millis. If the mouse enters a * new node which also has a tooltip before LEFT_TIMER expires, then the * second tooltip is activated and shown immediately (the ACTIVATION_TIMER * having been bypassed), and the HIDE_TIMER is started. If the LEFT_TIMER @@ -730,10 +838,9 @@ private boolean hideOnExit; - TooltipBehavior(Duration openDelay, Duration visibleDuration, Duration closeDelay, final boolean hideOnExit) { + TooltipBehavior(final boolean hideOnExit) { this.hideOnExit = hideOnExit; - activationTimer.getKeyFrames().add(new KeyFrame(openDelay)); activationTimer.setOnFinished(event -> { // Show the currently activated tooltip and start the // HIDE_TIMER. @@ -785,6 +892,7 @@ visibleTooltip = activatedTooltip; hoveredNode = null; + hideTimer.getKeyFrames().setAll(new KeyFrame(activatedTooltip.getShowDurationOnOver())); hideTimer.playFromStart(); } @@ -795,7 +903,6 @@ activatedTooltip = null; }); - hideTimer.getKeyFrames().add(new KeyFrame(visibleDuration)); hideTimer.setOnFinished(event -> { // Hide the currently visible tooltip. assert visibleTooltip != null; @@ -804,7 +911,6 @@ hoveredNode = null; }); - leftTimer.getKeyFrames().add(new KeyFrame(closeDelay)); leftTimer.setOnFinished(event -> { if (!hideOnExit) { // Hide the currently visible tooltip. @@ -860,6 +966,7 @@ t.show(owner, event.getScreenX()+TOOLTIP_XOFFSET, event.getScreenY()+TOOLTIP_YOFFSET); leftTimer.stop(); + hideTimer.getKeyFrames().setAll(new KeyFrame(t.getShowDurationOnOver())); hideTimer.playFromStart(); } else { // Start / restart the timer and make sure the tooltip @@ -867,6 +974,7 @@ t.setActivated(true); activatedTooltip = t; activationTimer.stop(); + activationTimer.getKeyFrames().setAll(new KeyFrame(t.getShowDelay())); activationTimer.playFromStart(); } } @@ -888,8 +996,13 @@ assert visibleTooltip != null; hideTimer.stop(); if (hideOnExit) visibleTooltip.hide(); + Node source = (Node) event.getSource(); + Tooltip t = (Tooltip) source.getProperties().get(TOOLTIP_PROP_KEY); + if (t != null) { + leftTimer.getKeyFrames().setAll(new KeyFrame(t.getShowDurationOnExit())); leftTimer.playFromStart(); } + } hoveredNode = null; activatedTooltip = null; @@ -911,6 +1024,25 @@ visibleTooltip = null; }; + private InvalidationListener OWNER_SCENE_LISTENER = (Observable observable) -> { + final Node owner = (Node)((ReadOnlyObjectProperty)observable).getBean(); + loadCss(owner, (Tooltip)owner.getProperties().get(TOOLTIP_PROP_KEY)); + }; + + private void loadCss(Node node, Tooltip t) { + if(node.getScene()!=null && t!=null){ + loadStylesheetsFromOwner(node.getScene(), t.getScene()); + t.getScene().getRoot().applyCss(); + } + } + + private void loadStylesheetsFromOwner(final Scene ownerScene, final Scene sceneValue) { + if (ownerScene.getUserAgentStylesheet() != null) { + sceneValue.setUserAgentStylesheet(ownerScene.getUserAgentStylesheet()); + } + sceneValue.getStylesheets().setAll(ownerScene.getStylesheets()); + } + private void install(Node node, Tooltip t) { // Install the MOVE_HANDLER, LEAVING_HANDLER, and KILL_HANDLER on // the given node. Stash the tooltip in the node's client properties @@ -921,13 +1053,15 @@ node.addEventHandler(MouseEvent.MOUSE_EXITED, LEAVING_HANDLER); node.addEventHandler(MouseEvent.MOUSE_PRESSED, KILL_HANDLER); node.getProperties().put(TOOLTIP_PROP_KEY, t); + loadCss(node, t); + node.sceneProperty().addListener(OWNER_SCENE_LISTENER); } - private void uninstall(Node node) { if (node == null) return; node.removeEventHandler(MouseEvent.MOUSE_MOVED, MOVE_HANDLER); node.removeEventHandler(MouseEvent.MOUSE_EXITED, LEAVING_HANDLER); node.removeEventHandler(MouseEvent.MOUSE_PRESSED, KILL_HANDLER); + node.sceneProperty().removeListener(OWNER_SCENE_LISTENER); Tooltip t = (Tooltip)node.getProperties().get(TOOLTIP_PROP_KEY); if (t != null) { node.getProperties().remove(TOOLTIP_PROP_KEY); Index: modules/controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css --- modules/controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css +++ modules/controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css @@ -2552,6 +2552,9 @@ -fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */ -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.5) , 10, 0.0 , 0 , 3 ); -fx-font-size: 0.85em; + -fx-show-delay: 1000ms; + -fx-show-duration-on-over: 5000ms; + -fx-show-duration-on-exit: 200ms; } /*******************************************************************************