FXML
As well as creating the UI in code as in the interface examples, if you want something more complex, or just want to see it laid out before you add it to the launcher you can load an .fxml
file instead. Whilst you could write the file by hand, it would probably be easier if you download Scene Builder and use it to to help you make layouts.
An .fxml
file looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.VBox?>
<VBox prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="mod.wurmonline.MyController">
<children>
<TextField fx:id="nameText" promptText="Enter name" />
<Button fx:id="saveButton" mnemonicParsing="false" onAction="#saveButtonClicked" text="Save" />
</children>
</VBox>
If you use Scene Builder, make sure to set controller
in the bottom left of the window. This is what connects your layout to your code.
package mod.wurmonline;
import javafx.scene.control.Label;
import javafx.scene.layout.Region;
import javafx.scene.layout.Pane;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import mod.wurmonline.serverlauncher.gui.ServerGuiController;
import org.gotti.wurmunlimited.modloader.interfaces.WurmMod;
import org.gotti.wurmunlimited.modloader.interfaces.WurmUIMod;
public class MyController implements WurmMod, WurmUIMod {
ServerGuiController guiController;
public Region getRegion(ServerGuiController guiController) {
controller = guiController;
try {
FXMLLoader fx = new FXMLLoader(MyController.class.getResource("MyLayout.fxml"));
fx.setClassLoader(this.getClass().getClassLoader());
return (Region)fx.load();
} catch (IOException ex) {
logger.log(Level.SEVERE, ex.getMessage(), ex);
Pane pane = new Pane();
Label label = new Label("Players.fxml was not loaded.");
pane.getChildren().add(label);
return pane;
}
}
}
Because this layout is not the main window, you have to add a step in between what you'd normally do to load an .fxml
. So after creating a new FXMLLoader
you need to setClassLoader
to your class' classloader
, otherwise it will try and find it on the launcher controller. The catch section isn't necessarily needed, however if for some reason it does not find the .fxml
file it will stop it bringing the whole launcher down. Not that I had that happen to me...
@FXML
TextField nameText;
@FXML
Button saveButton;
@FXML
void saveButtonClicked() {
saveButton.setDisable(true);
String text = nameText.getText();
// Save text somewhere.
}
When you have your .fxml
file loaded, you can access any of the items you set a name for by adding @FXML
above them. Same goes for methods, when a button is clicked it will call the method of the controller specified in the onAction=""
attribute. However not all items have onAction
, in which case you need to look into creating a ChangeListener
. Any items that allow the user to enter or alter information have getText
or getValue
or similar. By keeping a reference to the button as well you can enable or disable it depending on how your mod works.
If you want to see some more involved examples, have a look at the following mods that come with the launcher: