简体   繁体   English

在工具提示代码中无限触发两个鼠标事件的奇怪行为

[英]Weird behavior of two mouse events being triggered infinitely in tooltip code

I am trying to implement a custom tooltip using the javafx.stage.Popup . 我正在尝试使用javafx.stage.Popup实现自定义工具提示。 The sample demo code is: 示例演示代码是:

public class PopupDemo extends Application {

    private Popup tooltip;
    private final SepiaTone sepiaTone = new SepiaTone();

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

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("PopupDemo");

        Label content = new Label();
        content.setStyle("-fx-background-color:#FCFBBD; -fx-padding: 5; -fx-border-color: #BFBD3B");

        tooltip = new Popup();
        tooltip.getContent().add(content);

        VBox vbox = new VBox(10);
        for (int i = 0; i < 5; i++) {
            final Label lbl = new Label("item " + i);
            lbl.setStyle("-fx-border-color:darkgray; -fx-background-color:lightgray");
            lbl.setMaxSize(80, 60);
            lbl.setMinSize(80, 60);
            lbl.setAlignment(Pos.CENTER);

            lbl.setOnMouseEntered(new EventHandler<MouseEvent>() {

                @Override
                public void handle(final MouseEvent e) {
                    lbl.setEffect(sepiaTone);
                    lbl.setStyle("-fx-cursor: hand");
                    Label content = (Label) tooltip.getContent().get(0);
                    content.setText(lbl.getText());
                    tooltip.show(lbl, e.getScreenX(), e.getScreenY());
                }
            });
            lbl.setOnMouseExited(new EventHandler<MouseEvent>() {

                @Override
                public void handle(MouseEvent e) {
                    lbl.setEffect(null);
                    lbl.setStyle("-fx-cursor: default");
                    tooltip.hide();
                }
            });

            vbox.getChildren().add(lbl);
        }

        StackPane root = new StackPane();
        root.setPadding(new Insets(20));
        root.getChildren().add(vbox);
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }
}

When I move the mouse over the labels the popup shows up and it is working great. 当我将鼠标移到标签上时,弹出窗口显示出来并且效果很好。 But in some cases the two mouse event handlers OnMouseEntered and OnMouseExited are being called continuously one after another. 但在某些情况下,两个鼠标事件处理程序OnMouseEnteredOnMouseExited将一个接一个地连续调用。 One can reproduce this by running provided example, maximising a window and hovering labels continuously. 可以通过运行提供的示例,最大化窗口和连续悬停标签来重现这一点。

Is there a way to avoid this? 有办法避免这种情况吗? I'm using JavaFX 2.0.1. 我正在使用JavaFX 2.0.1。 Thanks. 谢谢。

It's a classic problem: you put mouse at a point, node receives MouseEntered — tooltip appears under the mouse and covers the node triggering MouseExited . 这是一个经典问题:你将鼠标放在一个点上,节点接收MouseEntered - 鼠标下出现工具提示并覆盖触发MouseExited的节点。

To avoid that you can change tooltip.show(lbl, e.getScreenX(), e.getScreenY()) call to 为了避免这种情况,你可以改变tooltip.show(lbl, e.getScreenX(), e.getScreenY())调用

tooltip.show(lbl, e.getScreenX() + 1, e.getScreenY() + 1);

This is not really an answer, so much as pointers to things you might try or investigate further. 这不是一个真正的答案,而是指向您可能尝试或进一步调查的事情的指针。

You could look at the implementation of Tooltip Skin and Behavior to see how it handles some of these cases. 您可以查看Tooltip SkinBehavior的实现,以了解它如何处理这些情况。

The easiest way to implement a custom popup is just to use a Tooltip, style it the way you need using css and use the Tooltip's setGraphic method to add any custom Node content you want. 实现自定义弹出窗口的最简单方法是使用工具提示, 使用css以您需要的方式设置样式,并使用Tooltip的setGraphic方法添加所需的任何自定义节点内容。

If you prefer to use your own implementation, I think you need to keep track of whether the popup has been displayed or not, so you don't try to show it if it is already showing, etc. You may also need invoke the hiding of the popup by having a mouse exit handler installed on the popup itself. 如果您更喜欢使用自己的实现,我认为您需要跟踪弹出窗口是否已显示,因此如果已经显示,则不要尝试显示它等。您可能还需要调用隐藏通过在弹出窗口上安装鼠标退出处理程序来弹出弹出窗口。 You also might want a click to dismiss function for the popup by implementing a mouse click handler on the popup. 您还可能希望通过在弹出窗口上实现鼠标单击处理程序来单击以关闭弹出窗口的功能。 You should also consider whether you should do a straight subclass of Popup or PopupControl , though using Popup as you have is likely more straightforward. 您还应该考虑是否应该执行PopupPopupControl的直接子类,尽管使用Popup可能更直接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM