In JavaFX, how to open another stage without losing focus of the first?

I have a main stage, which should open another stage, without losing the focus of the first. I know that I can call mainWindow.requestFocus() after calling secondWindow.show() , but I want to make it work without the first window, even losing focus.

I want to do this because the second stage is the notification window with StageStyle.TRANSPARENT, which always stays on top and closes after a few seconds. Is there a way to make the second window β€œunmanaged”?

+6
source share
3 answers

Do you really need to create a new Stage to display your notification window? You can also use javafx.stage.Popup , which by default creates transparent windows (so you do not need to set StageStyle.TRANSPARENT ). Another advantage of using Popup instead of Stage is that it does not β€œsteal” focus from your main stage, which should be pretty much what you need.

Here's more info on the popup class: https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Popup.html

And here is a simple example of using a popup in your application: https://gist.github.com/jewelsea/1926196

+3
source

Well, I managed to do this by embedding my java fx stage inside the swinging JFrame. On JFrame, I can do what I want. here's how:

 JFrame frame = new JFrame(); frame.setUndecorated(true); frame.setBackground(new java.awt.Color(0, 0, 0, 0)); final JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setSize(422, 116); frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); fxPanel.setScene(scene); frame.setResizable(false); frame.setAlwaysOnTop(true); frame.setFocusableWindowState(false); // <- Here is the secret frame.setVisible(true); 

If anyone knows a less dirty way to do this, I would appreciate it.

+1
source

For this you need some parameters. There is a method called stage.setOnShown() that will be called immediately after opening a new stage.

But remember the code below, it will open the second stage without any opportunity to close it, so you need to kill the application. This can be improved with a timer where windows will automatically close.

 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.StageStyle; public class TwoStage extends Application { @Override public void start(Stage primaryStage) { Button btn = new Button(); btn.setText("Open second stage"); btn.setOnAction((e) -> { Label l = new Label("I'm a second window"); Scene s = new Scene(l, 100, 100); Stage s1 = new Stage(StageStyle.TRANSPARENT); s1.centerOnScreen(); s1.setScene(s); s1.initModality(Modality.NONE); s1.setAlwaysOnTop(true); s1.setOnShown((e1) -> { primaryStage.requestFocus(); }); s1.show(); }); StackPane root = new StackPane(); root.getChildren().add(btn); Scene scene = new Scene(root, 300, 250); primaryStage.setTitle("Two Windows"); primaryStage.setScene(scene); primaryStage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 
0
source

All Articles