Let's create simple history view for brief demonstration of the history API. (We are going to show history view in our application tab.)
It is possible to do more things using History extension API, see the History guide.
We will extend our app tab to contain pane for history view.
<?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="History Test">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<AnchorPane fx:id="historyPane" layoutY="36.0" prefHeight="535.0" prefWidth="976.0" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="10.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="35.0" />
<Label layoutX="14.0" layoutY="14.0" styleClass="heading-2" text="Here you can see loaded history view:" AnchorPane.leftAnchor="10.0" AnchorPane.topAnchor="10.0" />
</children>
</AnchorPane>
</content>
</Tab>
<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>
We will also extend the controller to dynamically load the history view:
/**
* Controller for example application tab.
* <p>Loads history view into the tab content.</p>
*/
@RequiredArgsConstructor
public class ExampleAppTabController implements Initializable {
private final ExtensionHelper extensionHelper;
private final HistoryApi historyApi;
private HistoryView historyView;
@FXML
private Pane historyPane;
@FXML
private SerializedPduView serializedPduView;
@FXML
private Button sendToButton;
@Override
public void initialize(URL location, ResourceBundle resources) {
initHistoryView();
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;
}
// Obtain receivers that support serialized PDU
var receivers = extensionHelper.getReceivers(SerializedPdu.class).stream()
.map(ReceiverWrapper::new)
.collect(Collectors.toList());
// Let the user pick receiver
var maybeReceiverWrapper = Dialogs.createChoiceDialog("Send to receiver", "Choose receiver", receivers);
if (maybeReceiverWrapper.isEmpty()) {
return;
}
// Send the PDU to the receiver
var receiver = maybeReceiverWrapper.get().getReceiver();
extensionHelper.sendToReceiver(
receiver.getCode(),
maybePdu.get().copy()
);
}
/**
* Creates and loads history view into the tab.
*/
private void initHistoryView() {
if (historyApi == null) {
return;
}
// Create filter for history
var filter = HistoryFilter.builder().build();
// Create view to history
historyView = historyApi.createView(filter);
// Get JavaFX node of history view
var historyNode = historyView.getNode();
AnchorPane.setBottomAnchor(historyNode, 0.0);
AnchorPane.setTopAnchor(historyNode, 0.0);
AnchorPane.setLeftAnchor(historyNode, 0.0);
AnchorPane.setRightAnchor(historyNode, 0.0);
// Add history node to the history pane
historyPane.getChildren().add(historyNode);
}
}
To make this work, we have to get HistoryApi from History extension during load of the application and store reference to it in our extension. For this, we are going to use afterInit method in petep.Extension:
var maybeHistory = helper.getExtension("history");
if (maybeHistory.isPresent()) {
historyApi = (HistoryApi) maybeHistory.get();
}
Now we can hand over the history api reference to our controller by adding it as constructor parameter in initGui:
// Load application tab
try {
var loader = new FXMLLoader(getClass().getResource("/fxml/ExampleAppTab.fxml"));
var controller = new ExampleAppTabController(extensionHelper, historyApi);
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);
}
After starting PETEP, we should be able to see History in the application tab of our extension.