It is however possible to do templating using javaFX available features and this is one such attempt.
About the Sample Module
The module contains following- Template file "testtemplate.fxml"
- Template's constituents like header, footer etc (top.fxml, bottom.fxml and right.fxml)
- Application pages like first.fxml and second.fxml
- Controller classes
"Template"
Template file "testtemplate.fxml", creates a layout structure, in which there is a header component, a footer component, a right component and a "main" component. Files "top.fxml", "bottom.fxml" and "right.fxml" fill as the common component and are loaded using "<fx:include>".
<Pane layoutX="14.0" layoutY="14.0" prefHeight="740.0" prefWidth="996.0" style="-fx-background-color: white; -fx-border-radius: 20; -fx-background-radius: 20;"> <children> <FlowPane prefHeight="733.0" prefWidth="996.0"> <children> <AnchorPane id="top" prefHeight="175.0" prefWidth="996.0" > <fx:include source="top.fxml"/> </AnchorPane> <AnchorPane id="main" prefHeight="474.0" prefWidth="867.0" > <TextField id="dummyTxt" layoutX="4.0" layoutY="57.0" text="This is Text Field in template"></TextField> </AnchorPane> <AnchorPane id="right" prefHeight="474.0" prefWidth="129.0" > <fx:include source="right.fxml"/> </AnchorPane> <AnchorPane id="bottom" prefHeight="77.0" prefWidth="996.0" > <fx:include source="bottom.fxml"/> </AnchorPane> </children> </FlowPane> </children> </Pane>
The template also contains an AnchorPain with id "main", it is a placeholder for application pages, which will be loaded by "Application" class.
"Main Application"
"MainController.java" implements "Application" and hence its the starting point of the application, once launched, JavaFX lifecycle calls "Start(..)" on it. After setting the "Stage", replaceSceneContent(..) is called, it contains all the template processing logic.
First the page to be displayed is loaded
// get main page
Page mainPage = Page.getPage(_displayPage);
main = mainPage.getPane();
// get reference of Pane to be added to the template.
main = (AnchorPane) main.lookup("#screenID");
mainController = mainPage.getController();
then the template
// get template
templatePage = (AnchorPane) getTemplate(_template);
// get reference of the "main" section in template i.e. where the new contents will be added
AnchorPane origMain = (AnchorPane) templatePage.lookup("#main");
// set contents of "mainPage" into the template.
origMain.getChildren().setAll(main.getChildren());
A Scene is created and set onto stage
// create scene.
Scene scene = new Scene(templatePage, 1200, 800);
//set stage.
stage.setScene(scene);
The resulting page that is displayed contains all four pieces i.e. header, footer, right and main.
Download source here
Prasanna Bhale
Note: Any note or comment is appreciated; it helps improve my blog.
Hi great tutorial and exactly what I was searching for. Seam's your the only documentation for using templating. Anyhow when I run your example code it throws the following exception in Page.java row 37 => "javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load." Any idea how to solve this?
ReplyDeleteHi Jan,
DeleteTry running sample code with JDK 7 and Netbeans 8.0. Simply download the zip file, and open the project in Netbeans and run project.
the same error
DeleteI managed to make it work by replacing the tag <fx:root type="javafx.scene.layout.AnchorPane" with just <AnchorPane in all templates
DeleteI don't see setRoot anywhere in the code, and fx:root requires it's usage: "the calling code must specify this value by calling the setRoot() method. "
Been looking for this...Go to the individual fxml file and switch the root tags, in my case I switched to ..... and it worked. Thanks!
ReplyDeleteThis comment has been removed by the author.
Deletethanks for sharinign vey nice blog
ReplyDeleteselenium training institute