JavaFX Have multiple Panes in one scene? - java

I am trying to make an application which will have a date at the top (always automatically centered) and content at the bottom which is not going to be aligned to any direction.
I figured the best way to do this would be to have:
Pane normalLayout = new Pane();
StackPane centeredLayout = new Stackpane();
Label centeredText = new Label("I want this text centered!");
Button unorganizedButton = new Button("Press me");
centeredLayout.getChildren().add(centeredText);
normalLayout.getChildren().add(unorganizedButton);
But then I can't do something like:
Scene myScene = new Scene(centeredLayout, normalLayout, 500, 500);
Window myWindow = new Window();
myWindow.setScene(myScene);
myWindow.show();
So how can this be done? How can multiple panes exist on the same scene?

The Scene it self can only have one root Pane.
So if you want 2 panes in the Scene you need 3.
Scene
|
V
Root Pane (Vbox for example)
| |
V V
Pane1 Pane2
In your code this can look like this:
StackPane rootPane = new StackPane();
Scene scene = new Scene(rootPane,...);
Pane pane1 = new Pane();
Pane pane2 = new Pane();
rootPane.getChildren().addAll(pane1,pane2);
Depending on how your Application should be layouted you have to choose the right Pane implementations.
As a little Tip to get familiar whit all the Layout Containers try the SceneBuilder Application. http://gluonhq.com/open-source/scene-builder/
Maybe this link will help you understanding how layouting works in JavaFX:
http://docs.oracle.com/javafx/2/scenegraph/jfxpub-scenegraph.htm
https://docs.oracle.com/javafx/2/layout/builtin_layouts.htm

I would suggest you to create a "root"-Pane.
In your case, you could use a BorderPane.
Example:
BorderPane root = new BorderPane();
Label centeredText = new Label("I want this text centered!");
Button unorganizedButton = new Button("Press me");
BorderPane.setAlignment(centeredText, Pos.CENTER);
root.setTop(centeredText);
root.setBottom(unorganizedButton);
Afterwards just call the constructor with the newly created pane.
Scene scene = new Scene(root, 500, 500);
Addition:
You could also just set new panes.
AnchorPane anchorPane = new AnchorPane();
root.setTop(anchorPane);

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.

ScrollPane scroll does not work with other nodes

I want to have StackPane as my root pane. I want to have a scrollPane as a small box in the middle of the scene and two buttons below the container.
I tried to make it happen by writing this code:
private StackPane root = new StackPane();
private Scene scene = new Scene(root, 1366, 768);
public ContinueScreen() {
Button button1 = new ButtonBuilder("My Button1").setPrefWidth(200).build();
Button button2 = new ButtonBuilder("My Button2").setPrefWidth(200).build();
Button button3 = new ButtonBuilder("My Button3").setPrefWidth(200).build();
Button button4 = new ButtonBuilder("My Button4").setPrefWidth(200).build();
Button button5 = new ButtonBuilder("My Button5").setPrefWidth(200).build();
Button button6 = new ButtonBuilder("My Button6").setPrefWidth(200).build();
VBox vBox = new VBox(5);
vBox.getChildren().addAll(button1, button2, button3, button4, button5, button6);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(vBox);
scrollPane.setPannable(true);
scrollPane.setMaxSize(500, 180);
scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
root.getChildren().add(scrollPane);
StackPane.setAlignment(scrollPane, Pos.CENTER);
}
As you can probably notice, the code does work perfectly fine but that is until I add the buttons below I was talking about. I added those buttons in an HBox as
HBox hBox = new HBox(5);
hBox.setAlignment(Pos.BOTTOM_CENTER);
hBox.getChildren().addAll(new Button("cat"), new Button("dog"));
root.getChildren().addAll(hBox);
Now both the scrollpane and the two buttons are shown. However the scroll pane now stops working for some reason. The scrollpane is shown and its content but the horizontal or the vertical scroll, both of them do not work. Anyone knows why is this happening and how to fix it?
As you are using StackPane as root it piles up the nodes on one another so the top pane is HBox and not the ScrollPane, so it you are not able to use.
Use BorderPane or VBox and try.
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 1366, 768);
root.setCenter(scrollPane);
HBox hBox = new HBox(5);
hBox.getChildren().addAll(new Button("cat"), new Button("dog"));
root.setBottom(hBox);
The issue here is that StackPane is allowed to resize the HBox, which it does. The HBox covers the complete scene preventing mouse events from reaching the ScrollPane. You can easily see this by coloring the HBox:
hBox.setStyle("-fx-background-color: rgba(100%, 0%, 0%, 0.5)");
The most simple solution would be to set up the HBox to only receive events on non-(fully-)transparent areas:
hBox.setPickOnBounds(false);
However you could also set up the HBox to take up the space required to fit the preferred size of the content and do the alignment via the StackPane:
hBox.setPrefSize(Region.USE_COMPUTED_SIZE, Region.USE_COMPUTED_SIZE);
hBox.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
StackPane.setAlignment(hBox, Pos.BOTTOM_CENTER);
// hBox.setAlignment(Pos.BOTTOM_CENTER);
Note that using a StackPane like this does not provide you with a responsive GUI: If you resize the window to a small enough height, the buttons will cover the ScrollPane.
You may have better luck using a BorderPane or wrapping the StackPane and the HBox in a VBox and setting VBox.vgrow to Priority.ALWAYS for the StackPane...

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

Unable to Pos.CENTER in BorderPane

BorderPane root = new BorderPane();
Button chooseFile = new Button("chooseFile");
TextField fileLocation = new TextField("C:/");
Button makeGrid = new Button("Solve");
HBox fileLoad = new HBox(chooseFile, fileLocation, makeGrid);
root.setTop(lastfil);
BorderPane.setAlignment(root, Pos.TOP_CENTER);
BorderPane.setMargin(root, new Insets(12,12,12,12));
root.setPrefSize(500, 500);
I'm having some issues centering this, I want the prefSize to be 500 x 500 and have the file loader top center, but it does not do that. It is top but I am unable to get it to the center of the top. Anything obvious I'm doing wrong?
BorderPane sets the alignment and Margin for the child node.
BorderPane.setAlignment(Node child, Pos value)
BorderPane.setMargin(Node child, Insets value)
So replace Borderpane 'root' to child node 'fileLoad ' as:
BorderPane.setAlignment(fileLoad, Pos.TOP_CENTER);
BorderPane.setMargin(fileLoad, new Insets(12,12,12,12));
Also set the child HBox alignment like:
fileLoad.setAlignment(Pos.CENTER);
Refer Class BorderPane to more info.

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