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

时间:2014-07-03 22:21:41

标签: javafx-8

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

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

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

6 个答案:

答案 0 :(得分:11)

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

    Stage stage = new Stage();

    stage.initStyle(StageStyle.UTILITY);
    stage.setMaxHeight(0);
    stage.setMaxWidth(0);
    stage.setX(Double.MAX_VALUE);

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

答案 1 :(得分:7)

JavaFX不支持您请求的功能

只使用核心Java 8类,你无法做你想要的(没有显示未修饰或透明的舞台的任务栏图标)。

如果您愿意,请在JavaFX issue tracker

中提交功能请求

您可以编写一些本地JNI code,也许告诉Windows不要为您的应用程序显示任务栏图标。我不知道你会怎么做。


对任务栏图标的建议

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

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

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

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

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

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

在实施RT-17503 Provide system tray support时,JavaFX(可能使用Java 9)将支持完整的系统托盘支持。

答案 2 :(得分:6)

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

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

<special-link>link</special-link>

童车:

primaryStage.initStyle(StageStyle.UTILITY);
primaryStage.setOpacity(0);
primaryStage.show();

示例代码

this.initOwner(owner);
this.initStyle(StageStyle.UNDECORATED);

答案 3 :(得分:0)

JavaFX支持这一点。

不要将main()方法放在Application类中。只需创建另一个类作为您的主类:

public class FxApplication extends Application {

}

public class Main {
  public static void main(String[] args) {
    PlatformImpl.setTaskbarApplication(false);
    Application.launch(FxApplication.class, args);
  }
}

答案 4 :(得分:0)

受@Loki解决方案的启发,并进行了一些升级(我认为)

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class TransparentAndUtilityStageApp extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.initStyle(StageStyle.UTILITY);
        primaryStage.setOpacity(0.);
        primaryStage.show();

        Stage stage = new Stage();
        Label label = new Label("Rainmeter");
        StackPane stackPane = new StackPane(label);
        stackPane.setPrefSize(600, 400);
        stackPane.setStyle("-fx-background-color: transparent;");

        Scene scene = new Scene(stackPane);
        scene.setFill(null);

        stage.initOwner(primaryStage);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setScene(scene);
        stage.show();
    }
}

答案 5 :(得分:0)

据我所知,JavaFX和Swing是可互操作的,并且swing支持此功能。因此,如果可以使用Swing,请将类似的内容集成到您的应用程序中:

class MyFrame extends JFrame {

    // ...    

    MyFrame() {
        setUndecorated(true);
        setType(Type.UTILITY);
    }

    // ...
}

我还没有尝试过,但是其他类似this这样的问题可能会帮助您如何在JavaFX中使用Swing。