JavaFX : Mouse events for a PopOver Window (ControlsFX)

你说的曾经没有我的故事 提交于 2020-03-23 07:56:17

问题


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.


回答1:


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.




回答2:


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);
    }
}


来源:https://stackoverflow.com/questions/57850154/javafx-mouse-events-for-a-popover-window-controlsfx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!