I'm writing a JavaFX application where I'm having a menu bar at the top and an AnchorPane below that where i can use other FXML file to show content. Problem is when the code runs, other FXML file's content is not resizing even after i've set Vgrow to "Always". All of this is inside a AnchorPane.
Can someone please tell me what to do in order to get the inner AnchorPane all the space other than that of the title bar...
Below is the code of parent AnchorPane (savingsCreateDeleteAccount.fxml) :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane prefHeight="455.0" prefWidth="753.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="HomePage">
<children>
<VBox layoutX="-122.0" layoutY="41.0" prefHeight="200.0" prefWidth="722.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="Home">
<items>
<MenuItem mnemonicParsing="false" onAction="#homeScreenOnAction" text="HomeScreen" />
<MenuItem mnemonicParsing="false" onAction="#closeOnAction" text="Close" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Account">
<items>
<Menu mnemonicParsing="false" text="Savings Account">
<items>
<MenuItem mnemonicParsing="false" onAction="#savingsCreateDeleteAccountOnAction" text="Create/Delete Account" />
<MenuItem mnemonicParsing="false" onAction="#savingsViewAccountsOnAction" text="View Account(s)" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Current Account">
<items>
<MenuItem mnemonicParsing="false" onAction="#currentCreateDeleteAccountOnAction" text="Create/Delete Account" />
<MenuItem mnemonicParsing="false" onAction="#currentViewAccountsOnAction" text="View Account(s)" />
</items>
</Menu>
</items>
</Menu>
<Menu mnemonicParsing="false" text="Transactions">
<items>
<MenuItem mnemonicParsing="false" text="Personal Transactions" />
<MenuItem mnemonicParsing="false" text="Business Transactions" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Loan">
<items>
<MenuItem mnemonicParsing="false" text="Student Loan" />
<MenuItem mnemonicParsing="false" text="Property Loan" />
<MenuItem mnemonicParsing="false" text="Business Loan" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About Bank" />
<MenuItem mnemonicParsing="false" text="About App" />
</items>
</Menu>
</menus>
</MenuBar>
<Pane fx:id="displayPane" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" VBox.vgrow="ALWAYS" />
</children>
</VBox>
</children>
</AnchorPane>
Below is the code of the child AnchorPane (homePage.fxml) :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.Pane?>
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" style="-fx-background-color: red;" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" />
Below is the code of Controller Class (HomePage.java) :
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
public class HomePage {
@FXML Pane displayPane;
@FXML public void homeScreenOnAction() throws Exception {
Pane newPane = FXMLLoader.load(getClass().getResource("homePage.fxml"));
Main.primaryStage.setScene(new Scene(newPane, 1000, 600));
Main.primaryStage.show();
}
@FXML public void closeOnAction() {
Main.primaryStage.close();
}
@FXML public void savingsCreateDeleteAccountOnAction() throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("savingsCreateDeleteAccount.fxml"));
Pane tempPane = fxmlLoader.load();
displayPane.getChildren().setAll(tempPane);
}
@FXML public void savingsViewAccountsOnAction() {
}
@FXML public void currentCreateDeleteAccountOnAction() {
}
@FXML public void currentViewAccountsOnAction() {
}
// Transactions, Loan and Help
}
Method to focus on : savingsCreateDeleteAccountOnAction() Main.primaryStage : static variable in Main class to store the primaryStage of the program.
The problem is that you're adding the content loaded from the fxml to a Pane
which doesn't do any positioning or resizing other than resizing the content to it's preferred size.
Replacing displayPane
in the parent layout's child list would allow the VBox
to resize/position.
A different layout is much simpler to use in this case though: BorderPane
This layout allows you to replace the a node like displayPane
easily and also resizes the node that takes it's place automatically:
<BorderPane fx:id="container" prefHeight="455.0" prefWidth="753.0" xmlns="http://javafx.com/javafx/10.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="HomePage">
<top>
<MenuBar>
...
</MenuBar>
</top>
<center>
<Pane fx:id="displayPane" prefHeight="200.0" prefWidth="200.0" />
</center>
</BorderPane>
@FXML
private BorderPane container;
@FXML private void savingsCreateDeleteAccountOnAction() throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("savingsCreateDeleteAccount.fxml"));
Pane tempPane = fxmlLoader.load();
container.setCenter(tempPane);
}
Note: Using static properties of layouts that are not the parent of a node is pointless. E.g. displayPane
's parent is a VBox
so
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"
does not have any effect.
Also manually setting layoutX
/layoutY
, if the parent layout does the positioning is pointless. Those properties of your VBox
are simply overwritten by the parent AnchorPane
during the first layout pass without affecting layout in any way.