You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中ControlsFX PopOver鼠标事件问题:移入弹窗时不隐藏

解决ControlsFX PopOver在鼠标从Label移到弹窗时不隐藏的问题

我明白你的需求——现在鼠标移出Label就直接隐藏PopOver,但当鼠标从Label滑到PopOver弹窗上时,你希望弹窗保持显示。这个问题的核心是我们需要区分「鼠标完全离开Label区域且没进入PopOver」和「鼠标从Label移到PopOver」这两种情况,下面给你一个实用的解决方案:

我们可以通过延迟隐藏+PopOver鼠标监听的组合来实现需求,具体逻辑是:给Label的移出事件添加短暂延迟,在这段时间内如果鼠标进入了PopOver,就取消隐藏操作;如果没进入,再执行隐藏。

修改后的完整代码

public class JavaFXApplication35 extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Label lblName = new Label("Testing 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);
            
            // 创建延迟隐藏任务,200毫秒延迟可根据体验调整
            PauseTransition hideDelay = new PauseTransition(Duration.millis(200));
            hideDelay.setOnFinished(event -> {
                if (popOver.isShowing()) {
                    popOver.hide();
                }
            });
            
            // 鼠标进入PopOver时,取消延迟隐藏任务
            popOver.setOnMouseEntered(mouseEvent -> {
                hideDelay.stop();
            });
            
            // 鼠标离开PopOver时,启动延迟隐藏
            popOver.setOnMouseExited(mouseEvent -> {
                hideDelay.playFromStart();
            });
            
            Label label = new Label("Mouse over me");
            label.setOnMouseEntered(mouseEvent -> {
                // 显示弹窗前先停止可能正在运行的延迟任务
                hideDelay.stop();
                popOver.show(label, -3);
            });
            
            label.setOnMouseExited(mouseEvent -> {
                // 启动延迟隐藏,给鼠标足够时间移到PopOver上
                hideDelay.playFromStart();
            });
            
            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();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

方案原理说明

  1. 延迟隐藏机制:当鼠标离开Label时,不是立刻隐藏弹窗,而是启动一个200毫秒的延迟任务,这段时间足够用户把鼠标从Label滑到PopOver上。
  2. PopOver监听补全:给PopOver添加鼠标进入/离开事件,当鼠标进入弹窗时,立刻停止延迟隐藏任务,确保弹窗保持显示;当鼠标离开弹窗时,再启动延迟隐藏,保证鼠标完全离开弹窗区域后才关闭。
  3. 边界处理:在显示弹窗前停止延迟任务,避免之前的延迟任务干扰新的弹窗显示逻辑。

内容的提问来源于stack exchange,提问作者user3164187

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:36:44