Странное поведение двух событий мыши, вызываемых бесконечно в коде всплывающей подсказки - PullRequest
5 голосов
/ 07 февраля 2012

Я пытаюсь реализовать пользовательскую подсказку, используя javafx.stage.Popup.Пример демонстрационного кода:

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

Когда я перемещаю мышь над ярлыками, появляется всплывающее окно, и оно отлично работает.Но в некоторых случаях два обработчика событий мыши OnMouseEntered и OnMouseExited вызываются непрерывно один за другим.Это можно воспроизвести, запустив приведенный пример, развернув окно до максимума и постоянно нависая надписи.

Есть ли способ избежать этого?Я использую JavaFX 2.0.1.Спасибо.

Ответы [ 2 ]

7 голосов
/ 08 февраля 2012

Это классическая проблема: вы помещаете мышь в точку, узел получает MouseEntered - под мышкой появляется всплывающая подсказка, которая закрывает узел, вызывающий MouseExited.

Чтобы избежать этого, вы можете изменить tooltip.show(lbl, e.getScreenX(), e.getScreenY()) call на

tooltip.show(lbl, e.getScreenX() + 1, e.getScreenY() + 1);
1 голос
/ 08 февраля 2012

Это на самом деле не ответ, а скорее указатели на то, что вы можете попробовать или исследовать дальше.

Вы можете взглянуть на реализацию Tooltip Скин и Поведение , чтобы увидеть, как оно обрабатывает некоторые из этих случаев.

Самый простой способ реализовать собственное всплывающее окно - просто использовать подсказку, стилизовать ее так, как вам нужно , используя css ииспользуйте метод setGraphic всплывающей подсказки , чтобы добавить любой пользовательский контент Node, который вы хотите.

Если вы предпочитаете использовать собственную реализацию, я думаю, вам нужно отслеживать, отображалось ли всплывающее окно илинет, поэтому вы не пытаетесь показать его, если он уже отображается и т. д. Вам также может понадобиться вызвать скрытие всплывающего окна, установив обработчик выхода мыши в самом всплывающем окне.Вы также можете захотеть отключить функцию щелчка для всплывающего окна, реализовав обработчик щелчка мыши во всплывающем окне.Вам также следует подумать о том, следует ли вам использовать прямой подкласс Popup или PopupControl , хотя использование Popup, как и у вас, вероятно, более просто.

...