Javafx Custom Tooltip Implementation Only Shows on Last Node Installed
Javafx Custom Tooltip Implementation Only Shows on Last Node Installed
I'm trying to create my own Tooltip implementation, that has an arrow and shows the tooltip on a certain side of the node it's installed on.
It looks like this:
Here's what i've coded so far
Tooltip.java
public class Tooltip extends PopupControl
private StringProperty message = new SimpleStringProperty();
private final static TooltipSkin skin = new TooltipSkin();
private final static TooltipBehavior behavior = new TooltipBehavior();
public Tooltip(Node node, String message)
this.message.setValue(message);
if (getContent() != skin.createSkin())
getContent().setAll(skin.createSkin());
behavior.install(node, Tooltip.this);
/****************************************************************
********** ACCESSORS ************
****************************************************************/
String getMessage()
return message.get();
StringProperty messageProperty()
return message;
private static class TooltipBehavior
final String TOOLTIP_PROP_KEY = "fxtooltip";
private void install(Node node, Tooltip tooltip)
if (node == null)
return;
node.addEventHandler(MouseEvent.MOUSE_ENTERED, ENTERED_HANDLER);
node.addEventHandler(MouseEvent.MOUSE_EXITED, KILL_HANDLER);
node.addEventHandler(MouseEvent.MOUSE_PRESSED, KILL_HANDLER);
node.getProperties().put(TOOLTIP_PROP_KEY, tooltip);
private EventHandler<MouseEvent> ENTERED_HANDLER = (MouseEvent event) ->
Node hoveredNode = (Node) event.getSource();
Tooltip tooltip = ((Tooltip) hoveredNode.getProperties().get(TOOLTIP_PROP_KEY));
String message = tooltip.getMessage();
skin.setMessage(message);
tooltip.show(getWindow(hoveredNode), 0, 0);
;
private EventHandler<MouseEvent> KILL_HANDLER = (MouseEvent event) ->
Node hoveredNode = (Node) event.getSource();
Tooltip tooltip = ((Tooltip) hoveredNode.getProperties().get(TOOLTIP_PROP_KEY));
tooltip.hide();
;
private Window getWindow(final Node node)
final Scene scene = node == null ? null : node.getScene();
return scene == null ? null : scene.getWindow();
private static class TooltipSkin
private static HBox $RootView = new HBox();
private static StackPane $PaneMessageBody = new StackPane();
private static StackPane $PaneArrow = new StackPane();
private static Text $TextMessage = new Text();
private static boolean skinInitialized = false;
Pane createSkin()
if (skinInitialized)
return $RootView;
else
skinInitialized = true;
$RootView.getChildren().addAll($PaneMessageBody, $PaneArrow);
$PaneMessageBody.getChildren().addAll($TextMessage);
return $RootView;
void setMessage(String message)
$TextMessage.setText(message);
In my controller, I have some buttons i added tooltips to this way
new Tooltip($BtnDownload, "Download");
new Tooltip($BtnActivate, "Activate");
However, this only works on the last node a tooltip is installed on, If i hover over other nodes that have a tooltip, cursor starts flickering, and the tooltip doesn't show at all. What could the issue be here?
Thanks, Should i include trivials. like creating an app class, a controller and a view? If not, what do you see i can add here?
– Rafat Rifaie
Sep 6 '18 at 3:20
It's not really what you can add; as it stands, your post contains a lot of code that most people don't really want to read through. The purpose of a mcve is to make your question shorter, so that people can spend less time reading code and more time coming up with a solution.
– ricky3350
Sep 6 '18 at 3:24
Two things: 1). You've tagged your post [javafx-8] and [javafx-2]. I assume you're not using both, so please remove the tag of the version you are not using. 2). For the nodes where the cursor starts flickering, check to see whether or not your
KILL_HANDLER
is called immediately after the MOVE_HANDLER
. It is possible that the tooltip is appearing on top of the node, causing the mouse to "move out" of the node.– ricky3350
Sep 6 '18 at 3:40
KILL_HANDLER
MOVE_HANDLER
"Should i include trivials. like creating an app class, a controller and a view?" Yes, it's the C in MCVE. If we can't copy-paste and run it (and see the problem), it's not a MCVE.
– user1803551
Sep 6 '18 at 5:33
0
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Suggestion: to help others answer your questions better, consider creating a mcve to demonstrate your problem in a shorter format.
– ricky3350
Sep 6 '18 at 3:17