From b3a30e10d13861019ea9b5047a92da2e47f3056a Mon Sep 17 00:00:00 2001 From: Harkamal Randhawa Date: Sun, 29 Mar 2026 16:54:01 -0600 Subject: [PATCH] fix desktop pet and product dialogs --- .../org/example/petshopdesktop/Validator.java | 51 ++++++++++++++++++- .../example/petshopdesktop/api/ApiClient.java | 16 ++++-- .../PetDialogController.java | 12 ++++- .../ProductDialogController.java | 11 +++- .../util/DesktopImageSupport.java | 11 +++- .../dialogviews/pet-dialog-view.fxml | 12 ++--- .../dialogviews/product-dialog-view.fxml | 14 ++--- 7 files changed, 99 insertions(+), 28 deletions(-) diff --git a/desktop/src/main/java/org/example/petshopdesktop/Validator.java b/desktop/src/main/java/org/example/petshopdesktop/Validator.java index cf51eb1e..2940cde4 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/Validator.java +++ b/desktop/src/main/java/org/example/petshopdesktop/Validator.java @@ -44,6 +44,33 @@ public class Validator { return msg; } + /** + * Checks if the input is a positive double + * @param value input of string + * @param name name of input + * @return error msg if input is not a number or not positive, otherwise empty + */ + public static String isPositiveDouble(String value, String name){ + String msg =""; + if (value == null) { + msg += name + " must be a number.\n"; + + return msg; + } + double result; + try { + result = Double.parseDouble(value); + if (result <= 0){ + msg += name + " must be greater than 0. \n"; + } + } + catch (NumberFormatException e){ + msg += name + " must be a number.\n"; + } + + return msg; + } + /** * Checks if the input is a double in 2 different range * @param value input of string @@ -95,6 +122,28 @@ public class Validator { return msg; } + /** + * Checks if the input is a positive integer + * @param value input of string + * @param name name of input + * @return error msg if input is not a number or not positive, otherwise empty + */ + public static String isPositiveInteger(String value, String name){ + String msg =""; + int result; + try { + result = Integer.parseInt(value); + if (result <= 0){ + msg += name + " must be greater than 0. \n"; + } + } + catch (NumberFormatException e){ + msg += name + " must be a whole number.\n"; + } + + return msg; + } + /** * check if the string is a given amount of characters or fewer * @param value input of string @@ -154,4 +203,4 @@ public class Validator { return msg; } -} \ No newline at end of file +} diff --git a/desktop/src/main/java/org/example/petshopdesktop/api/ApiClient.java b/desktop/src/main/java/org/example/petshopdesktop/api/ApiClient.java index d6b48d21..3914d226 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/api/ApiClient.java +++ b/desktop/src/main/java/org/example/petshopdesktop/api/ApiClient.java @@ -224,15 +224,21 @@ public class ApiClient { try { if (response.body() != null && !response.body().isEmpty()) { var errorNode = objectMapper.readTree(response.body()); - if (errorNode.has("message")) { - return errorNode.get("message").asText(); - } if (errorNode.has("errors")) { StringBuilder sb = new StringBuilder(); errorNode.get("errors").fields().forEachRemaining(entry -> { - sb.append(entry.getValue().asText()).append("\n"); + String errorText = entry.getValue().asText(); + if (errorText != null && !errorText.isBlank()) { + sb.append(errorText).append("\n"); + } }); - return sb.toString().trim(); + if (sb.length() > 0) { + String message = errorNode.has("message") ? errorNode.get("message").asText() : null; + return (message != null && !message.isBlank() ? message + "\n" : "") + sb.toString().trim(); + } + } + if (errorNode.has("message")) { + return errorNode.get("message").asText(); } } } catch (Exception e) { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java index 3ebcfa5b..78ad836a 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/PetDialogController.java @@ -20,6 +20,7 @@ import org.example.petshopdesktop.util.FilePickerSupport; import java.io.File; import java.math.BigDecimal; + public class PetDialogController { @FXML @@ -120,7 +121,7 @@ public class PetDialogController { //Check validation (format) errorMsg += Validator.isNonNegativeDouble(txtPetPrice.getText(), "Price"); - errorMsg += Validator.isNonNegativeInteger(txtPetAge.getText(), "Age"); + errorMsg += Validator.isPositiveInteger(txtPetAge.getText(), "Age"); if(errorMsg.isEmpty()){ PetRequest request = buildPetRequest(); @@ -252,6 +253,7 @@ public class PetDialogController { } private void applyImageChanges(Long petId) throws Exception { + String previousImageUrl = currentImageUrl; if (removeImageRequested) { try { PetApi.getInstance().deletePetImage(petId); @@ -260,7 +262,15 @@ public class PetDialogController { } if (selectedImageFile != null) { PetApi.getInstance().uploadPetImage(petId, selectedImageFile.toPath()); + currentImageUrl = "/api/v1/pets/" + petId + "/image"; + } else if (removeImageRequested) { + currentImageUrl = null; } + DesktopImageSupport.evict(previousImageUrl); + DesktopImageSupport.evict(currentImageUrl); + selectedImageFile = null; + removeImageRequested = false; + refreshImagePreview(); } private void refreshImagePreview() { diff --git a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java index 796a8019..7b354a9d 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java +++ b/desktop/src/main/java/org/example/petshopdesktop/controllers/dialogcontrollers/ProductDialogController.java @@ -130,7 +130,7 @@ public class ProductDialogController { errorMsg += Validator.isLessThanVarChars(txtProdPrice.getText(), "Product Price", 12); //Check Validation (format) - errorMsg += Validator.isNonNegativeDouble(txtProdPrice.getText(), "Product Price"); + errorMsg += Validator.isPositiveDouble(txtProdPrice.getText(), "Product Price"); if (errorMsg.isEmpty()) { try { @@ -258,6 +258,7 @@ public class ProductDialogController { } private void applyImageChanges(Long productId) throws Exception { + String previousImageUrl = currentImageUrl; if (removeImageRequested) { try { ProductApi.getInstance().deleteProductImage(productId); @@ -266,7 +267,15 @@ public class ProductDialogController { } if (selectedImageFile != null) { ProductApi.getInstance().uploadProductImage(productId, selectedImageFile.toPath()); + currentImageUrl = "/api/v1/products/" + productId + "/image"; + } else if (removeImageRequested) { + currentImageUrl = null; } + DesktopImageSupport.evict(previousImageUrl); + DesktopImageSupport.evict(currentImageUrl); + selectedImageFile = null; + removeImageRequested = false; + refreshImagePreview(); } private void refreshImagePreview() { diff --git a/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java b/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java index f4347a1e..59cbcb98 100644 --- a/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java +++ b/desktop/src/main/java/org/example/petshopdesktop/util/DesktopImageSupport.java @@ -20,12 +20,21 @@ public final class DesktopImageSupport { imageView.setFitWidth(width); imageView.setFitHeight(height); imageView.setPreserveRatio(true); + imageView.setSmooth(true); imageView.setImage(null); if (imageUrl == null || imageUrl.isBlank()) { return; } + if (imageUrl.startsWith("file:")) { + Image image = new Image(imageUrl, 0, 0, true, true); + if (!image.isError()) { + imageView.setImage(image); + } + return; + } + Image cached = IMAGE_CACHE.get(imageUrl); if (cached != null) { imageView.setImage(cached); @@ -35,7 +44,7 @@ public final class DesktopImageSupport { new Thread(() -> { try { byte[] bytes = ApiClient.getInstance().getBytes(imageUrl); - Image image = new Image(new ByteArrayInputStream(bytes), width, height, true, true); + Image image = new Image(new ByteArrayInputStream(bytes)); if (!image.isError()) { IMAGE_CACHE.put(imageUrl, image); Platform.runLater(() -> imageView.setImage(image)); diff --git a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml index 781caeb9..2f5bd110 100644 --- a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml +++ b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/pet-dialog-view.fxml @@ -10,11 +10,10 @@ - - + @@ -63,18 +62,13 @@ - + - + - - - - - diff --git a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml index 2ed33051..47c2a7c2 100644 --- a/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml +++ b/desktop/src/main/resources/org/example/petshopdesktop/dialogviews/product-dialog-view.fxml @@ -10,11 +10,10 @@ - - + @@ -63,19 +62,14 @@ - + - + - - - - - - +