This post simply explains, development of JavaFX 2 application using FXML.
FXML: you can say as a Flexible XML.
Requirements:
- XML knowledge
- CSS knowledge
As per JavaFX 2 architecture, it uses Scene Graph which is the starting point for constructing a JavaFX 2 application. It is a hierarchical tree of nodes that represents all of the visual elements of the application's user interface.
For more information on Scene Graph follow this link:
http://docs.oracle.com/javafx/2/scenegraph/jfxpub-scenegraph.htm
- Imports in FXML
<?import javafx.scene.control.*?>
Imports all classes from the javafx.scene.control package into the current namespace.
- Includes in FXML
<fx:include>
This tag creates an object from FXML markup defined in another file.
This promotes ease of maintenance and separation of UI concern.
- Controllers in FXML
We can specify a controller (a handler) for particular FXML. A controller is an object that is associated with the deserialized contents of n FXML document and is responsible for coordinating the behaviors of the objects (often user interface elements) defined by the document.
<AnchorPane id="AnchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="demoshowhide.Sample">
<children>
.....
</children>
</AnchorPane>
- Controller method event handler
A controller method event handler is a method defined by a document's "controller".
Here the controller is binded to that particular FXML.
And also please note that we need to specify the fx:controller in root tag only otherwise it throw exception.
<AnchorPane id="AnchorPane" xmlns:fx="http://javafx.com/fxml" fx:controller="demoshowhide.Sample">
<children>
<HBox id="hBox1" layoutX="102.0" layoutY="36.0" prefHeight="37.0" prefWidth="343.0" spacing="30.0">
<children>
<Button id="areaBtn" onAction="#loadTextArea" text="SHOW TEXT AREA" />
<Button id="treeBtn" onAction="#loadTree" text="SHOW TREE VIEW" />
</children>
</HBox>
</children>
</AnchorPane>
Demo Application
Here is the code for Demo application.
This application contains 2 fxml files which contains view related code.
A java class which will be a controller for the respective fxml and a launcher class (a application class.)
- Sample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>
<?import javafx.scene.shape.*?>
<?import javafx.geometry.*?>
<AnchorPane id="AnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml" fx:controller="demoshowhide.Sample">
<children>
<StackPane id="stackPane1" fx:id="parentStack" layoutX="68.0" layoutY="193.0" prefHeight="147.0" prefWidth="419.0">
<children>
<fx:include source="TextArea.fxml" />
<TreeView id="treeView" fx:id="tree" prefHeight="200.0" prefWidth="200.0" visible="false">
<TreeItem value="Case Full Name">
<children>
<TreeItem>
<value>
<CheckBox id="checkBox1" prefWidth="180.0" text="ONE" />
</value>
</TreeItem>
<TreeItem>
<value>
<CheckBox id="checkBox2" prefWidth="180.0" text="TWO" />
</value>
</TreeItem>
<TreeItem>
<value>
<CheckBox id="checkBox3" prefWidth="180.0" text="THREE" />
</value>
</TreeItem>
</children>
</TreeItem>
</TreeView>
</children>
</StackPane>
<HBox id="hBox1" layoutX="102.0" layoutY="36.0" prefHeight="37.0" prefWidth="343.0" spacing="30.0">
<children>
<Button id="areaBtn" onAction="#loadTextArea" text="SHOW TEXT AREA" />
<Button id="treeBtn" onAction="#loadTree" text="SHOW TREE VIEW" />
</children>
</HBox>
</children>
</AnchorPane>
- TextArea.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<TextArea id="textArea" xmlns:fx="http://javafx.com/fxml" fx:id="area" prefWidth="200.0" text="This is demo application ....text area control..." wrapText="true" />
- Sample.java
package demoshowhide;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeView;
import javafx.scene.layout.StackPane;
/**
*
* @author amol.hingmire
*/
public class Sample implements Initializable {
@FXML
private TreeView tree;
@FXML
private TextArea area;
@FXML
private StackPane parentStack;
@FXML
private void loadTree(ActionEvent event) {
tree.setVisible(true);
area.setVisible(false);
}
@FXML
private void loadTextArea(ActionEvent event) {
area.setVisible(true);
tree.setVisible(false);
}
@Override
public void initialize(URL url, ResourceBundle rb) {
area = (TextArea) parentStack.lookup("#textArea");
}
}
- DemoShowHide.java
package demoshowhide;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*
* @author amol.hingmire
*/
public class DemoShowHide extends Application {
private Stage stage;
public static void main(String[] args) {
Application.launch(DemoShowHide.class, args);
}
@Override
public void start(Stage mainStage) throws Exception {
stage = mainStage;
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
Scene scene = stage.getScene();
if (scene == null) {
scene = new Scene(root);
scene.getStylesheets().add(DemoShowHide.class.getResource("/demoshowhide/demo.css").toExternalForm());
stage.setScene(scene);
} else {
stage.getScene().setRoot(root);
}
stage.sizeToScene();
stage.show();
}
public Stage getStage() {
return stage;
}
}
Description of Application code
Here the application will start from DemoShowHide.java which a launcher/application class.
The FXMLLoader loads the fxml file i.e. Sample.fxml.
In the Sample.fxml file we used the include tag, which actually includes the code present in the other (included fxml i.e. source file) fxml file.
As the fxml file gets loaded its associated controller also gets initialized .
Here Sample.java gets initialized which is bound with Sample.fxml.
In its initialize () we performing the lookup to locate/get the desired Node.
To bind the control i.e. Node we use @FXML annotation.
Note: For FXML details check out for official document at this link
http://docs.oracle.com/javafx/2/api/javafx/fxml/doc-files/introduction_to_fxml.html