JavaFX: можете ли вы создать сцену, которая не отображается на панели задач и не декорирована?

Я пытаюсь создать сцену, которая не отображается на панели задач Windows и не декорирована (без границ и кнопок закрытия/минимизации/максимизации). Моя конечная цель - создать приложение значка в трее, которое откроет окна уведомлений.

Он похож на question, где мне нужно поведение как StageStyle.UTILITY(что препятствует показу сцены на панели задач), так и StageStyle.TRANSPARENT(который является полностью неразделенным окном).

Связанный вопрос не работает для меня, потому что у меня нет родительского этапа, из которого можно создать модальное окно. Любые идеи о том, как заставить это работать? Благодаря

Ответ 1

Мне удалось решить эту проблему со следующим кодом:

    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), чтобы поместить его далеко за пределы экрана, чтобы он не отображался. Это немного hokey, но, похоже, он работает нормально.

Ответ 2

JavaFX не поддерживает функцию, которую вы запрашиваете

Вы не можете делать то, что вы спрашиваете (не показывать значок панели задач для недекорированного или прозрачного этапа), используя только основные классы Java 8.

Если вы хотите, напишите запрос функции для этого в отслеживании ошибок JavaFX.

Вы можете написать некоторый собственный код JNI и, возможно, сообщить Windows, чтобы не отображать значок панели задач для вашего приложения. Я не знаю, как вы это сделаете.


Предложение по значкам панели задач

Я думаю, что это стандартное поведение инструментария окон, чтобы показать основное окно приложения на панели задач, когда главное окно приложения не скрыто, поэтому я предлагаю не пытаться обойти это стандартное поведение.

Предложение по уведомлениям и значкам лотков

Это напрямую не связано с вашим типом вопроса, а просто комментирует конечную цель вашей задачи - уведомления для значков в трее.

В большинстве приложений на лотке, которые я видел, нет значка панели задач, когда окно, связанное с значком в трее, скрыто, но есть значок панели задач, когда отображается окно, связанное с значком в трее, - поэтому я предлагаю вы придерживаетесь этой настройки.

Кроме того, уведомления являются стандартной частью самой инфраструктуры значков в системном трее, поэтому я предлагаю вам использовать стандартные механизмы уведомлений значков в системном трее, а не использовать свои собственные. Это также позволит пользователю настроить отображение значка в трее и его уведомлений с помощью стандартного значка панели задач ОС и интерфейса управления уведомлением.

Я создал приложение примера которое использует AWT SystemTray API для предоставления системного лотка для приложения JavaFX, в котором используются некоторые из предложений этого раздел. Вы можете попробовать, если хотите.

Поддержка полного системного лотка придет в JavaFX (возможно, с Java 9), когда RT-17503 Обеспечивает поддержку системных лотков.

Ответ 3

Этот вопрос не совсем свежий, но у меня была такая же проблема и сначала не было найдено решения, но вот мой способ:)

Лучшее решение, которое я нашел, это установить утилиту primaryStage для стилей и сделать все дочерние элементы Style Undecorated. Затем установите непрозрачность первичного напряжения равным 0.0, чтобы его не было видно: PrimaryStage:

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

Чайлдс:

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

Пример кода

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

Ответ 4

JavaFX поддерживает это.

Не помещайте метод main() в свой класс приложения. Просто создайте еще один класс для вашего основного класса:

public class FxApplication extends Application {

}

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

Ответ 5

Вдохновленный решением @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();
    }
}