Search code examples
javawindowsjavafxfullscreentaskbar

JavaFX changing Scenes on fullscreen mode


I have problem with JavaFX. I created two scenes and switch button. When I click that button I'm changing scene. But earlier i set fullscreen on true and after I pressed the button, windows taskbar shows for a moment. Is there any way to change scenes without having this taskbar visible? There is the code:
----Main class----

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws InterruptedException, IOException {
        DesktopApplication.launch(DesktopApplication.class);
    }
}

----DesktopApplication class----

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class DesktopApplication extends Application implements Runnable {

Scene firstScene;
Scene secondScene;
Scene scene;
public static Stage primaryStagePublic;

public DesktopApplication() {
}

@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Title");
    primaryStage.initStyle(StageStyle.TRANSPARENT);
    primaryStage.initStyle(StageStyle.UNDECORATED);

    int width = (int) Screen.getPrimary().getBounds().getWidth();
    int height = (int) Screen.getPrimary().getBounds().getHeight();

    HBox mainLayout = new HBox();
    mainLayout.getChildren().add(new Text("hello!"));
    MyLayout myLayout = new MyLayout(this);

    firstScene = new Scene(myLayout,width,height);
    secondScene = new Scene(mainLayout, width, height);

    scene = firstScene;

    primaryStage.setScene(scene);
    primaryStage.setFullScreen(true);
    primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
    primaryStage.show();

    primaryStagePublic = primaryStage;

}

@Override
public void run() {
    Thread thread = new Thread() {
        public void run() {
            launch(DesktopApplication.class);
        }
    };

    thread.start();

    while (true) {

    }
}

public void swapScenes(Stage primaryStage){
    primaryStage.setScene(secondScene);
    primaryStage.setFullScreen(true);
    primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
}
}

----MyLayout class----

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
public class MyLayout extends HBox{

private DesktopApplication desktopApplication;

public MyLayout(DesktopApplication desktopApplication) {
    this.desktopApplication = desktopApplication;
    init();
}

private void init(){

    this.setStyle("-fx-background-color: #f8ff7d;");
    Label text = new Label("testing");
    Button button = new Button("Button");
    button.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            desktopApplication.swapScenes(DesktopApplication.primaryStagePublic);
        }
    });
    this.getChildren().addAll(text, button);
}
}

Solution

  • I had a similar issue and solved it like @James_D suggested: Do not replace the scene as a whole, but only the root element:

    public void swapScenes(Parent newContent){
        stage.getScene().setRoot(newContent);
    }
    

    This requires changing the rest of the initialisation code a bit:

    public class DesktopApplication extends Application implements Runnable {
    
        Parent myLayout;
        Parent mainLayout;
        Scene scene;
        public static Stage stage; // if possible make this private and non static
    
        public DesktopApplication() {
        }
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            primaryStage.setTitle("Title");
            primaryStage.initStyle(StageStyle.TRANSPARENT);
            primaryStage.initStyle(StageStyle.UNDECORATED);
    
            int width = (int) Screen.getPrimary().getBounds().getWidth();
            int height = (int) Screen.getPrimary().getBounds().getHeight();
    
            mainLayout = new HBox();
            mainLayout.getChildren().add(new Text("hello!"));
            myLayout = new MyLayout(this);
    
            scene = new Scene(myLayout,width,height);
    
            primaryStage.setScene(scene);
            primaryStage.setFullScreen(true);
            primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
            primaryStage.show();
    
            primaryStagePublic = primaryStage;
    
        }
        ...