Development Guide

Example - First Receiver

Let's create simple receiver for SerializedPdu, which will be used to show received SerializedPdu using SerializedPduView and we will make it possible to send the SerializedPdu to other receiver.

Simple receiver

Our simple reciver will receive SerializedPdu and hand them over to Consumer<SerializedPdu>, which will be part of the controller.

receiver.ExampleReceiver
package receiver;

import com.warxim.petep.core.pdu.SerializedPdu;
import com.warxim.petep.extension.receiver.Receiver;
import lombok.Data;

import java.util.function.Consumer;

/**
 * Example receiver for receiving serialized PDUs.
 */
@Data
public class ExampleReceiver implements Receiver {
    private Consumer<SerializedPdu> consumer;

    @Override
    public String getName() {
        return "Example Receiver";
    }

    @Override
    public String getCode() {
        return "example-receiver";
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return SerializedPdu.class.equals(clazz);
    }

    @Override
    public void receive(Object object) {
        if (consumer == null) {
            return;
        }

        var serializedPdu = (SerializedPdu) object;
        consumer.accept(serializedPdu);
    }
}

We have to register the receiver in beforeInit method:

petep.Extension: public void beforeInit(ExtensionHelper helper)
if (helper.getContextType().equals(ContextType.GUI)) {
    receiver = new ExampleReceiver();
    helper.registerReceiver(receiver);
    extensionHelper = helper;
}

App Tab With Controller

We have to improve our FXML template for app tab, so that it contains SerializedPduView, and we also have to define controller, so that we can show serialized PDUs programatically.

Extended tab template for app tab:

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

<?import com.warxim.petep.gui.control.SerializedPduView?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Tab?>
<?import javafx.scene.control.TabPane?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="645.0" prefWidth="996.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <Label layoutX="10.0" layoutY="10.0" styleClass="heading-2" text="Example Tab" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
      <TabPane layoutY="37.0" prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="35.0">
        <tabs>
          <Tab text="Received serialized PDU">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                  <Label layoutX="14.0" layoutY="14.0" styleClass="heading-2" text="Last received serialized PDU:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
                     <SerializedPduView fx:id="serializedPduView" layoutX="10.0" layoutY="34.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
                     <Button fx:id="sendToButton" layoutX="234.0" layoutY="6.0" mnemonicParsing="false" onAction="#onSendToButtonClick" text="Send To" AnchorPane.leftAnchor="200.0" AnchorPane.topAnchor="6.0" />
              </AnchorPane>
            </content>
          </Tab>
        </tabs>
      </TabPane>
    </children>
</AnchorPane>

Controller class:

gui.ExampleAppTabController
package gui;

import com.warxim.petep.core.pdu.SerializedPdu;
import com.warxim.petep.extension.receiver.Receiver;
import com.warxim.petep.gui.control.SerializedPduView;
import com.warxim.petep.gui.dialog.Dialogs;
import com.warxim.petep.helper.ExtensionHelper;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Value;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

@RequiredArgsConstructor
public class ExampleAppTabController implements Initializable {
    private final ExtensionHelper extensionHelper;

    @FXML
    private SerializedPduView serializedPduView;
    @FXML
    private Button sendToButton;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        sendToButton.setDisable(true);
    }

    /**
     * Shows serialized PDU in view.
     * @param serializedPdu PDU to be shown
     */
    public void showSerializedPdu(SerializedPdu serializedPdu) {
        sendToButton.setDisable(false);
        serializedPduView.setSerializedPdu(serializedPdu);
    }

    /**
     * Shows dialog for choosing target receiver and then sends serialized PDU to it.
     */
    @FXML
    private void onSendToButtonClick(ActionEvent event) {
        var maybePdu = serializedPduView.getSerializedPdu();
        if (maybePdu.isEmpty()) {
            return;
        }

        var receivers = extensionHelper.getReceivers(SerializedPdu.class).stream()
                .map(ReceiverWrapper::new)
                .collect(Collectors.toList());

        var maybeReceiverWrapper = Dialogs.createChoiceDialog("Send to receiver", "Choose receiver", receivers);
        if (maybeReceiverWrapper.isEmpty()) {
            return;
        }

        var receiver = maybeReceiverWrapper.get().getReceiver();
        extensionHelper.sendToReceiver(
                receiver.getCode(),
                maybePdu.get().copy()
        );
    }

}
gui.ReceiverWrapper
package gui;

import com.warxim.petep.extension.receiver.Receiver;
import lombok.Value;

/**
 * Receiver wrapper for displaying receiver in dialog.
 */
@Value
class ReceiverWrapper {
    private Receiver receiver;

    @Override
    public String toString() {
        return receiver.getName() + " (" + receiver.getCode() + ")";
    }
}

Now we have to set the controller for the tab in petep.Extension:

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

It is done. Now we can run PETEP and for example by using History, we can send some serialized PDU to our receiver and view it in tab of our extension.