Java FX, switching scenes messes up node alignment of second scene? - java

Im working on a java FX application were I switch between my start up scene, startScreen() and my game play scene, create(). I have looked at multiple tutorials on how to switch scenes to make sure I had the right idea, and it seems simple enough.
However, if I start the application with the create() scene the format and alignment of all the nodes within are fine. If I try to start with the startScreen() scene and then switch to the create() using the action event, the alignment of the nodes in the game play scene gets messed up (the boards shift and the labels are placed on top of the boards). As far as I've seen in tutorials, switching scenes shouldn't affect the alignment of nodes of scenes assuming the scenes normally work separately.
Original (just calling create()) and Second Version calling both startScreen() and create()
public Parent create() {
BorderPane root = new BorderPane();
root.setPrefSize(800, 800);
setButtons(root);
enemy = new Board(event -> {...}, true);
player = new Board(event -> {...}, false);
VBox vbox = new VBox(50, enemyLabel, enemy, playerLabel, player);
vbox.setAlignment(Pos.CENTER);
root.setCenter(vbox);
return root;
}
public Parent startScreen(Stage primaryStage) {
BorderPane pane = new BorderPane();
pane.setPrefSize(800, 800);
pane.setId("pane");
Button button = new Button("START");
button.setOnAction(e-> primaryStage.setScene(new Scene(create())));
pane.setCenter(button);
return pane;
}
#Override
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("Boat Wars");
primaryStage.setResizable(false);
//Scene scene = new Scene(startScreen(primaryStage));
//scene.getStylesheets().addAll(this.getClass().getResource("application.css").toExternalForm());
Scene scene = new Scene(create());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}

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.

How do you combine two scenes into one scene?

Is there a way to combine two javaFx scenes into one scene (then assign that scene to a stage) or, assign two scenes to a stage simultaneously so they are side by side on a stage.
Aim: I have a scene that shows a calculator, I have a scene that shows a clock. I want to have them side by side (calculator on left, clock on right) on the same stage (without using scene builder).
Any help would be appreciated.
yes you can do this in javafx with subscenes,
a subscene is like a scene that can be added into layouts
you can do something like this
#Override
public void start(Stage primaryStage) throws Exception {
StackPane layoutOne = new StackPane();
Label labelOne = new Label("One");
layoutOne.getChildren().add(labelOne);
SubScene subSceneOne = new SubScene(layoutOne,300,100);
StackPane layoutTwo = new StackPane();
Label labelTwo = new Label("Two");
layoutTwo.getChildren().add(labelTwo);
SubScene subSceneTwo = new SubScene(layoutTwo,300,100);
VBox root = new VBox(10);
root.setAlignment(Pos.CENTER);
root.getChildren().addAll(subSceneOne,subSceneTwo);
Scene mainScene = new Scene(root,300,210);
primaryStage.setScene(mainScene);
primaryStage.show();
}
hope this what you were looking for, you can also check this for more

how to lock the size of a Stage in java

I made a very simple java application with 3 scenes and 3 buttons.
button3 (b3) opens a popup but I set the image to lock size but the window can still be changed by using the mouse on one of the corners.
is there a way to lock the size so the curson can't edit this?
Here's the simplified code (just to get and idea)
public class Handler extends Application
{
#Override
public void start(Stage primaryStage) throws Exception {
Button button1 = new Button("AD");
VBox layout1 = new VBox(button1);
layout2.setAlignment(Pos.CENTER);
Pane layout2 = new Pane();
layout3.setStyle("-fx-background-image: url(ad.jpg);" +
"-fx-background-repeat: no-repeat;" +
"-fx-background-size: initial;");
Scene scene1 = new Scene(layout1);
Scene scene2 = new Scene(layout2);
//Stage (window)
primaryStage.setTitle("Basic Handler");
primaryStage.setScene(scene1);
primaryStage.setHeight(400);
primaryStage.setWidth(400);
primaryStage.show();
button1.setOnAction(event -> {
Stage PopUp = new Stage();
PopUp.setHeight(266);
PopUp.setWidth(474);
PopUp.setTitle("Sponsored AD");
PopUp.setScene(scene2);
PopUp.showAndWait();
});
}
}
Just add this in your stage :
PopUp.setResizable(false);

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.

Can't display text in a simple javafx application

I'm struggling to display text in a simple javafx application, and I'm struggling to see why it's happening. Here's my code:
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
//Declarations
Pane root = new Pane();
Scene scene = new Scene(root, 960, 600);
javafx.scene.canvas.Canvas background = new Canvas(3840, 2160);
StackPane infoPane = new StackPane();
Text test = new Text("Hello");
test.setY(500);
test.setX(500);
root.getChildren().add(test);
//Stage Setting
primaryStage.setScene(scene);
primaryStage.setTitle("Test application");
primaryStage.setFullScreen(true);
primaryStage.setFullScreenExitHint("Press escape to exit fullscreen");
primaryStage.show();
//javafx.scene.image.Image icon = new Image("Sample/Test.png");
//primaryStage.getIcons().add(icon);
//Parent and child declarations
infoPane.getChildren().add(test);
//Styling
//Background
StackPane backgroundHolder = new StackPane();
backgroundHolder.setStyle("-fx-background-color: #0053A8");
backgroundHolder.getChildren().add(background);
root.getChildren().add(backgroundHolder);
}
The idea is to have an application with a blue background, that has different text fields on it. Thanks for any and all help!
You add the test node to your root Pane, but then you add it also to infoPane. Since a node can only appear once in the scene graph, you are essentially removing it from the root pane before you can see it.
Note that you never add infoPane to your scene graph.
I suggest you read this tutorial, and maybe try a few simple layouts with Scene Builder.

Categories

Resources