From 72d87a894ec8538f0f1a71830505a78ca7c5680b Mon Sep 17 00:00:00 2001 From: Jonas Hinterdorfer Date: Wed, 23 Apr 2025 18:56:20 +0200 Subject: [PATCH] implemented controller repo and model --- .../controller/AddressBookController.java | 93 +++++++++++++++++-- .../ionas999/adressbook/models/Contact.java | 59 ++++++++++++ .../adressbook/repository/AddressBook.java | 40 ++++++++ src/main/java/module-info.java | 4 +- 4 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 src/main/java/at/ionas999/adressbook/models/Contact.java create mode 100644 src/main/java/at/ionas999/adressbook/repository/AddressBook.java diff --git a/src/main/java/at/ionas999/adressbook/controller/AddressBookController.java b/src/main/java/at/ionas999/adressbook/controller/AddressBookController.java index daa3697..88910df 100644 --- a/src/main/java/at/ionas999/adressbook/controller/AddressBookController.java +++ b/src/main/java/at/ionas999/adressbook/controller/AddressBookController.java @@ -1,10 +1,15 @@ package at.ionas999.adressbook.controller; +import at.ionas999.adressbook.models.Contact; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.collections.transformation.FilteredList; import javafx.event.ActionEvent; -import javafx.scene.control.Button; -import javafx.scene.control.Label; -import javafx.scene.control.ListView; -import javafx.scene.control.TextField; +import javafx.scene.control.*; +import javafx.scene.control.Alert.AlertType; + +import java.util.function.Predicate; public class AddressBookController { public TextField searchBox; @@ -13,19 +18,91 @@ public class AddressBookController { public TextField phoneField; public TextField emailField; public Label labelContactAmount; - public ListView contactView; + public ListView contactView; public Button searchButton; - public void searchButtonClickEvent(ActionEvent actionEvent) { + private final ObservableList contacts = FXCollections.observableArrayList(); + private final FilteredList filteredContacts = new FilteredList<>(contacts); + + public void initialize() { + contactView.setItems(filteredContacts); + + contacts.addListener((ListChangeListener) (observable) -> updateContactCount()); + updateContactCount(); + } + + private Predicate createFilterPredicate(String searchText) { + if (searchText == null || searchText.isBlank()) { + return contact -> true; + } + String lowerCaseSearchText = searchText.toLowerCase(); + return contact -> contact.getName().toLowerCase().contains(lowerCaseSearchText) || + contact.getEmail().toLowerCase().contains(lowerCaseSearchText); + } + + private void updateContactCount() { + labelContactAmount.setText("Contacts: " + contacts.size()); } public void addContactButtonClickEvent(ActionEvent actionEvent) { - + try { + String name = nameField.getText(); + String phone = phoneField.getText(); + String email = emailField.getText(); + Contact newContact = new Contact(name, phone, email); + contacts.add(newContact); + clearInputFields(); + } catch (IllegalArgumentException e) { + showAlert("Error", e.getMessage()); + } } public void deleteContactButtonClickEvent(ActionEvent actionEvent) { + Contact selectedContact = contactView.getSelectionModel().getSelectedItem(); + if (selectedContact != null) { + contacts.remove(selectedContact); + } else { + showAlert("Error", "No contact selected for deletion."); + } } public void saveButtonClickEvent(ActionEvent actionEvent) { + Contact selectedContact = contactView.getSelectionModel().getSelectedItem(); + if (selectedContact != null) { + try { + selectedContact.setName(nameField.getText()); + selectedContact.setPhone(phoneField.getText()); + selectedContact.setEmail(emailField.getText()); + refreshListView(); + } catch (IllegalArgumentException e) { + showAlert("Error", e.getMessage()); + } + } else { + showAlert("Error", "No contact selected for saving."); + } } -} + + public void searchButtonClickEvent(ActionEvent actionEvent) { + String searchText = searchBox.getText(); + filteredContacts.setPredicate(createFilterPredicate(searchText)); + } + + private void refreshListView() { + contactView.setItems(null); + contactView.setItems(filteredContacts); + } + + private void clearInputFields() { + idField.clear(); + nameField.clear(); + phoneField.clear(); + emailField.clear(); + } + + private void showAlert(String title, String message) { + Alert alert = new Alert(AlertType.ERROR); + alert.setTitle(title); + alert.setContentText(message); + alert.showAndWait(); + } +} \ No newline at end of file diff --git a/src/main/java/at/ionas999/adressbook/models/Contact.java b/src/main/java/at/ionas999/adressbook/models/Contact.java new file mode 100644 index 0000000..580bccf --- /dev/null +++ b/src/main/java/at/ionas999/adressbook/models/Contact.java @@ -0,0 +1,59 @@ +package at.ionas999.adressbook.models; + +import java.util.regex.Pattern; + +public class Contact { + private static int contactCounter = 0; + private static final Pattern emailPattern = Pattern.compile("^[\\w.%+-]+@[\\w.-]+\\.[a-zA-Z]{2,}$"); + private static final Pattern phonePattern = Pattern.compile("^\\+?[0-9-]+$"); + + private final int id = Contact.contactCounter++; + private String name; + private String phone; + private String email; + + public Contact(String name, String phone, String email) { + this.setEmail(email); + this.setName(name); + this.setPhone(phone); + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public String getPhone() { + return phone; + } + + public String getEmail() { + return email; + } + + public void setName(String name) { + this.name = name; + } + + public void setPhone(String phone) { + if (!phonePattern.matcher(phone).matches()) { + throw new IllegalArgumentException("Invalid phone number format"); + } + this.phone = phone; + } + + public void setEmail(String email) { + if (!emailPattern.matcher(email).matches()) { + throw new IllegalArgumentException("Invalid email address format"); + } + this.email = email; + } + @Override + public String toString() + { + return this.name; + } +} diff --git a/src/main/java/at/ionas999/adressbook/repository/AddressBook.java b/src/main/java/at/ionas999/adressbook/repository/AddressBook.java new file mode 100644 index 0000000..f7d8812 --- /dev/null +++ b/src/main/java/at/ionas999/adressbook/repository/AddressBook.java @@ -0,0 +1,40 @@ +package at.ionas999.adressbook.repository; + +import at.ionas999.adressbook.models.Contact; +import javafx.beans.property.SimpleIntegerProperty; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; + +public class AddressBook { + private static AddressBook instance; + private ObservableList list; + + private AddressBook() { + list = FXCollections.observableArrayList(); + } + + public static AddressBook getInstance() { + if (AddressBook.instance == null) { + AddressBook.instance = new AddressBook(); + } + return instance; + } + + public ObservableList getContacts() { + return FXCollections.unmodifiableObservableList(list); + } + + public void addContact(Contact contact) { + list.add(contact); + } + + public void removeContact(Contact contact) { + list.remove(contact); + } + + public SimpleIntegerProperty getAmount() { + SimpleIntegerProperty amount = new SimpleIntegerProperty(); + amount.bind(javafx.beans.binding.Bindings.size(list)); + return amount; + } +} \ No newline at end of file diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 9dedbdb..5163b7d 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -2,7 +2,7 @@ module at.ionas999.adressbook { requires javafx.controls; requires javafx.fxml; - opens at.ionas999.adressbook to javafx.fxml; + opens at.ionas999.adressbook.controller to javafx.fxml; + exports at.ionas999.adressbook; - exports at.ionas999.adressbook.controller to javafx.fxml; } \ No newline at end of file