Development Guide

Example - First Extension

Let's create our own extension. First download the extension template from PETEP Extension Template GitHub.

You can download the final extension project on PETEP Example Extension GitHub or you can follow this guide.

Building and running extension with PETEP

You can also clone PETEP repository from PETEP GitHub and configure settings.gradle file, so that it includes extensions to build:

  1. Set "gradle.ext.extensions" in petep/settings.gradle to "true".
  2. Set "gradle.ext.extensionsDirectory" in petep/settings.gradle to correct path to your extensions.
  3. Set "gradle.ext.petepLib" in extension/settings.gradle to correct path to built "petep-lib.jar".
  4. Make some changes in your extension.
  5. Run "mvn assemble" in PETEP project.
  6. Run "mvn run" in PETEP project.
  7. PETEP will be built, your extension will be built and JAR file of your extension will be automatically copied to /ext in PETEP directory.
  8. PETEP will start.

Using this approach you can easily develop your extension and run PETEP with it. You can also setup the petep/settings.gradle, so that it does not show wizard, but always runs your project. (This is a lot faster than doing these actions by yourself.)

If you need some functionality in PETEP core for your extension, using this approach you can easily make changes in both PETEP and your extension and test it together. Afterwards you can create pull request to PETEP repository if you want to make it accessible for everyone.

Building and running extension with PETEP

The first thing we need is to import PetepLib.jar (from distribution/api) to our project and then create package petep with class PetepExtension. (Or you can download empty PETEP extension with everything configured from PETEP Extension GitHub.)

public class PetepExtension extends Extension {
    public PetepExtension(String path) {

    public String getCode() {
        return "example";

    public String getName() {
        return "Example extension.";

    public String getDescription() {
        return "Example extension for developers.";

    public String getVersion() {
        return "0.0.42";

    public void init(ExtensionHelper helper) {
        Logger.getGlobal().info("Example extension loaded!");

    public void initGui(GuiHelper helper) {
        Logger.getGlobal().info("Example extension GUI loaded!");

Now we can export our extension to .JAR file and import it to our project. If we run PETEP from command line, we should see our logs.

Let's also create a simple empty Tab in both application and settings by adding the following code to initGui method:

petep.Extension: public void initGui(GuiHelper helper)
// Load application tab
try {
    var loader = new FXMLLoader(getClass().getResource("/fxml/ExampleAppTab.fxml"));
    var appTab = (Parent) loader.load();
    helper.registerTab("Example App Tab", appTab);
} catch (IOException e) {
    Logger.getGlobal().log(Level.SEVERE, "Could not load example app tab.", e);

// Load settings tab
try {
    Parent settingsTab = FXMLLoader.load(getClass().getResource("/fxml/ExampleSettingsTab.fxml"));
    helper.registerSettingsTab("Example Settings Tab", settingsTab);
} catch (IOException e) {
    Logger.getGlobal().log(Level.SEVERE, "Could not load example settings tab.", e);

Example FXML tab template:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane xmlns:fx="" prefHeight="37.0" prefWidth="90.0" xmlns="">
        <Label layoutX="10.0" layoutY="10.0" styleClass="heading-2" text="Example Tab" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0"/>

If you are not used to using JavaFX/FXML, I recommend checking out Gluon Scene Builder for designing the GUI.

We should see both tabs added to the extension after deploying it again.