Add multi-row selection and deletion to all tables

This commit is contained in:
2026-02-25 10:08:47 -07:00
parent 13684f97de
commit 96b50a21be
8 changed files with 427 additions and 278 deletions

View File

@@ -62,6 +62,8 @@ public class AdoptionController {
void initialize() { void initialize() {
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvAdoptions.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colAdoptionId.setCellValueFactory(new PropertyValueFactory<>("adoptionId")); colAdoptionId.setCellValueFactory(new PropertyValueFactory<>("adoptionId"));
colPetId.setCellValueFactory(new PropertyValueFactory<>("petId")); colPetId.setCellValueFactory(new PropertyValueFactory<>("petId"));
@@ -100,54 +102,71 @@ public class AdoptionController {
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected adoptions
Adoption selectedAdoption = tvAdoptions.getSelectionModel().getSelectedItem(); var selectedAdoptions = tvAdoptions.getSelectionModel().getSelectedItems();
if (selectedAdoptions.isEmpty()) return;
//ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this adoption record?"); String message = selectedAdoptions.size() == 1
? "Are you sure you want to delete this adoption record?"
: "Are you sure you want to delete " + selectedAdoptions.size() + " adoption records?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); Optional<ButtonType> result = question.showAndWait();
//if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) { if (result.isPresent() && result.get() == ButtonType.OK) {
int adoptionId = selectedAdoption.getAdoptionId(); int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
try { for (Adoption adoption : selectedAdoptions) {
numRows = AdoptionDB.deleteAdoption(adoptionId); try {
} int numRows = AdoptionDB.deleteAdoption(adoption.getAdoptionId());
catch (SQLIntegrityConstraintViolationException e) { if (numRows > 0) {
ActivityLogger.getInstance().logException( successCount++;
"AdoptionController.btnDeleteClicked", } else {
e, failCount++;
"Deleting adoption (integrity constraint violation) with ID: " + adoptionId); }
Alert alert = new Alert(Alert.AlertType.ERROR); }
alert.setHeaderText("Database Operation Error"); catch (SQLIntegrityConstraintViolationException e) {
alert.setContentText("Delete failed\nThe selected adoption is being referred in another table"); ActivityLogger.getInstance().logException(
alert.showAndWait(); "AdoptionController.btnDeleteClicked",
return; e,
} catch (SQLException e) { String.format("Attempting to delete adoption ID %d - foreign key constraint", adoption.getAdoptionId()));
ActivityLogger.getInstance().logException( failCount++;
"AdoptionController.btnDeleteClicked", errors.append("Adoption ID ").append(adoption.getAdoptionId()).append(" is referenced in another table\n");
e, } catch (SQLException e) {
"Deleting adoption with ID: " + adoptionId); ActivityLogger.getInstance().logException(
throw new RuntimeException(e); "AdoptionController.btnDeleteClicked",
e,
String.format("Attempting to delete adoption ID %d", adoption.getAdoptionId()));
failCount++;
errors.append("Failed to delete adoption ID ").append(adoption.getAdoptionId()).append("\n");
}
} }
if (numRows == 0) { //show results
Alert alert = new Alert(Alert.AlertType.ERROR); if (failCount > 0) {
alert.setHeaderText("Database Operation Error"); Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setContentText("Delete failed"); alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait(); alert.showAndWait();
} else { } else if (successCount > 0) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION); Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " adoption record(s)");
alert.showAndWait(); alert.showAndWait();
displayAdoptions();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displayAdoptions();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }

View File

@@ -40,6 +40,8 @@ public class AppointmentController {
@FXML @FXML
public void initialize(){ public void initialize(){
//Enable multiple selection
tvAppointments.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colAppointmentId.setCellValueFactory(new PropertyValueFactory<>("appointmentId")); colAppointmentId.setCellValueFactory(new PropertyValueFactory<>("appointmentId"));
colPetName.setCellValueFactory(new PropertyValueFactory<>("petName")); colPetName.setCellValueFactory(new PropertyValueFactory<>("petName"));
@@ -127,21 +129,56 @@ public class AppointmentController {
@FXML @FXML
void btnDeleteClicked(ActionEvent event){ void btnDeleteClicked(ActionEvent event){
//get selected appointments
var selectedAppointments = tvAppointments.getSelectionModel().getSelectedItems();
if (selectedAppointments.isEmpty()) return;
AppointmentDTO selected = //ask user to confirm
tvAppointments.getSelectionModel().getSelectedItem(); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete");
String message = selectedAppointments.size() == 1
? "Are you sure you want to delete this appointment?"
: "Are you sure you want to delete " + selectedAppointments.size() + " appointments?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
java.util.Optional<ButtonType> result = question.showAndWait();
if(selected == null) return; //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) {
int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
try{ for (AppointmentDTO appointment : selectedAppointments) {
AppointmentDB.deleteAppointment(selected.getAppointmentId()); try{
AppointmentDB.deleteAppointment(appointment.getAppointmentId());
successCount++;
}catch(Exception e){
ActivityLogger.getInstance().logException(
"AppointmentController.btnDeleteClicked",
e,
String.format("Attempting to delete appointment ID %d", appointment.getAppointmentId()));
failCount++;
errors.append("Failed to delete appointment ID ").append(appointment.getAppointmentId()).append("\n");
}
}
//show results
if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait();
} else if (successCount > 0) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Successfully deleted " + successCount + " appointment(s)");
alert.showAndWait();
}
//refresh display
loadAppointments(); loadAppointments();
}catch(Exception e){
ActivityLogger.getInstance().logException(
"AppointmentController.btnDeleteClicked",
e,
"Deleting appointment with ID: " + selected.getAppointmentId());
e.printStackTrace();
} }
} }

View File

@@ -61,6 +61,8 @@ public class InventoryController {
//Buttons disabled until row is selected //Buttons disabled until row is selected
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvInventory.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colInventoryId.setCellValueFactory(new PropertyValueFactory<>("inventoryId")); colInventoryId.setCellValueFactory(new PropertyValueFactory<>("inventoryId"));
colProductId.setCellValueFactory(new PropertyValueFactory<>("prodId")); colProductId.setCellValueFactory(new PropertyValueFactory<>("prodId"));
@@ -101,64 +103,72 @@ public class InventoryController {
//Prompts user for confirmation prior to deletion //Prompts user for confirmation prior to deletion
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected inventory records
Inventory selectedInventory = tvInventory.getSelectionModel().getSelectedItem(); var selectedInventory = tvInventory.getSelectionModel().getSelectedItems();
if (selectedInventory.isEmpty()) return;
//Confirmation popup //ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this inventory record?"); String message = selectedInventory.size() == 1
? "Are you sure you want to delete this inventory record?"
: "Are you sure you want to delete " + selectedInventory.size() + " inventory records?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); Optional<ButtonType> result = question.showAndWait();
//If user confirms, proceed with trying to delete... //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) { if (result.isPresent() && result.get() == ButtonType.OK) {
int inventoryId = selectedInventory.getInventoryId(); int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
try { for (Inventory inventory : selectedInventory) {
numRows = InventoryDB.deleteInventory(inventoryId); try {
int numRows = InventoryDB.deleteInventory(inventory.getInventoryId());
if (numRows > 0) {
successCount++;
} else {
failCount++;
}
}
catch (SQLIntegrityConstraintViolationException e) {
ActivityLogger.getInstance().logException(
"InventoryController.btnDeleteClicked",
e,
String.format("Attempting to delete inventory ID %d - foreign key constraint", inventory.getInventoryId()));
failCount++;
errors.append("Inventory record '").append(inventory.getProdName()).append("' is referenced in another table\n");
}
catch (SQLException e) {
ActivityLogger.getInstance().logException(
"InventoryController.btnDeleteClicked",
e,
String.format("Attempting to delete inventory ID %d", inventory.getInventoryId()));
failCount++;
errors.append("Failed to delete '").append(inventory.getProdName()).append("'\n");
}
} }
catch (SQLIntegrityConstraintViolationException e) { //show results
ActivityLogger.getInstance().logException( if (failCount > 0) {
"InventoryController.btnDeleteClicked", Alert alert = new Alert(Alert.AlertType.WARNING);
e, alert.setHeaderText("Delete Operation Completed with Errors");
"Deleting inventory (integrity constraint violation) with ID: " + inventoryId); alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
Alert alert = new Alert(Alert.AlertType.ERROR); successCount, failCount, errors.toString()));
alert.setHeaderText("Database Operation Error");
alert.setContentText("Delete failed\nThe selected inventory record is being referred in another table");
alert.showAndWait(); alert.showAndWait();
return; } else if (successCount > 0) {
} Alert alert = new Alert(Alert.AlertType.INFORMATION);
catch (SQLException e) {
ActivityLogger.getInstance().logException(
"InventoryController.btnDeleteClicked",
e,
"Deleting inventory with ID: " + inventoryId);
throw new RuntimeException(e);
}
//Checks if deletion succeeded
if (numRows == 0) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setHeaderText("Database Operation Error");
alert.setContentText("Delete failed");
alert.showAndWait();
}
else {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " inventory record(s)");
alert.showAndWait(); alert.showAndWait();
//Refresh UI
displayInventory();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displayInventory();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }

View File

@@ -67,63 +67,72 @@ public class PetController {
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected pets
Pet selectedPet = tvPets.getSelectionModel().getSelectedItem(); var selectedPets = tvPets.getSelectionModel().getSelectedItems();
if (selectedPets.isEmpty()) return;
//ask user to confirm //ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this pet?"); String message = selectedPets.size() == 1
? "Are you sure you want to delete this pet?"
: "Are you sure you want to delete " + selectedPets.size() + " pets?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response Optional<ButtonType> result = question.showAndWait();
//if confirmed,start deletion //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) { if (result.isPresent() && result.get() == ButtonType.OK) {
int petId = selectedPet.getPetId(); int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
//try deleting for (Pet pet : selectedPets) {
try{ try{
numRows = PetDB.deletePet(petId); int numRows = PetDB.deletePet(pet.getPetId());
} if (numRows > 0) {
catch (SQLIntegrityConstraintViolationException e){ successCount++;
ActivityLogger.getInstance().logException( } else {
"PetController.btnDeleteClicked", failCount++;
e, }
"Deleting pet (integrity constraint violation) with ID: " + petId); }
Alert alert = new Alert(Alert.AlertType.ERROR); catch (SQLIntegrityConstraintViolationException e){
alert.setHeaderText("Database Operation Error"); ActivityLogger.getInstance().logException(
alert.setContentText("Delete failed\n" + "PetController.btnDeleteClicked",
"the selected pet is being referred in another table"); e,
alert.showAndWait(); String.format("Attempting to delete pet ID %d - foreign key constraint", pet.getPetId()));
return; failCount++;
} errors.append("Pet '").append(pet.getPetName()).append("' is referenced in another table\n");
catch (SQLException e) { }
ActivityLogger.getInstance().logException( catch (SQLException e) {
"PetController.btnDeleteClicked", ActivityLogger.getInstance().logException(
e, "PetController.btnDeleteClicked",
"Deleting pet with ID: " + petId); e,
throw new RuntimeException(e); String.format("Attempting to delete pet ID %d", pet.getPetId()));
failCount++;
errors.append("Failed to delete '").append(pet.getPetName()).append("'\n");
}
} }
//prompt user of any errors //show results
if (numRows == 0){ if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.ERROR); Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Database Operation Error"); alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText("Delete failed"); alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait(); alert.showAndWait();
} } else if (successCount > 0) {
else{ Alert alert = new Alert(Alert.AlertType.INFORMATION);
//prompt user of delete conformation
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " pet(s)");
alert.showAndWait(); alert.showAndWait();
//refresh display and reset inputs
displayPets();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displayPets();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }
@@ -144,6 +153,8 @@ public class PetController {
void initialize() { void initialize() {
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvPets.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colPetId.setCellValueFactory(new PropertyValueFactory<Pet,Integer>("petId")); colPetId.setCellValueFactory(new PropertyValueFactory<Pet,Integer>("petId"));
colPetName.setCellValueFactory(new PropertyValueFactory<Pet,String>("petName")); colPetName.setCellValueFactory(new PropertyValueFactory<Pet,String>("petName"));

View File

@@ -71,6 +71,8 @@ public class ProductController {
//Disable buttons until a row is selected //Disable buttons until a row is selected
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvProducts.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
//set up table columns //set up table columns
colProductId.setCellValueFactory(new PropertyValueFactory<ProductDTO,Integer>("prodId")); colProductId.setCellValueFactory(new PropertyValueFactory<ProductDTO,Integer>("prodId"));
colProductName.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("prodName")); colProductName.setCellValueFactory(new PropertyValueFactory<ProductDTO,String>("prodName"));
@@ -137,69 +139,77 @@ public class ProductController {
} }
/** /**
* Delete a selected product when delete is clicked * Delete selected product(s) when delete is clicked
* @param event click event for button * @param event click event for button
*/ */
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected products
//set selected product var selectedProducts = tvProducts.getSelectionModel().getSelectedItems();
ProductDTO selectedProduct = tvProducts.getSelectionModel().getSelectedItem(); if (selectedProducts.isEmpty()) return;
//ask user to confirm //ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this product?"); String message = selectedProducts.size() == 1
? "Are you sure you want to delete this product?"
: "Are you sure you want to delete " + selectedProducts.size() + " products?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response Optional<ButtonType> result = question.showAndWait();
//if confirmed,start deletion //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) { if (result.isPresent() && result.get() == ButtonType.OK) {
int prodId = selectedProduct.getProdId(); int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
//try deleting for (ProductDTO product : selectedProducts) {
try{ try{
numRows = ProductDB.deleteProduct(prodId); int numRows = ProductDB.deleteProduct(product.getProdId());
} if (numRows > 0) {
catch (SQLIntegrityConstraintViolationException e){ successCount++;
ActivityLogger.getInstance().logException( } else {
"ProductController.btnDeleteClicked", failCount++;
e, }
String.format("Attempting to delete product ID %d - foreign key constraint", prodId)); }
Alert alert = new Alert(Alert.AlertType.ERROR); catch (SQLIntegrityConstraintViolationException e){
alert.setHeaderText("Database Operation Error"); ActivityLogger.getInstance().logException(
alert.setContentText("Delete failed\n" + "ProductController.btnDeleteClicked",
"the selected product is being referred in another table"); e,
alert.showAndWait(); String.format("Attempting to delete product ID %d - foreign key constraint", product.getProdId()));
return; failCount++;
} errors.append("Product '").append(product.getProdName()).append("' is referenced in another table\n");
catch (SQLException e) { }
ActivityLogger.getInstance().logException( catch (SQLException e) {
"ProductController.btnDeleteClicked", ActivityLogger.getInstance().logException(
e, "ProductController.btnDeleteClicked",
String.format("Attempting to delete product ID %d", prodId)); e,
throw new RuntimeException(e); String.format("Attempting to delete product ID %d", product.getProdId()));
failCount++;
errors.append("Failed to delete '").append(product.getProdName()).append("'\n");
}
} }
//prompt user of any errors //show results
if (numRows == 0){ if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.ERROR); Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Database Operation Error"); alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText("Delete failed"); alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait(); alert.showAndWait();
} } else if (successCount > 0) {
else{ Alert alert = new Alert(Alert.AlertType.INFORMATION);
//prompt user of delete conformation
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " product(s)");
alert.showAndWait(); alert.showAndWait();
//refresh display and reset inputs
displayProduct();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displayProduct();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }

