JavaFX SchulController refactoring, validation best practices, and code structure

Kai Smith 0 Zuverlässigkeitspunkte
2026-11-04T12:02:06.9833333+00:00

I am currently working on a JavaFX application for school management (Schulverwaltung). I have written a Controller class (SchulController) that handles UI interactions, validates text input fields for first names, last names, postal codes, and roles (such as teacher or student), and updates both a ListView and a statistics label.

While the code is currently functional, I have several concerns regarding code quality, maintainability, and best practices in Java / JavaFX. I would appreciate some advice from the community on how to improve this. And please excuse the weird names of the methods, they are german.

My specific questions: Input Validation and Regex: In the onHinzufuegen() method, I am iterating over the characters of the first and last name to check if they only contain letters, spaces, or hyphens. Is there a cleaner, more idiomatic way to achieve this using Regular Expressions (Pattern / Matcher) or JavaFX TextFormatter?

Method Complexity and Refactoring: The onHinzufuegen() method has grown quite large and contains deep nested if-else statements. What is the best way to extract this validation and object creation logic into smaller, helper methods without breaking the JavaFX binding or event-handling structure?

Separation of Concerns: Should the validation logic (like checking the length of postal codes or role restrictions) reside directly inside the JavaFX Controller, or should it be delegated to a model/service layer? If so, how should errors be communicated back to the UI to display alerts properly?

Thank you very much in advance for your help! Here is my complete, unedited code:


public class SchulController {

    @FXML
    private RadioButton schuelerRadioButton;

    @FXML
    private RadioButton lehrerRadioButton;

    @FXML
    private TextField vornameField;

    @FXML
    private TextField nachnameField;

    @FXML
    private TextField rolleField;

    @FXML
    private TextField strasseField;

    @FXML
    private TextField plzField;

    @FXML
    private TextField ortField;

    @FXML
    private Label rolleLabel;

    @FXML
    private ListView<String> personenListView;

    @FXML
    private Label statistikLabel;



    Schule schule = new Schule();

    Adresse adresse = new Adresse("abc", 1234 , "abc");
    Schueler schueler1 = new Schueler("willy", "wonka1",adresse , "123" );
    Schueler schueler2 = new Schueler("willy", "wonka2",adresse , "123" );

    Lehrer lehrer = new Lehrer("Willfried", "Unterrainer", adresse, "WSRU");



    @FXML
    public void initialize() {
        IO.println("SchulverwaltungController initialized");


        schule.personhinzufuegen(schueler1);
        schule.personhinzufuegen(schueler2);
        schule.personhinzufuegen(lehrer);
        IO.println(lehrer.toString());
        personenListView.getItems().add(lehrer.toString());
        personenListView.getItems().add(schueler1.toString());
        personenListView.getItems().add(schueler2.toString());
        statistikAktualisieren();
    }

    @FXML
    protected void onRolleGeaendert() {

        if(lehrerRadioButton.isSelected())
        {
            rolleLabel.setText("Kürzel:");
            rolleField.setPromptText("z.B JJWU");
        }
        else
        {
            rolleLabel.setText("Klasse:");
            rolleField.setPromptText("z.B 3AHINF");
        }
    }



    @FXML
    protected void onHinzufuegen() {

        Alert alert = new Alert(Alert.AlertType.ERROR);


        if(vornameField.getText().isEmpty() || nachnameField.getText().isEmpty())
        {
            showAlert("Vornamefeld oder Nachnamefeld ist leer");
            return;
        }

        String vorname = vornameField.getText();

        for (int i = 0; i < vorname.length(); i++) {

            char zeichen = vorname.charAt(i);

            if (!Character.isLetter(zeichen)
                    && zeichen != ' '
                    && zeichen != '-') {

                showAlert("Vorname ist inkompatibel");
                return;
            }
        }

        String nachname = nachnameField.getText();

        for (int i = 0; i < nachname.length(); i++) {

            char zeichen = nachname.charAt(i);

            if (!Character.isLetter(zeichen)
                    && zeichen != ' '
                    && zeichen != '-') {

                showAlert("Nachname ist inkompatibel");
                return;
            }
        }


        if(strasseField.getText().isEmpty() || ortField.getText().isEmpty())
        {
            showAlert("Straße ist falsch");
            return;
        }

        if(plzField.getText().length() != 4)
        {
            showAlert("Postleitzahl ist falsch");
            return;
        }

        if(Objects.equals(rolleLabel.getText(), "Klasse:"))
        {
            if(rolleField.getText().length() < 2 || rolleField.getText().length() > 6)
            {
                showAlert("Rolle ist falsch");
                return;
            }

            char[] zeichen = rolleField.getText().toCharArray();

            if(Character.isDigit(zeichen[0]))
            {
                int erste_zahl = Integer.parseInt(String.valueOf(zeichen[0]));

                if(erste_zahl > 5 || erste_zahl < 1)
                {
                    showAlert("Kein zeichen");
                    return;
                }
            }

            Adresse adresse = new Adresse(strasseField.getText(),Integer.parseInt(plzField.getText()), ortField.getText());
            Schueler schueler = new Schueler(vornameField.getText(), nachnameField.getText(), adresse, rolleLabel.getText());
            schule.personhinzufuegen(schueler);
            statistikAktualisieren();
            personenListView.getItems().add(schueler.toString());

        } else if (rolleField.getText().length() < 2 && rolleField.getText().length() > 4) {
            showAlert("Es dürfen zwischen 2-4 Zeichen verwendet werden!");
            return;
        }
        else
        {
            Adresse adresse = new Adresse(strasseField.getText(),Integer.parseInt(plzField.getText()), ortField.getText());
            Lehrer lehrer = new Lehrer(vornameField.getText(), nachnameField.getText(), adresse, rolleLabel.getText());
            schule.personhinzufuegen(lehrer);
            statistikAktualisieren();
            personenListView.getItems().add(lehrer.toString());
        }



    }

    private void showAlert(String text) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("Achtung!");
        alert.setHeaderText((String)null);
        alert.setContentText(text);
        alert.showAndWait();
    }

    @FXML
    protected void onFelderLeeren() {
        personenListView.getItems().clear();
        schule.personenLeeren();
        statistikAktualisieren();
    }

    private void statistikAktualisieren() {
        statistikLabel.setText(
                "Schüler/innen: " + schule.getAnzahlSchueler()
                        + " | Lehrer/innen: " + schule.getAnzahlLehrer()
        );
    }

}
Entwicklertechnologien | Visual Studio | Andere
Entwicklertechnologien | Visual Studio | Andere

Eine Familie von Microsoft-Suiten integrierter Entwicklungstools zum Erstellen von Anwendungen für Windows, das Web, mobile Geräte und viele andere Plattformen. Verschiedene Themen, die nicht in bestimmte Kategorien passen.

0 Kommentare Keine Kommentare

Ihre Antwort

Antworten können von Fragestellenden als „Angenommen“ und von Moderierenden als „Empfohlen“ gekennzeichnet werden, wodurch Benutzende wissen, dass diese Antwort das Problem des Fragestellenden gelöst hat.