JavaFX fullscreen stage resizing - java

I have a problem with fullscreen stages. I have 1 main stage which enters full screen immediately when application starts, then when the user invokes specific event, I create second stage which is also full screen, but it shows image and its background is transparent, so the main stage and its content is still visible.
The problem is when I display this new stage and set it to fullscreen mode, it makes my main stage exit its fullscreen mode and resize.
Creation of main stage:
root = new StackPane();
scene = new Scene(root);
stage = primaryStage;
scene.setOnKeyReleased(event -> {
if (event.getCode() == KeyCode.ESCAPE) {
close();
}
});
stage.setScene(scene);
stage.setFullScreen(true);
stage.setFullScreenExitHint(null);
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
stage.setOnCloseRequest(closeRequest -> onClose(closeRequest));
Creation of the new stage:
root = new StackPane();
scene = new Scene(root);
stage = new Stage(StageStyle.TRANSPARENT);
image = new ImageView(new Image(imagePath, 400, 580, true, true));
root.setAlignment(Pos.CENTER);
root.setStyle("-fx-background-color: rgba(0, 0, 0, 0.5)");
root.getChildren().add(image);
scene.setFill(Color.TRANSPARENT);
scene.setOnMousePressed(event -> stage.close());
stage.initOwner(Window.getInstance().getStage());
stage.setScene(scene);
stage.setFullScreen(true);
stage.setFullScreenExitHint(null);
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);

Well I solved this problem by using stage.setMaximized(true) instead of setting it to fullscreen and it worked. I don't know if this is good solution, but I just wanted to post it here.

Related

Changing stage width/height then switching scene does not update the UI in the new scene

I have two scenes A and B and a stage.
If I'm in scene A, and change the stage width / height, it will update the UI to scale it to the new stage dimensions.
However if from there I switch to scene B, the UI in scene B will not be updated till I force a update by doing something like resizing the screen or opening and closing the stage.
Is there a way to update all scenes when the stage width / height is changed? Since only one scene can be set to the stage at one time the current changes are not applying automatically to all scenes.
Here's a minimal reproduced example.
#Override
public void start(Stage stage) throws Exception {
stage.setWidth(400);
stage.setHeight(400);
Scene scene1, scene2;
BorderPane layout1 = new BorderPane();
Button buttontosecond = new Button("go to second page");
layout1.setCenter(buttontosecond);
scene1 = new Scene(layout1, stage.getWidth(), stage.getHeight());
BorderPane layout2 = new BorderPane();
Button buttonsize = new Button("change size");
Button buttontomain = new Button("back to main");
VBox vbox = new VBox(buttonsize, buttontomain);
vbox.setAlignment(Pos.CENTER);
layout2.setCenter(vbox);
scene2 = new Scene(layout2, stage.getWidth(), stage.getHeight());
buttontomain.setOnAction(actionEvent -> {stage.setScene(scene1);});
buttontosecond.setOnAction(actionEvent -> {stage.setScene(scene2);});
buttonsize.setOnAction(actionEvent -> {stage.setWidth(200);stage.setHeight(200);});
stage.setScene(scene1);
stage.show();
}
DO not do scene switching in this way. Instead implement a single scene root-switching system as shown in the answer to this post. I did not manage to get the code above to work, but I found that the reason for this was my dual monitor setup. When dragging the game window into the other monitor it worked fine.

Having some trouble with javafx alert box interactions

I'm trying to learn javafx and I'm having some trouble with alert box interactions. My code is pretty straightforward:
public static void display(String title, String message) {
Stage window = new Stage();
window.initModality(Modality.APPLICATION_MODAL);
window.setTitle(title);
window.setMinWidth(250);
Label label = new Label();
label.setText(message);
Button closeButton = new Button("Close the window");
closeButton.setOnAction(e -> window.close());
VBox layout = new VBox(10);
layout.getChildren().addAll(label, closeButton);
layout.setAlignment(Pos.CENTER);
Scene scene = new Scene(layout);
window.setScene(scene);
window.showAndWait();
}
The problem is I can still somewhat interact with my initial window that I used to open the alert box, mainly clicking on the initial window brings it in front of the alert box. To my understanding, this shouldn't happen. Here is a gif demonstrating the issue: https://gyazo.com/0c2b69ec39f849227560fbdf2099c07c
Here is my code that calls the alert box
public void start(Stage primaryStage) {
window = primaryStage;
window.setTitle("Alert Box test");
button = new Button("Click me");
button.setOnAction(e -> AlertBox.display("New Alert", "Don't forget to close this window!"));
StackPane layout = new StackPane();
layout.getChildren().add(button);
Scene scene = new Scene(layout, 300, 250);
window.setScene(scene);
window.show();
}
What am I doing wrong here or is that just the intended behavior?

Creating new Transparent Stage on Event JavaFX