View File

@@ -68,6 +68,8 @@ public class ProductSupplierController {
//Disable buttons until a row is selected //Disable buttons until a row is selected
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvProductSuppliers.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
//set up table columns //set up table columns
colProductId.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,Integer>("prodId")); colProductId.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,Integer>("prodId"));
colProductName.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,String>("prodName")); colProductName.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,String>("prodName"));
@@ -158,70 +160,81 @@ public class ProductSupplierController {
} }
/** /**
* Delete a selected productSupplier when delete is clicked * Delete selected product-supplier(s) when delete is clicked
* @param event click event for button * @param event click event for button
*/ */
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected product-suppliers
//set selected item var selectedProductSuppliers = tvProductSuppliers.getSelectionModel().getSelectedItems();
ProductSupplierDTO selectedProductSupplier = tvProductSuppliers.getSelectionModel().getSelectedItem(); if (selectedProductSuppliers.isEmpty()) return;
//ask user to confirm //ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this product-supplier?"); String message = selectedProductSuppliers.size() == 1
? "Are you sure you want to delete this product-supplier?"
: "Are you sure you want to delete " + selectedProductSuppliers.size() + " product-suppliers?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response Optional<ButtonType> result = question.showAndWait();
//if confirmed,start deletion //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK) { if (result.isPresent() && result.get() == ButtonType.OK) {
int supId = selectedProductSupplier.getSupId(); int successCount = 0;
int prodId = selectedProductSupplier.getProdId(); int failCount = 0;
StringBuilder errors = new StringBuilder();
//try deleting for (ProductSupplierDTO productSupplier : selectedProductSuppliers) {
try{ try{
numRows = ProductSupplierDB.deleteProductSupplier(supId, prodId); int numRows = ProductSupplierDB.deleteProductSupplier(productSupplier.getSupId(), productSupplier.getProdId());
} if (numRows > 0) {
catch (SQLIntegrityConstraintViolationException e){ successCount++;
ActivityLogger.getInstance().logException( } else {
"ProductSupplierController.btnDeleteClicked", failCount++;
e, }
"Deleting product-supplier (integrity constraint violation) - SupID: " + supId + ", ProdID: " + prodId); }
Alert alert = new Alert(Alert.AlertType.ERROR); catch (SQLIntegrityConstraintViolationException e){
alert.setHeaderText("Database Operation Error"); ActivityLogger.getInstance().logException(
alert.setContentText("Delete failed\n" + "ProductSupplierController.btnDeleteClicked",
"the selected product-supplier is being referred in another table"); e,
alert.showAndWait(); String.format("Attempting to delete product-supplier - SupID: %d, ProdID: %d - foreign key constraint",
return; productSupplier.getSupId(), productSupplier.getProdId()));
} failCount++;
catch (SQLException e) { errors.append(String.format("Product-Supplier '%s - %s' is referenced in another table\n",
ActivityLogger.getInstance().logException( productSupplier.getProdName(), productSupplier.getSupCompany()));
"ProductSupplierController.btnDeleteClicked", }
e, catch (SQLException e) {
"Deleting product-supplier - SupID: " + supId + ", ProdID: " + prodId); ActivityLogger.getInstance().logException(
throw new RuntimeException(e); "ProductSupplierController.btnDeleteClicked",
e,
String.format("Attempting to delete product-supplier - SupID: %d, ProdID: %d",
productSupplier.getSupId(), productSupplier.getProdId()));
failCount++;
errors.append(String.format("Failed to delete '%s - %s'\n",
productSupplier.getProdName(), productSupplier.getSupCompany()));
}
} }
//prompt user of any errors //show results
if (numRows == 0){ if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.ERROR); Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Database Operation Error"); alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText("Delete failed"); alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait(); alert.showAndWait();
} } else if (successCount > 0) {
else{ Alert alert = new Alert(Alert.AlertType.INFORMATION);
//prompt user of delete conformation
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " product-supplier(s)");
alert.showAndWait(); alert.showAndWait();
//refresh display and reset inputs
displayProductSupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displayProductSupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }

