1

I am having the following code to display a PopOver (Custom PopUp by ControlsFX - mvn repo)

public class JavaFXApplication35 extends Application {

    @Override
    public void start(Stage primaryStage) {
        try {

            Label lblName = new Label("Tetsing name");
            Label lblStreet = new Label("Some street name");
            Label lblCityStateZip = new Label("Some city, 111111");
            VBox vBox = new VBox(lblName, lblStreet, lblCityStateZip);

            PopOver popOver = new PopOver(vBox);

            Label label = new Label("Mouse mouse over me");

            label.setOnMouseEntered(mouseEvent -> {
                popOver.show(label, -3);
            });

            label.setOnMouseExited(mouseEvent -> {
                if (popOver.isShowing()) {
                    popOver.hide();
                }
            });

            StackPane root = new StackPane();
            root.getChildren().add(label);

            Scene scene = new Scene(root, 300, 250);

            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.setOnCloseRequest((WindowEvent event) -> {
                System.exit(0);
            });
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

The problem is ,

  1. I want the pop-up to be displayed when mouse entered the Label - works fine.

  2. I want the pop-up to be hidden when user exits mouse from Label but not if he enters mouse in to the pop-up window.

I have added MouseEntered and MouseExited actions on Label but how can i handle the another scenario where i don't want to hide the pop-up if user enters mouse in to pop-up.

user3164187
  • 1,382
  • 3
  • 19
  • 50
  • Have the same issue using [`ControlsFX 11`](https://controlsfx.bitbucket.io/org/controlsfx/control/PopOver.html). I am guessing it's a bug. It does not make sense to have a Calendar in a `PopOver` and not be able to interact with it. – SedJ601 Sep 09 '19 at 14:06
  • @Sedrick Without ControlsFX : if i just want to show a normal Pane on MouseEnter and hide it on MouseExit over a label, but not if i enter the mouse in to the Pane - how can that be done ? – user3164187 Sep 10 '19 at 03:44

2 Answers2

2

I ran into the same problem. Here is my solution. Just pass your label (or other node) and PopOver's content node as arguments to this method.

public static void addAutoHidingPopOver(Node hoverableNode, Node contentNode) {
   //Creating PopOver
   PopOver popOver = new PopOver(hoverableNode);
   popOver.setContentNode(contentNode);
   //Here you can set custom parameters of your PopOver
   //...

   //Mouse Actions handling
   final Timeline timeline = new Timeline();
   timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1000)));
   timeline.setOnFinished(finishEvent -> {
        if (hoverableNode.isHover() || contentNode.isHover()) timeline.play();
        else popOver.hide();
   });
   hoverableNode.setOnMouseEntered(mouseEvent -> {if (!popOver.isShowing()) popOver.show(hoverableNode);});
   hoverableNode.setOnMouseExited(mouseEvent -> timeline.play());
}

PopOver will be hidden after 1 sec after mouse leave hoverableNode or contentNode. Use it like this:

addAutoHidingPopOver(someLabel, someContentNode);

Note, that your content node should take all visible space of PopOver for comfort use.

  • Works nicely, thank you. Only thing I would add is popOver.setDetachable(false) so that the popup can't be detached - otherwise it would disappear anyway once the mouse goes out of the anchor node. Or....handle the detached state of the popover to make it not disappeared when it's detached. – Alessandro Roaro Nov 26 '19 at 11:10
0

That could be expected behavior. I am not sure, but here is a workaround. You can use a ToggleButton.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ToggleButton;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.controlsfx.control.PopOver;

public class App extends Application
{

    @Override
    public void start(Stage primaryStage)
    {
        //Build PopOver look and feel
        Label lblName = new Label("John Doe");
        Label lblStreet = new Label("123 Hello Street");
        Button lblCityStateZip = new Button("MadeUpCity, XX 55555");
        VBox vBox = new VBox(lblName, lblStreet, lblCityStateZip);
        //Create PopOver and add look and feel
        PopOver popOver = new PopOver(vBox);

        ToggleButton toggleButton = new ToggleButton("Click me!");
        toggleButton.selectedProperty().addListener((obs, oldValue, newValue) -> {
            if (newValue) {
                popOver.show(toggleButton);
            }
            else {
                popOver.hide();
            }
        });
        ;

        StackPane root = new StackPane();
        root.getChildren().add(toggleButton);
        var scene = new Scene(root, 500, 500);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args)
    {
        launch(args);
    }
}
SedJ601
  • 12,173
  • 3
  • 41
  • 59