I'm trying to create a new Stage when a button is pressed.
It works but the problem is that I'd like this Stage to be fully transparent and lets us see what's behind the screen.
Code
Dimension Sizescreen = Toolkit.getDefaultToolkit().getScreenSize();
//Main stage with option menu
Pane window = new Pane();
Scene scene = new Scene(window);
stage.setTitle("Notification Extender");
//Create the button SetLooker
Button SetLooker = new Button("Set Looker");
//Add a Event when pressed
SetLooker.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
//Create a sub-Stage
Pane subwindow = new Pane();
Scene subscene = new Scene(subwindow);
Stage substage = new Stage();
substage.setTitle("Notification Extender");
//Set this subStage Transparent
substage.initStyle(StageStyle.TRANSPARENT);
subscene.setFill(Color.TRANSPARENT);
substage.setWidth(Sizescreen.getWidth());
substage.setHeight(Sizescreen.getHeight());
substage.setX(0);
substage.setY(0);
//Create a a graphique element
Rectangle redrec = new Rectangle(120,40,50,50);
redrec.setStroke(Color.RED);
redrec.setStrokeWidth(2);
redrec.setFill(Color.TRANSPARENT);
//Add the graphique element to the sub-stage
subwindow.getChildren().add(redrec);
//Show the sub-stage
substage.setScene(subscene);
substage.show();
}
});
//Add the button to the main stage
window.getChildren().add(SetLooker);
//Show the main stage
stage.setScene(scene);
stage.show();
The problem is that when I press the button it shows the stage but it's not transparent at all it's completely white.
I've also tried to change the main Stage, but I cannot change it once it has been shown.
You also need to remove the background from the root of your new scene:
subwindow.setBackground(null);

In Javafx when a window is opened how can i set it so that the user isnt able to open the same window again?

I tried a lot but just couldn't find any solution. At the moment the opened window(popup window) is always on top but the user can still access the main window. That's how it should be, but it shouldn't be possible to open the same popup window again.
Stage stage = new Stage();
stage.setTitle(panelTitle);
stage.setScene(new Scene(root));
stage.initModality(Modality.WINDOW_MODAL);
stage.setAlwaysOnTop(true);
stage.showAndWait();
Thank you in advance!
As LazerBanana said, I would disable the button that opens the window, and I would enable it when you close it.
Stage stage = new Stage();
button.setDisable(true);
stage.setTitle(panelTitle);
stage.setScene(new Scene(root));
stage.initModality(Modality.WINDOW_MODAL);
stage.setAlwaysOnTop(true);
stage.showAndWait();
// your logic here
button.setDisable(false);
An alternative solution to creating a new one each time is to create one and just setup and show.
public class Stack extends Application {
private final Stage popup = new Stage();
#Override
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
root.setPrefWidth(400);
root.setPrefHeight(200);
Button button = new Button("ClickMePopup");
root.setCenter(button);
button.setOnAction(
event -> {
if (!popup.isShowing()) {
// you dont set modality because after the stage is set to visible second time it will throw an exception.
// Again depends on what you need.
// popup.initModality(Modality.WINDOW_MODAL);
// this focuses the popup and main window is not clickable
// popup.initOwner(stage);
VBox dialogVbox = new VBox(20);
dialogVbox.getChildren().add(new Text("Some Dialog"));
Scene dialogScene = new Scene(dialogVbox, 300, 200);
popup.setScene(dialogScene);
// you can actually put all above into the method called initPopup() or whatever, do it once, and just show it here or just bind the property to the button.
popup.show();
}
});
Scene scene = new Scene(root);
stage.setTitle("Stack");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Or disable the button when clicked, but if your popup is not driven by the button or can be opened from other places the first idea would be a bit better in my opinion. Depends on what you need.
Or just create your own class and Springify it.

Using showAndWait in the onFinished EventHandler of an Animation doesn't work

In JavaFx, I want to show a modal dialog after an animation ends. For some reason, calling showAndWait in the EventHandler that gets executed after the animation ends doesn't work. A new window is shown, but it seems like nothing is drawn inside it.
This example demonstrates the issue:
public void start(Stage primaryStage) {
Rectangle rect = RectangleBuilder.create().width(200).height(200).fill(Color.RED).build();
StackPane root = new StackPane();
root.getChildren().add(rect);
Timeline animation = new Timeline();
animation.getKeyFrames().addAll(
new KeyFrame(new Duration(1000),
new KeyValue(rect.widthProperty(), 100),
new KeyValue(rect.heightProperty(), 100)),
new KeyFrame(new Duration(2000),
new KeyValue(rect.widthProperty(), 300),
new KeyValue(rect.heightProperty(), 300))
);
animation.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Stage stage = new Stage();
StackPane pane = new StackPane();
pane.getChildren().add(new Label("Hello world"));
stage.setScene(new Scene(pane, 100, 100));
stage.showAndWait();
}
});
animation.setCycleCount(1);
Scene scene = new Scene(root, 300, 300);
primaryStage.setScene(scene);
primaryStage.show();
animation.play();
}
The full code can be found at https://gist.github.com/bmesuere/9605866
I'd like to know why this doesn't work (on my macbook using java 1.7.0_51) and get suggestions for a workaround.
It seems to work if you wrap the code to show the stage in a Platform.runLater():
animation.setOnFinished(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
Platform.runLater(new Runnable() {
#Override
public void run() {
Stage stage = new Stage();
StackPane pane = new StackPane();
pane.getChildren().add(new Label("Hello world"));
stage.setScene(new Scene(pane, 100, 100));
stage.showAndWait();
}
});
}
});
No idea why. It fails on Java FX 8 too.
I have reported this as a bug in JavaFX (Jira issue).
A comment from that issue:
The problem is that no subsequent pulse is scheduled when showAndWait() is called while pulse is being processed.
This was 'fixed' in Java 8u20. An exception is now thrown. Changes can be seen here.

Categories

Resources