JavaFX:你能创建一个没有在任务栏上显示并且未修饰的舞台吗?

dej*_*now 12 javafx-8

我正在尝试创建一个没有出现在Windows任务栏上并且未修饰的阶段(没有边框,没有关闭/最小化/最大化按钮).我的最终目标是创建一个托盘图标应用程序,它将弹出通知窗口.

它类似于这个问题,我想要StageStyle.UTILITY的行为(它阻止舞台在任务栏上显示)和StageStyle.TRANSPARENT(这是一个完全未修饰的窗口).

引用的问题对我不起作用,因为我没有用于创建模态窗口的父级.有关如何使其工作的任何想法?谢谢

dej*_*now 12

我能够使用以下代码解决此问题:

    Stage stage = new Stage();

    stage.initStyle(StageStyle.UTILITY);
    stage.setMaxHeight(0);
    stage.setMaxWidth(0);
    stage.setX(Double.MAX_VALUE);
Run Code Online (Sandbox Code Playgroud)

StageStyle.UTILITY将避免创建任务栏图标.我将宽度和高度设置为0使窗口变小,然后使用stage.setX(Double.MAX_VALUE)将其远离屏幕,使其不显示.这有点好玩,但似乎工作正常.


jew*_*sea 9

JavaFX不支持您请求的功能

仅使用核心Java 8类,您无法做出您所要求的(不显示未修饰或透明阶段的任务栏图标).

如果您愿意,请在JavaFX问题跟踪器中为此提交功能请求.

您可以编写一些本机JNI代码,并且可能告诉Windows不要为您的应用程序显示任务栏图标.我不知道你会怎么做.


对任务栏图标的建议

我认为当主应用程序窗口未被隐藏时,在任务栏中显示主应用程序窗口是相当标准的窗口工具包行为,因此我建议不要试图规避该标准行为.

关于通知和托盘图标的建议

这与您的问题标题没有直接关系,只是评论您的任务的最终目标 - 托盘图标的通知.

我看到的大多数基于托盘的应用程序在与托盘图标关联的窗口被隐藏时没有任务栏图标,但在显示与托盘图标关联的窗口时确实有任务栏图标 - 所以我建议您坚持使用那个设置.

此外,通知是系统托盘图标基础结构本身的标准部分,因此我建议您使用系统托盘图标通知的标准机制,而不是使用您自己的.这还将允许用户配置是否使用标准OS托盘图标和通知管理UI显示托盘图标及其通知.

我创建了一个示例应用程序,它使用AWT SystemTray API为JavaFX应用程序提供系统托盘,该托盘使用了本节中的一些建议.如果你愿意,你可以尝试一下.

当实施RT-17503提供系统托盘支持时,将对JavaFX(可能使用Java 9)提供完整的系统托盘支持.


小智 9

这个问题并不是很新鲜,但我遇到了同样的问题并且一开始没有找到解决方案,但这是我的解决方法:)

我找到的最佳解决方案是将primaryStage设置为样式实用程序,并将所有childStages设置为Style Undecorated.然后将primaryStage的不透明度设置为0.0,使其不可见:PrimaryStage:

primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0);
primaryStage.show();
Run Code Online (Sandbox Code Playgroud)

柴尔兹:

this.initOwner(owner);
this.initStyle(StageStyle.UNDECORATED);
Run Code Online (Sandbox Code Playgroud)

示例代码

public void start(Stage primaryStage) throws IOException{
    //make primaryStage utility
    primaryStage.initStyle(StageStyle.UTILITY);
    primaryStage.setOpacity(0);

    Stage secondaryStage = new Stage();
    secondaryStage.initOwner(primaryStage);
    //make secondaryStage transparent
    secondaryStage.initStyle(StageStyle.TRANSPARENT);


    //load ui via FXMLLoader
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/ui.fxml"));
    AnchorPane pane = loader.load();//example with anchor pane

    Scene scene = new Scene(pane,400,400); //example width and height
    scene.setFill(Color.TRANSPARENT); //make scene transparent as well

    secondaryStage.setScene(scene);

    primaryStage.show();
    secondaryStage.show();
}
Run Code Online (Sandbox Code Playgroud)