changing scenes in full screen - javafx

I have read several questions/solutions here that are related to my problems. but nothing seems to work.
so I have a primarystage in fullscreen mode, say if i click a button it changes the scene. but the stage seems to display the taskbar. also I resolved the issue by adding this to all of the scene methods..
stage.setFullScreen(false);
stage.setFullScreen(true);
BUT, the transition in scenes is not that fluid. first it goes to desktop and back to fullscreen.. which is not the ideal solution.
here is my code for the primary stage:
public static Stage stage;
private static AnchorPane mainLayout;
#Override
public void start(Stage primaryStage) throws IOException
{
Main.stage = primaryStage;
Main.stage.setTitle("Raven App");
stage.initStyle(StageStyle.UNDECORATED);
stage.setFullScreen(true);
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
Main.showMain();
}
here is my code for changing the scene:
public static void UserLogin() throws IOException
{
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
Scene scene=new Scene(mainLayout);
stage.setScene(scene);
stage.show();
}
I don't know if this is a bug or something. But i thought if you set your primary stage to full screen. and should be fullscreen all through out regardless of scene.
also, if i have a primary stage in full screen mode.. and a secondary stage NOT in full screen mode. the primary stage seems to disappear if i click a button to show the secondary stage. I wanted to show the secondary page on top of the primary stage, and the primary stage should not be clickable unless the secondary page is closed.
my code for showing the secondary stage:
public static void PasswordVerify() throws IOException
{
Stage stage = new Stage();
Parent root = FXMLLoader.load(Main.class.getResource("page/PassConfirm.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("popup window");
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
stage.show();
}

Instead of creating a new scene, just change the root of the existing scene:
public static void UserLogin() throws IOException {
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
stage.getScene().setRoot(mainLayout);
// or just
// scene.setRoot(mainLayout);
// if you already have a reference to the scene
}
The second thing you are asking is not really possible. In JavaFX, on many platforms "full screen mode" is really implemented as "exclusive screen mode"; so there is a unique window visible. So you would need another solution entirely to this, that didn't involve displaying a new window at all.

Related

Cannot set stage to transparent in Preloader

I am trying to create a simple splash screen. In fact I have a stackpane with an image as background. I do not want to show the default javafx decorations.
So I tried StageStyle.TRANSPARENT but it makes the whole thing transparent. On the other hand StageStyle.UNDECORATED show the image but with a white background. Here is the code in my start method.
public class SplashScreen extends Preloader {
private Stage stage;
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
StackPane root = (StackPane) FXMLLoader.load(getClass().getClassLoader().getResource("layouts/splash.fxml"));
Scene scene = new Scene(root, 690, 380,true, SceneAntialiasing.BALANCED);
scene.setFill(Color.TRANSPARENT);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
...
I am using java 11.0.8 and javafx 14
JavaFX 15 fixed this. Seems it was a bug.

How to make pane and elements in it resizable when stage size is changing

Can you please tell me how can I realize that the whole content of a pane will be resized while the stage is resized with mousedragg. Here is my code:
public class fab extends Application {
private Stage stage;
private Pane pane;
private Scene scene;
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
Button button = new Button("Button");
pane = new Pane();
pane.getChildren().add(button);
stage.setTitle("Test");
scene = new Scene(pane, 640, 640);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
I think there is the idea of binding. But I don't know how to use that, in order to make all nodes of a pane resizable, when the stage size is changing.
I'm searching a solution without Fxml or sceneBuilder.
Thank you in advance.
If you insists to use the Pane container then after the line scene = new Scene(pane, 640, 640); add this:
scene.widthProperty().addListener((c,o,n)->button.setPrefWidth((Double)n));
scene.heightProperty().addListener((c,o,n)->button.setPrefHeight((Double)n));
and after the line stage.setScene(scene); add this:
button.setPrefSize(scene.getWidth(), scene.getHeight());
This works fine with Pane and do your required thing.
But I prefer using an AnchorPane container and set the Top, Right,Bottom and Left anchors to 0 .
Here is the solution if you wish to bind the width of the button to you scene width
button.minWidthProperty().bind(scene.widthProperty());
You can also modify this +/- whatever you want for ex
button.minWidthProperty().bind(scene.widthProperty().subtract(20));
and you can do the same for the height
button.minHeightProperty().bind(scene.heightProperty().subtract(200));

How to make non-modal stage appear always on top of JavaFx fullscreen stage

I have
a primary stage which the user can configure to be in fullscreen mode
secondary stages (tool windows) which the user can open. These windows should be always on top the the primary stage (regardless of whether its in fullscreen mode or not).
The latter does not work, even if I use setAlwaysOnTop(true) for the secondary stages they will disappear behind the primary stage once the user clicks on the primary stage.
This only happens when the primary stage is in full screen mode, everything works fine if the primary stage is not in fullscreen mode.
How can I enable this concept of tools windows in front of a fullscreen stage? Example code:
public class Test extends Application {
#Override
public void start(Stage stage) {
VBox vbox = new VBox();
Scene scene = new Scene(vbox);
stage.setScene(scene);
Button button1 = new Button("New Tool Window");
button1.setOnAction((e) -> {
Stage toolStage = new Stage();
Scene toolScene = new Scene(new Label("Am I on top?"), 300, 250);
toolStage.setScene(toolScene);
toolStage.initOwner(stage);
toolStage.setAlwaysOnTop(true);
toolStage.show();
});
Button button2 = new Button("Close");
button2.setOnAction((e) -> System.exit(0));
vbox.getChildren().addAll(button1, button2);
stage.show();
stage.setFullScreen(true);
}
public static void main(String[] args) {
launch(args);
}
}
Update 8/20/2016: Confirmed as a bug: JDK-8164210
A way to bypass this limitation is to:
Deactivate fullscreen mode
Create a keyCombination for psuedo fullscreen
Set the stage style undecorated and not resizable
Se the screen to the size of the user screen and position it at 0,0.
It is easy to create your own border for minimizing and closing the program as shown here:
JavaFX Stage.setMaximized only works once on Mac OSX (10.9.5)
And here:
JavaFX 8 Taskbar Icon Listener
you need to set initmodality after set initowner
toolStage.initOwner(stage);
toolStage.initModality(Modality.APPLICATION_MODAL);

JavaFX + Scene Builder how switch scene

I'm working with JavaFx and Scenebuilder and want create a local app for myself called "Taskplanner" in eclipse.
I created a new Stage and set it with a Scene (see Main.java). But not sure how to set a new Scene in the old stage (see Controller.java). Didnt also not find out if it is possible pass the signInButtonClicked()-Methode the "Stage primaryStage" over Scene Builder
Can anybody help ?
Controller.java:
#FXML
Button btnSignIn;
#FXML
public void signInButtonClicked() throws Exception
{
//Here I want call the new Scene(SignInGUI.fxml) in my old Stage
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("../view/SignInGUI.fxml"));
}
Main.java:
#Override
public void start(Stage primaryStage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("../view/LoginGUI.fxml"));
primaryStage.setTitle("Taskplanner");
primaryStage.setScene(new Scene(root,500,500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
You can get a reference to the Scene and Window from your button reference. From there, it's up to you to decide how to you want to show the new view.
Here's how you get those references:
Scene scene = btnSignIn.getScene();
Window window = scene.getWindow();
Stage stage = (Stage) window;
You can change the view by changing the root of your Scene:
FXMLLoader loader = ... // create and load() view
btnSignIn.getScene().setRoot(loader.getRoot());
Or you can change the entire Scene:
FXMLLoader loader = ... // create and load() view
Stage stage = (Stage) btnSignIn.getScene().getWindow();
Scene scene = new Scene(loader.getRoot());
stage.setScene(scene);

How to create a modal window in JavaFX 2.1

I can't figure out how to create a modal window in JavaFX. Basically I have file chooser and I want to ask the user a question when they select a file. I need this information in order to parse the file, so the execution needs to wait for the answer.
I've seen this question but I've not been able to find out how to implement this behavior.
In my opinion this is not good solution, because parent window is all time active.
For example if You want open window as modal after click button...
private void clickShow(ActionEvent event) {
Stage stage = new Stage();
Parent root = FXMLLoader.load(
YourClassController.class.getResource("YourClass.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("My modal window");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(
((Node)event.getSource()).getScene().getWindow() );
stage.show();
}
Now Your new window is REALY modal - parent is block.
also You can use
Modality.APPLICATION_MODAL
Here is link to a solution I created earlier for modal dialogs in JavaFX 2.1
The solution creates a modal stage on top of the current stage and takes action on the dialog results via event handlers for the dialog controls.
JavaFX 8+
The prior linked solution uses a dated event handler approach to take action after a dialog was dismissed. That approach was valid for pre-JavaFX 2.2 implementations. For JavaFX 8+ there is no need for event handers, instead, use the new Stage showAndWait() method. For example:
Stage dialog = new Stage();
// populate dialog with controls.
...
dialog.initOwner(parentStage);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.showAndWait();
// process result of dialog operation.
...
Note that, in order for things to work as expected, it is important to initialize the owner of the Stage and to initialize the modality of the Stage to either WINDOW_MODAL or APPLICATION_MODAL.
There are some high quality standard UI dialogs in JavaFX 8 and ControlsFX, if they fit your requirements, I advise using those rather than developing your own. Those in-built JavaFX Dialog and Alert classes also have initOwner and initModality and showAndWait methods, so that you can set the modality for them as you wish (note that, by default, the in-built dialogs are application modal).
You can create application like my sample. This is only single file JavaFX application.
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Stage stage;
stage = new Stage();
final SwingNode swingNode = new SwingNode();
createSwingContent(swingNode);
StackPane pane = new StackPane();
pane.getChildren().add(swingNode);
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Swing in JavaFX");
stage.setScene(new Scene(pane, 250, 150));
stage.show();
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void createSwingContent(final SwingNode swingNode) {
SwingUtilities.invokeLater(() -> {
try {
Path currentRelativePath = Paths.get("");
String s = currentRelativePath.toAbsolutePath().toString();
JasperDesign jasperDesign = JRXmlLoader.load(s + "/src/reports/report1.jrxml");
String query = "SELECT * FROM `accounttype`";
JRDesignQuery jrquery = new JRDesignQuery();
jrquery.setText(query);
jasperDesign.setQuery(jrquery);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint JasperPrint = JasperFillManager.fillReport(jasperReport, null, c);
//JRViewer viewer = new JRViewer(JasperPrint);
swingNode.setContent(new JRViewer(JasperPrint));
} catch (JRException ex) {
Logger.getLogger(AccountTypeController.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

Resources