diff --git a/src/main/java/name/nathanmcrae/numbersstation/AddPrefixController.java b/src/main/java/name/nathanmcrae/numbersstation/AddPrefixController.java
new file mode 100644
index 0000000..8ffcc21
--- /dev/null
+++ b/src/main/java/name/nathanmcrae/numbersstation/AddPrefixController.java
@@ -0,0 +1,145 @@
+    package name.nathanmcrae.numbersstation;
+
+    import java.lang.StringBuilder;
+    import javafx.application.Platform;
+    import javafx.fxml.FXML;
+    import javafx.scene.control.Button;
+    import javafx.scene.control.TextField;
+    import javafx.stage.Stage;
+    import javafx.scene.input.KeyCode;
+    import javafx.scene.input.KeyEvent;
+
+    public class AddPrefixController {
+        @FXML
+        private TextField prefixField;
+
+        @FXML
+        private Button okButton;
+
+        @FXML
+        private Button cancelButton;
+
+        private int digitsPerGroup;
+        private MainSettingsController mainSettingsController;
+
+        public void setDigitsPerGroup(int newDigitsPerGroup) {
+            digitsPerGroup = newDigitsPerGroup;
+        }
+
+        public void setMainSettingsController(MainSettingsController mainSettingsController) {
+            this.mainSettingsController = mainSettingsController;
+        }
+
+        @FXML
+        private void initialize() {
+            okButton.setOnAction(event -> handleOkButtonPress());
+            cancelButton.setOnAction(event -> handleCancelButtonPress());
+
+            // Set focus on the text field when the window is shown
+            Platform.runLater(() -> prefixField.requestFocus());
+
+            // Add event filter to handle Enter key press
+            prefixField.addEventFilter(KeyEvent.ANY, event -> {
+                if (event.getCode() == KeyCode.ENTER) {
+                    handleOkButtonPress();
+                    event.consume();
+                }
+
+                int cursorPosition = prefixField.getCaretPosition();
+
+                String character = event.getCharacter();
+                KeyCode code = event.getCode();
+
+                String str = event.getText();
+
+                // Consume the event to block the default behavior
+                if (!(code == KeyCode.DOWN ||
+                      code == KeyCode.END ||
+                      code == KeyCode.HOME ||
+                      code == KeyCode.LEFT ||
+                      code == KeyCode.PAGE_DOWN ||
+                      code == KeyCode.PAGE_UP ||
+                      code == KeyCode.RIGHT ||
+                      code == KeyCode.UP)) {
+                    event.consume();
+                }
+
+                if (event.getEventType() == KeyEvent.KEY_PRESSED &&
+                    (code == KeyCode.BACK_SPACE ||
+                     code == KeyCode.DELETE)) {
+
+                    String newText = prefixField.getText();
+                    if (code == KeyCode.BACK_SPACE) {
+                        newText = (newText.substring(0, cursorPosition - 1) + newText.substring(cursorPosition)).replaceAll(" ", "");
+                    }
+                    else if (code == KeyCode.DELETE) {
+                        newText = (newText.substring(0, cursorPosition) + newText.substring(cursorPosition + 1)).replaceAll(" ", "");
+                    }
+
+                    StringBuilder sb = new StringBuilder();
+
+                    for (int i = 0; i < newText.length(); i++) {
+                        sb.append(newText.charAt(i));
+                        if ((i + 1) % (digitsPerGroup) == 0) {
+                            sb.append(' ');
+                        }
+                    }
+
+                    prefixField.setText(sb.toString());
+                    if (code == KeyCode.BACK_SPACE) {
+                        prefixField.positionCaret(cursorPosition - 1);
+                    } else if (code == KeyCode.DELETE) {
+                        prefixField.positionCaret(cursorPosition);
+                    }
+                 }
+
+                if (event.getEventType() == KeyEvent.KEY_PRESSED &&
+                    (code == KeyCode.DIGIT0 ||
+                     code == KeyCode.DIGIT1 ||
+                     code == KeyCode.DIGIT2 ||
+                     code == KeyCode.DIGIT3 ||
+                     code == KeyCode.DIGIT4 ||
+                     code == KeyCode.DIGIT5 ||
+                     code == KeyCode.DIGIT6 ||
+                     code == KeyCode.DIGIT7 ||
+                     code == KeyCode.DIGIT8 ||
+                     code == KeyCode.DIGIT9)) {
+
+                    String newText = prefixField.getText().substring(0, cursorPosition) + str + prefixField.getText().substring(cursorPosition);
+                    newText = newText.replaceAll(" ", "");
+
+                    StringBuilder sb = new StringBuilder();
+
+                    for (int i = 0; i < newText.length(); i++) {
+                        sb.append(newText.charAt(i));
+                        if ((i + 1) % (digitsPerGroup) == 0) {
+                            sb.append(' ');
+                        }
+                    }
+
+                    prefixField.setText(sb.toString());
+                    if (prefixField.getText().charAt(cursorPosition) == ' ') {
+                        cursorPosition++;
+                    }
+                    prefixField.positionCaret(cursorPosition + 1);
+                }
+            });
+        }
+
+        private void handleOkButtonPress() {
+            String prefix = prefixField.getText();
+            if (prefix != null && !prefix.isEmpty()) {
+                mainSettingsController.addPrefix(prefix.replaceAll(" ", ""));
+                closeWindow();
+            }
+        }
+
+        private void handleCancelButtonPress() {
+            closeWindow();
+        }
+
+        private void closeWindow() {
+            Stage stage = (Stage) okButton.getScene().getWindow();
+            stage.close();
+        }
+    }
diff --git a/src/main/java/name/nathanmcrae/numbersstation/AddPrefixView.fxml b/src/main/java/name/nathanmcrae/numbersstation/AddPrefixView.fxml
new file mode 100644
index 0000000..6160948
--- /dev/null
+++ b/src/main/java/name/nathanmcrae/numbersstation/AddPrefixView.fxml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.control.TextField?>
+<?import javafx.scene.layout.AnchorPane?>
+<?import javafx.scene.layout.VBox?>
+
+<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="92.0" prefWidth="312.0" xmlns="http://javafx.com/javafx/23.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="name.nathanmcrae.numbersstation.AddPrefixController">
+   <children>
+      <AnchorPane prefHeight="200.0" prefWidth="312.0">
+         <children>
+            <Button fx:id="okButton" layoutX="89.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="OK" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="89.0" />
+            <Button fx:id="cancelButton" layoutX="169.0" layoutY="67.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="65.0" text="Cancel" AnchorPane.bottomAnchor="15.0" AnchorPane.rightAnchor="9.0" />
+            <Label layoutX="14.0" layoutY="14.0" text="Enter a message prefix / identifier:" />
+            <TextField fx:id="prefixField" layoutX="203.0" layoutY="10.0" prefHeight="25.0" prefWidth="105.0" AnchorPane.leftAnchor="203.0" AnchorPane.rightAnchor="10.0" />
+         </children>
+      </AnchorPane>
+   </children>
+</VBox>
diff --git a/src/main/java/name/nathanmcrae/numbersstation/MainSettingsController.java b/src/main/java/name/nathanmcrae/numbersstation/MainSettingsController.java
index cc7e242..d33a42b 100644
--- a/src/main/java/name/nathanmcrae/numbersstation/MainSettingsController.java
+++ b/src/main/java/name/nathanmcrae/numbersstation/MainSettingsController.java
@@ -21,8 +21,10 @@ import javafx.collections.FXCollections;
 import javafx.collections.ObservableList;
 import javafx.event.Event;
 import javafx.fxml.FXML;
