0

I'm trying to create my own Tooltip class. Basically the tooltip is going to be a Label with a pointer graphic(FontAwesomeView) on the bottom all wrapped inside a vbox.

The part i'm stuck at is, how do i show my custom tooltip on the screen without adding it to a parent node?

DarkMental
  • 482
  • 7
  • 26
  • You sort of have to add it to a parent node in order to get it to show up in your Scene at all. However, that parent node can be completely transparent. For example, you could have the root of your current Scene on one layer of a StackPane and add your VBox to an above layer, positioning it dependent on where the mouse is. – MMAdams Jan 09 '18 at 17:52
  • @MMAdams My issue with that is, with that, i have to add my custom tooltip to every fxml/nested-fxml that has a control that uses the tooltip. – DarkMental Jan 09 '18 at 17:56
  • 1
    If all you have is a Label with a Graphic, why not just use JavaFX Tooltips? You can set text and Graphics, and even style them with CSS. – MMAdams Jan 09 '18 at 17:59
  • I couldn't figure out how to make the graphic be anchored at the bottom center of the tooltip. [This](https://css-tricks.com/wp-content/uploads/2011/11/tooltip-scematics.jpg) is what i'm trying to achieve. – DarkMental Jan 09 '18 at 18:03
  • 1
    I see. Maybe try having your Custom Tooltip class extend PopupControl (https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/PopupControl.html), which is how the built in Tooltips and ContextMenus work. A PopupControl is a kind of undecorated window, so you can display it without adding it to your current scene. – MMAdams Jan 09 '18 at 18:07
  • Oh, i see now. Thanks i'll try to do that and dig deeper into the Tooltip class – DarkMental Jan 09 '18 at 18:12
  • Pretty sure you should be able to do this with a standard tooltip, setting the graphic, and using some CSS. You can set the shape of an arbitrary [`Region`](https://docs.oracle.com/javase/9/docs/api/javafx/scene/layout/Region.html#shapeProperty). – James_D Jan 09 '18 at 18:14
  • @James_D So the background of the tooltip (the text container) is a Region? – DarkMental Jan 09 '18 at 18:20
  • 1
    I'm not sure what is used as the root of the popup window (tooltip). No time to test now but try styling the tooltip with CSS and specifying a shape. – James_D Jan 09 '18 at 18:26
  • I'll try to do that. **CSS doesn't work** at all for me when using the install method on nodes that **don't** have a tooltip property. It always loads the default Modena style. But it works fine when i set the style using the **setStyle** method. So i'll try with that. – DarkMental Jan 09 '18 at 18:30

1 Answers1

7

You don't need to implement your own tooltip, you can just customize the built-in one.

Default tooltip:

hello sample default

Customized tooltip:

hello sample

It also works for installing Tooltips on nodes (like shapes) which don't have a setTooltip method:

circular

Sample code for customized tooltip:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.PopupWindow;
import javafx.stage.Stage;

public class BubbleTip extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    private static final String SQUARE_BUBBLE =
            "M24 1h-24v16.981h4v5.019l7-5.019h13z";

    @Override
    public void start(Stage stage) {
        Label label = new Label("hello,");
        label.setStyle("-fx-font-size: 16px;");

        label.setTooltip(makeBubble(new Tooltip(" world")));

        Circle circle = new Circle(20, Color.AQUA);
        Tooltip.install(circle, makeBubble(new Tooltip("circle")));

        VBox layout = new VBox(10, label, circle);
        layout.setPadding(new Insets(20));

        stage.setScene(new Scene(layout));
        stage.show();
    }

    private Tooltip makeBubble(Tooltip tooltip) {
        tooltip.setStyle("-fx-font-size: 16px; -fx-shape: \"" + SQUARE_BUBBLE + "\";");
        tooltip.setAnchorLocation(PopupWindow.AnchorLocation.WINDOW_BOTTOM_LEFT);

        return tooltip;
    }
}

This answer is based on the answer to:

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • I've been playing around with CSS all night yesterday, trying to get it to work. This works thanks! – DarkMental Jan 10 '18 at 14:20
  • I wish there was a way though, to separate the pointer from the bubble. As now the text is not vertically centered correctly, so i have to play with margins to get it right, which would work if the text of bubble is only one line for all popups, which is not the case. – DarkMental Jan 10 '18 at 14:31