fix desktop pet and product dialogs
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
@@ -63,18 +62,13 @@
|
||||
<Insets left="15.0" right="15.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<VBox prefHeight="370.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||
<VBox prefHeight="405.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||
<children>
|
||||
<GridPane hgap="25.0" VBox.vgrow="ALWAYS">
|
||||
<GridPane hgap="25.0" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
||||
<children>
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="560.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
@@ -63,19 +62,14 @@
|
||||
<Insets left="15.0" right="15.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<VBox prefHeight="370.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||
<VBox prefHeight="405.0" prefWidth="750.0" style="-fx-background-color: white; -fx-background-radius: 14; -fx-border-width: 2; -fx-border-color: #5580b5; -fx-border-radius: 14;">
|
||||
<children>
|
||||
<GridPane hgap="25.0" VBox.vgrow="ALWAYS">
|
||||
<GridPane hgap="25.0" vgap="10.0">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<children>
|
||||
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0">
|
||||
<children>
|
||||
<Label text="Product Name:" textFill="#2c3e50">
|
||||
|
||||
Reference in New Issue
Block a user