+import javafx.fxml.FXMLLoader;
 import javafx.scene.control.CheckBox;
 import javafx.scene.control.DatePicker;
+import javafx.scene.control.ListCell;
 import javafx.scene.control.ListView;
 import javafx.scene.control.RadioButton;
 import javafx.scene.control.Spinner;
@@ -33,7 +35,11 @@ import javafx.scene.control.ToggleGroup;
 import javafx.scene.input.KeyEvent;
 import javafx.scene.input.KeyCode;
 import javafx.scene.Node;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.stage.Modality;
 import javafx.stage.Stage;
+import javafx.util.Callback;
 
 public class MainSettingsController {
     private IntegerProperty digitsPerGroup = new SimpleIntegerProperty();
@@ -278,19 +284,59 @@ public class MainSettingsController {
                 stage.setUserData(false);
             }
         });
+
+        prefixListView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
+            @Override
+            public ListCell<String> call(ListView<String> listView) {
+                return new ListCell<String>() {
+                    @Override
+                    protected void updateItem(String item, boolean empty) {
+                        super.updateItem(item, empty);
+                        if (empty || item == null) {
+                            setText(null);
+                        } else {
+
+                            String newText = item.replaceAll(" ", "");
+                            StringBuilder sb = new StringBuilder();
+
+                            for (int i = 0; i < newText.length(); i++) {
+                                sb.append(newText.charAt(i));
+                                if ((i + 1) % (digitsPerGroup.get()) == 0) {
+                                    sb.append(' ');
+                                }
+                            }
+                            setText(sb.toString());
+                        }
+                    }
+                };
+            }
+        });
     }
 
     @FXML
     private void handleAddPrefixButtonPress() {
-        TextInputDialog dialog = new TextInputDialog();
-        dialog.setTitle("New prefix");
-        dialog.setHeaderText("Add a new prefix");
-        dialog.setContentText("Enter a message prefix / identifier:");
+        try {
+            FXMLLoader loader = new FXMLLoader(getClass().getResource("AddPrefixView.fxml"));
+            Parent root = loader.load();
 
-        Optional<String> result = dialog.showAndWait();
-        result.ifPresent(prefix -> {
+            AddPrefixController controller = loader.getController();
+            controller.setMainSettingsController(this);
+            controller.setDigitsPerGroup(settings.getDigitsPerGroup());
+
+            Stage stage = new Stage();
+            stage.setTitle("New prefix");
+            stage.setScene(new Scene(root));
+            stage.initModality(Modality.APPLICATION_MODAL);
+            stage.showAndWait();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void addPrefix(String prefix) {
+        if (!(prefix == null || prefix.isEmpty())) {
             prefixListView.getItems().add(prefix);
-        });
+        }
     }
 
     @FXML