The following source code will create a user interface using JavaFX FXML with source code from either an .xml or .fxml file. SceneBuilder (an app available from gluon) will allow the user to drag 'n drop controls onto a window and will automatically generate an .fxml file that can be opened in Android Studio. The alternative is to write your own .xml file using a standard text editor of your choice; this technique requires that you have some understanding of xml syntax. An example with an .xml file is shown below.
Processing Source Code:
import javafx.fxml.FXMLLoader;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
import java.io.File;
import java.net.URL;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.MalformedURLException;
import javafx.fxml.LoadException;
import java.io.IOException;
URL url;
Pane pane;
class MyController {
@FXML
void initialize() {
println("Controller was initialized.");
}
@FXML
void myBtnAction() {
println("You hit btn1.");
}
}
void setup() {
size(1, 1, FX2D);
FXMLLoader loader = new FXMLLoader();
MyController myController = new MyController();
File file = new File(sketchPath() + "/gui.xml");
URI uri = file.toURI();
try {
url = uri.toURL();
}
catch(MalformedURLException e) {
println(e);
}
println("url =", url);
loader.setController(myController);
loader.setLocation(url);
try {
pane = loader.<Pane>load();
println("pane =", pane);
println("children =", pane.getChildren());
}
catch(IOException e) {
println("error:", e.getCause());
}
Stage stage = new Stage();
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
gui.xml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Pane?>
<Pane prefHeight="200.0" prefWidth="400.0">
<children>
<Button layoutX="170.0" layoutY="60.0" onAction="#myBtnAction" prefHeight="26.0" prefWidth="63.0" text="Btn1" />
</children>
</Pane>
Output:
Alternate Technique of JavaFX FXML event handling without a Controller Class:
JavaFX FXML event handling was achieved with a Controller class in the first example. This example shows event handling without using a Controller class. An ObservableList of Nodes (controls) is obtained by calling .getChildren() on the root Pane. After looking at the list and making the appropriate cast, an instance of each control is obtained by using its respective list index. Various events may then be performed with these instances.
// Demonstrates JavaFX FXML event handling without using a Controller class
import javafx.fxml.FXMLLoader;
import javafx.fxml.FXML;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import java.io.File;
import java.net.URL;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.MalformedURLException;
import javafx.fxml.LoadException;
import java.io.IOException;
import javafx.collections.*;
URL url;
Pane pane;
ObservableList<javafx.scene.Node> ctrl;
Button btn1;
Label label1;
void myBtnAction() {
println("Btn hit.");
label1.setText("Jeremiah was a bullfrog.");
}
void setup() {
size(1, 1, FX2D);
FXMLLoader loader = new FXMLLoader();
File file = new File(sketchPath() + "/gui2.xml");
URI uri = file.toURI();
try {
url = uri.toURL();
println("url =", url);
}
catch(MalformedURLException e) {
println(e);
}
loader.setLocation(url);
try {
pane = loader.<Pane>load();
}
catch(IOException e) {
println("error:", e.getCause());
}
println("pane =", pane);
ctrl = pane.getChildren();
println("ctrl list:",ctrl);
label1 = (javafx.scene.control.Label)ctrl.get(0);
btn1 = (javafx.scene.control.Button)ctrl.get(1);
btn1.setOnAction(event -> { myBtnAction(); } );
Stage stage = new Stage();
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
gui2.xml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Pane?>
<Pane prefWidth="400.0" prefHeight="200.0" >
<children>
<Label layoutX="140.0" layoutY="40.0" text="Jeremiah"/>
<Button layoutX="150.0" layoutY="80.0" prefWidth="100.0" text="Btn1"/>
</children>
</Pane>
Output: