如何创建鼠标透明的通知弹出窗口?

时间:2016-02-09 05:56:30

标签: javafx

任务

我想创建一个通知窗口,该窗口对于舞台和桌面是透明的鼠标。

问题

弹出窗口没有鼠标透明功能。当弹出窗口显示时,您必须等到它消失才能访问其背后的内容。

问题

是否可以创建具有点击机制的通知弹出窗口(或其他窗口)?它应该适用于舞台上的弹出窗口和桌面弹出窗口。

代码

以下是单击按钮时创建通知的示例代码。弹出窗口在3秒后消失。之后,您可以再次单击该按钮。

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Notification extends Application {

    static double width = 800;
    static double height = 600;
    static int counter = 0;

    Stage stage;

    @Override
    public void start(Stage stage) {

        this.stage = stage;

        // content area
        StackPane root = new StackPane();
        root.setStyle("-fx-background-color:white");

        // button which shows a popup
        Button notificationButton = new Button("Add Popup");
        notificationButton.setOnAction(e -> {
            addNotification("This is notification nr. " + (++counter));
        });

        root.getChildren().add(notificationButton);

        Scene scene = new Scene(root, width, height);

        stage.setScene(scene);
        stage.show();

    }

    private void addNotification(String message) {

        // create popup content
        Label messageLabel = new Label(message);

        final StackPane content = new StackPane();
        content.setPrefSize(200, 200);
        content.setStyle("-fx-background-color:lightgrey");
        content.setOpacity(0.5);
        content.setMouseTransparent(true);

        content.getChildren().addAll(messageLabel);

        // create popup and show it
        final Popup popup = new Popup();
        popup.setX(stage.getX() + (stage.getScene().getWidth() - 200) / 2);
        popup.setY(stage.getY() + (stage.getScene().getHeight() - 200) / 2);
        popup.getContent().add(content);

        popup.show(stage.getScene().getWindow());

        // hide popup after 3 seconds
        Duration displayDuration = Duration.millis(3000);
        KeyFrame displayDurationKeyFrame = new KeyFrame(displayDuration);

        Timeline timeline = new Timeline(displayDurationKeyFrame);
        timeline.setOnFinished(e -> {
            popup.hide();
        });
        timeline.play();

    }

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

}

1 个答案:

答案 0 :(得分:0)

试试这个。我已经删除了initModality(),因为这是阻止输入事件传递到另一个窗口的原因。我还添加了监听器,以防止新舞台获得焦点。

final Stage popup = new Stage();
popup.setX(stage.getX() + (stage.getScene().getWidth() - 200) / 2);
popup.setY(stage.getY() + (stage.getScene().getHeight() - 200) / 2);
popup.setScene(new Scene(content));
popup.initOwner(stage);
popup.focusedProperty().addListener(new ChangeListener<Boolean>() {
    @Override
    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
        stage.requestFocus();
    }
});
popup.initStyle(StageStyle.TRANSPARENT);
popup.setOpacity(0.5);
popup.show();