dejuknow
dejuknow

Reputation: 1591

JavaFX: can you create a stage that doesn't show on the task bar and is undecorated?

I'm trying to create a stage that doesn't appear on the Windows task bar and is undecorated (no borders and no close/minimize/maximize buttons). My end goal is to create a tray icon application that will pop up notification windows.

It's similar to this question where I want the behavior of both StageStyle.UTILITY (which prevents the stage from showing on the task bar) and StageStyle.TRANSPARENT (which is a completely undecorated window).

The referenced question doesn't work for me because I don't have a parent stage from which to make a modal window. Any ideas on how to get this to work? Thanks

Upvotes: 15

Views: 14912

Answers (6)

Mahozad
Mahozad

Reputation: 24472

As far as I know, JavaFX and Swing are interoperable and swing supports this feature. So if you can use Swing, integrate something like this into your application:

class MyFrame extends JFrame {

    // ...    

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

    // ...
}

I haven't tried this but other SO questions like this will probably help you on how to use Swing in JavaFX.

Upvotes: -1

Przemek Krysztofiak
Przemek Krysztofiak

Reputation: 924

Inspired by @Loki solution with a little upgrade (in my opinion)

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

Upvotes: 2

Kanashius
Kanashius

Reputation: 111

This question is not really fresh, but I had the same problem and found no solution at first, but here is my workaround :)

The best solution I found was to set the primaryStage to style Utility and to make all childStages to Style Undecorated. Then set the opacity of the primaryStage to 0.0 so its not visible: PrimaryStage:

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

Childs:

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

Example code

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

Upvotes: 10

jewelsea
jewelsea

Reputation: 159281

JavaFX doesn't support the feature you request

You cannot do what you are asking (not show a task bar icon for an undecorated or transparent stage) using just the core Java 8 classes.

If you wish, file a feature request for this in the JavaFX issue tracker.

You could write some native JNI code and perhaps tell Windows not to display a task bar icon for your application. I do not know how you would do this.


Suggestion on task bar icons

I think it is fairly standard windowing toolkit behaviour to show the main application window in the task bar when the main application window is not hidden, so I suggest not trying to circumvent that standard behaviour.

Suggestion on notifications and tray icons

This isn't directly related to your question title, but is just comment on the end goal of your task - notifications for tray icons.

Most tray based applications I have seen don't have a task bar icon when the window associated with the tray icon is hidden, but do have a task bar icon when the window associated with the tray icon is displayed - so I suggest you stick with that setup.

Also, notifications are a standard part of the system tray icon infrastructure itself, so I suggest you use the standard mechanisms for system tray icon notifications, rather than using your own. This will also allow the user to configure whether the tray icon and it's notifications are shown using the standard OS tray icon and notification management UIs.

I created a sample application which uses the AWT SystemTray API to provide a System tray for a JavaFX application which uses some of the suggestions from this section. You can try it out if you like.

Full system tray support will come to JavaFX (probably with Java 9) when RT-17503 Provide system tray support is implemented.

Upvotes: 10

Michel Moreira
Michel Moreira

Reputation: 9

JavaFX DOES support that.

Don't put the main() method in your Application class. Just create another class to be your main class:

public class FxApplication extends Application {

}

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

Upvotes: 0

dejuknow
dejuknow

Reputation: 1591

I was able to workaround this issue with the following code:

    Stage stage = new Stage();

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

StageStyle.UTILITY will avoid creating a taskbar icon. I set the width and height to 0 make the window small and then use stage.setX(Double.MAX_VALUE) to place it far off screen so it doesn't show up. It's a bit hokey, but it seems to work fine.

Upvotes: 14

Related Questions