【问题标题】:Sending notification with javafx without stage使用 javafx 无阶段发送通知
【发布时间】:2014-11-11 21:53:24
【问题描述】:

您可以像这样使用 JavaFx 发送桌面通知(需要 jdk 8u20 或更高版本):

package sample;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import org.controlsfx.control.Notifications;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
//        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        Button notifyButton = new Button("Notify");
        notifyButton.setOnAction(e -> {
            Notifications.create().title("Test").text("Test Notification!").showInformation();
        });
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(notifyButton, 100, 50));
        primaryStage.show();
    }


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

但是这样你必须创建一个主窗口(舞台),是否可以避免这种情况?我正在寻找一种发送通知的方法,例如在 bash 中使用 zenity:大部分代码都是非 gui,但使用一些 gui 元素以非常基本的方式通知用户或与用户交互。

【问题讨论】:

  • 你的问题对我来说没有多大意义。舞台只是一个窗口。您无法在没有窗口的桌面窗口系统中显示任何类型的 UI。在这些zenity screenshots 中,所有的对话框都是窗口。您不需要第三方的 controlsfx 库来显示 UI 对话框(尽管它可能会有所帮助)。您只需 init the primary stage style 并填充舞台以显示对话框。
  • 有了 zenity,你可以做任何你想做的事情,甚至不需要触摸 gui(在 bash 中),并且只在必要时弹出窗口。使用 Javafx,对我来说如何接收命令行参数并不明显。问题是你不能在 main() 中做很多事情,除了 launch(args)。
  • 请参阅Application::getParameters,了解 JavaFX 应用程序中的命令行参数检索。请参阅Platform::setImplicitExit 以在未显示任何窗口时在后台运行 JavaFX 应用程序。请参阅stage::show, stage::hide and stage::showAndWait,了解按需显示和隐藏阶段的不同方式。

标签: java user-interface javafx notifications


【解决方案1】:

看起来 ControlsFX 通知需要现有阶段。您可以创建一个隐藏的实用程序阶段。试试这样的。

package sample;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.controlsfx.control.Notifications;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
    }


    public static void main(String[] args) {
        new JFXPanel();
        notifier("Good!", "It's working now!");
    }

    private static void notifier(String pTitle, String pMessage) {
        Platform.runLater(() -> {
                    Stage owner = new Stage(StageStyle.TRANSPARENT);
                    StackPane root = new StackPane();
                    root.setStyle("-fx-background-color: TRANSPARENT");
                    Scene scene = new Scene(root, 1, 1);
                    scene.setFill(Color.TRANSPARENT);
                    owner.setScene(scene);
                    owner.setWidth(1);
                    owner.setHeight(1);
                    owner.toBack();
                    owner.show();
                    Notifications.create().title(pTitle).text(pMessage).showInformation();
                }
        );
    }
}

new JFXPanel() 初始化 JavaFX 线程,而无需扩展 Application。你必须在调用Platform.runLater() 之前调用它,否则你会得到一个线程异常。不过,您只需要为整个应用程序调用一次。老实说,创建​​自己的通知阶段并直接显示它可能会更好。像上面一样创建一个舞台并放置您自己的内容。您可能可以重用 ControlsFX 源代码中的一些样式。

【讨论】:

  • 我收到了这个错误:java.lang.NullPointerException: Owner window must not be null,代码在这里:ideone.com/WTi0Ka
  • 看起来这是 ControlsFX 的一个已知问题。 bitbucket.org/controlsfx/controlsfx/issue/200/… 他们决定不修复它。解决方法是创建一个透明舞台或将舞台放置在屏幕外的 x-y 位置。
  • runLater,应该有一个结束的}。
  • 还有一个 ;不见了。但除了这些错别字之外,一切都确实有效。非常感谢。
  • 希望您不介意我稍微修改一下您的答案?我将在这里发布完整的 java 文件。
猜你喜欢
  • 1970-01-01
  • 2018-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多