View File

@@ -38,6 +38,8 @@ public class ServiceController {
@FXML @FXML
public void initialize() { public void initialize() {
//Enable multiple selection
tvServices.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
colServiceId.setCellValueFactory(new PropertyValueFactory<>("serviceId")); colServiceId.setCellValueFactory(new PropertyValueFactory<>("serviceId"));
colServiceName.setCellValueFactory(new PropertyValueFactory<>("serviceName")); colServiceName.setCellValueFactory(new PropertyValueFactory<>("serviceName"));
@@ -124,19 +126,56 @@ public class ServiceController {
@FXML @FXML
void btnDeleteClicked(ActionEvent e) { void btnDeleteClicked(ActionEvent e) {
//get selected services
var selectedServices = tvServices.getSelectionModel().getSelectedItems();
if (selectedServices.isEmpty()) return;
Service service = tvServices.getSelectionModel().getSelectedItem(); //ask user to confirm
if (service == null) return; Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete");
String message = selectedServices.size() == 1
? "Are you sure you want to delete this service?"
: "Are you sure you want to delete " + selectedServices.size() + " services?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
java.util.Optional<ButtonType> result = question.showAndWait();
try { //if confirmed, start deletion
ServiceDB.deleteService(service.getServiceId()); if (result.isPresent() && result.get() == ButtonType.OK) {
int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
for (Service service : selectedServices) {
try {
ServiceDB.deleteService(service.getServiceId());
successCount++;
} catch (Exception ex) {
ActivityLogger.getInstance().logException(
"ServiceController.btnDeleteClicked",
ex,
String.format("Attempting to delete service ID %d", service.getServiceId()));
failCount++;
errors.append("Failed to delete '").append(service.getServiceName()).append("'\n");
}
}
//show results
if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait();
} else if (successCount > 0) {
Alert alert = new Alert(Alert.AlertType.INFORMATION);
alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Successfully deleted " + successCount + " service(s)");
alert.showAndWait();
}
//refresh display
loadServices(); loadServices();
} catch (Exception ex) {
ActivityLogger.getInstance().logException(
"ServiceController.btnDeleteClicked",
ex,
"Deleting service with ID: " + service.getServiceId());
ex.printStackTrace();
} }
} }

View File

@@ -66,6 +66,8 @@ public class SupplierController {
//Disable buttons until a row is selected //Disable buttons until a row is selected
btnEdit.setDisable(true); btnEdit.setDisable(true);
btnDelete.setDisable(true); btnDelete.setDisable(true);
//Enable multiple selection
tvSuppliers.getSelectionModel().setSelectionMode(javafx.scene.control.SelectionMode.MULTIPLE);
//set columns for table view //set columns for table view
colSupplierId.setCellValueFactory(new PropertyValueFactory<Supplier, Integer>("supId")); colSupplierId.setCellValueFactory(new PropertyValueFactory<Supplier, Integer>("supId"));
colSupplierName.setCellValueFactory(new PropertyValueFactory<Supplier, String>("supCompany")); colSupplierName.setCellValueFactory(new PropertyValueFactory<Supplier, String>("supCompany"));
@@ -154,69 +156,77 @@ public class SupplierController {
} }
/** /**
* Delete a selected supplier when delete is clicked * Delete selected supplier(s) when delete is clicked
* @param event click event for button * @param event click event for button
*/ */
@FXML @FXML
void btnDeleteClicked(ActionEvent event) { void btnDeleteClicked(ActionEvent event) {
int numRows = 0; //get selected suppliers
//set selected supplier var selectedSuppliers = tvSuppliers.getSelectionModel().getSelectedItems();
Supplier selectedSupplier = tvSuppliers.getSelectionModel().getSelectedItem(); if (selectedSuppliers.isEmpty()) return;
//ask user to confirm //ask user to confirm
Alert question = new Alert(Alert.AlertType.CONFIRMATION); Alert question = new Alert(Alert.AlertType.CONFIRMATION);
question.setHeaderText("Please confirm delete"); question.setHeaderText("Please confirm delete");
question.setContentText("Are you sure you want to delete this supplier?"); String message = selectedSuppliers.size() == 1
? "Are you sure you want to delete this supplier?"
: "Are you sure you want to delete " + selectedSuppliers.size() + " suppliers?";
question.setContentText(message);
question.getDialogPane().lookupButton(ButtonType.OK).requestFocus(); question.getDialogPane().lookupButton(ButtonType.OK).requestFocus();
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response Optional<ButtonType> result = question.showAndWait();
//if confirmed, start deletion //if confirmed, start deletion
if (result.isPresent() && result.get() == ButtonType.OK){ if (result.isPresent() && result.get() == ButtonType.OK) {
int supId = selectedSupplier.getSupId(); int successCount = 0;
int failCount = 0;
StringBuilder errors = new StringBuilder();
//Try deleting supplier for (Supplier supplier : selectedSuppliers) {
try{ try{
numRows = SupplierDB.deleteSupplier(supId); int numRows = SupplierDB.deleteSupplier(supplier.getSupId());
} if (numRows > 0) {
catch (SQLIntegrityConstraintViolationException e){ successCount++;
ActivityLogger.getInstance().logException( } else {
"SupplierController.btnDeleteClicked", failCount++;
e, }
"Deleting supplier (integrity constraint violation) with ID: " + supId); }
Alert alert = new Alert(Alert.AlertType.ERROR); catch (SQLIntegrityConstraintViolationException e){
alert.setHeaderText("Database Operation Error"); ActivityLogger.getInstance().logException(
alert.setContentText("Delete failed\n" + "SupplierController.btnDeleteClicked",
"the selected supplier is being referred in another table"); e,
alert.showAndWait(); String.format("Attempting to delete supplier ID %d - foreign key constraint", supplier.getSupId()));
return; failCount++;
} errors.append("Supplier '").append(supplier.getSupCompany()).append("' is referenced in another table\n");
catch (SQLException e) { }
ActivityLogger.getInstance().logException( catch (SQLException e) {
"SupplierController.btnDeleteClicked", ActivityLogger.getInstance().logException(
e, "SupplierController.btnDeleteClicked",
"Deleting supplier with ID: " + supId); e,
throw new RuntimeException(e); String.format("Attempting to delete supplier ID %d", supplier.getSupId()));
failCount++;
errors.append("Failed to delete '").append(supplier.getSupCompany()).append("'\n");
}
} }
//prompt user of any errors //show results
if (numRows == 0){ if (failCount > 0) {
Alert alert = new Alert(Alert.AlertType.ERROR); Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Database Operation Error"); alert.setHeaderText("Delete Operation Completed with Errors");
alert.setContentText("Delete failed"); alert.setContentText(String.format("Deleted: %d\nFailed: %d\n\n%s",
successCount, failCount, errors.toString()));
alert.showAndWait(); alert.showAndWait();
} } else if (successCount > 0) {
else{ Alert alert = new Alert(Alert.AlertType.INFORMATION);
//prompt user of delete conformation
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setHeaderText("Database Operation Confirmed"); alert.setHeaderText("Database Operation Confirmed");
alert.setContentText("Delete successful"); alert.setContentText("Successfully deleted " + successCount + " supplier(s)");
alert.showAndWait(); alert.showAndWait();
//refresh display
displaySupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
//refresh display and reset inputs
displaySupplier();
btnDelete.setDisable(true);
btnEdit.setDisable(true);
txtSearch.setText("");
} }
} }