Merge pull request #13 from RecentRunner/CURDProductSupplier
Added CRUD to productSuppliers
This commit is contained in:
@@ -85,6 +85,7 @@ CREATE TABLE product (
|
|||||||
CREATE TABLE productSupplier (
|
CREATE TABLE productSupplier (
|
||||||
supId INT NOT NULL,
|
supId INT NOT NULL,
|
||||||
prodId INT NOT NULL,
|
prodId INT NOT NULL,
|
||||||
|
cost DECIMAL(10, 2) NOT NULL,
|
||||||
PRIMARY KEY (supId, prodId),
|
PRIMARY KEY (supId, prodId),
|
||||||
FOREIGN KEY (supId) REFERENCES supplier(supId),
|
FOREIGN KEY (supId) REFERENCES supplier(supId),
|
||||||
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||||
@@ -234,16 +235,16 @@ VALUES
|
|||||||
('Hamster Wheel', 15.00, 5, 'Exercise wheel for small pets'),
|
('Hamster Wheel', 15.00, 5, 'Exercise wheel for small pets'),
|
||||||
('Organic Dog Treats', 25.00, 1, 'Natural dog treats');
|
('Organic Dog Treats', 25.00, 1, 'Natural dog treats');
|
||||||
|
|
||||||
INSERT INTO productSupplier (supId, prodId)
|
INSERT INTO productSupplier (supId, prodId, cost)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1),
|
(1, 1, 35.00),
|
||||||
(1, 2),
|
(1, 2, 6.50),
|
||||||
(2, 2),
|
(2, 2, 7.00),
|
||||||
(3, 3),
|
(3, 3, 90.00),
|
||||||
(3, 4),
|
(3, 4, 60.00),
|
||||||
(4, 5),
|
(4, 5, 10.00),
|
||||||
(5, 6),
|
(5, 6, 18.00),
|
||||||
(1, 6);
|
(1, 6, 17.50);
|
||||||
|
|
||||||
INSERT INTO inventory (prodId, quantity)
|
INSERT INTO inventory (prodId, quantity)
|
||||||
VALUES
|
VALUES
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package org.example.petshopdesktop.DTOs;
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
|
|
||||||
|
public class ProductSupplierDTO {
|
||||||
|
private SimpleIntegerProperty supId;
|
||||||
|
private SimpleIntegerProperty prodId;
|
||||||
|
private SimpleStringProperty supCompany;
|
||||||
|
private SimpleStringProperty prodName;
|
||||||
|
private SimpleDoubleProperty cost;
|
||||||
|
|
||||||
|
//constructor
|
||||||
|
public ProductSupplierDTO(int supId, int prodId, String supCompany, String prodName, double cost) {
|
||||||
|
this.supId = new SimpleIntegerProperty(supId);
|
||||||
|
this.prodId = new SimpleIntegerProperty(prodId);
|
||||||
|
this.supCompany = new SimpleStringProperty(supCompany);
|
||||||
|
this.prodName = new SimpleStringProperty(prodName);
|
||||||
|
this.cost = new SimpleDoubleProperty(cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
//getter and setters
|
||||||
|
public int getSupId() {
|
||||||
|
return supId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleIntegerProperty supIdProperty() {
|
||||||
|
return supId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupId(int supId) {
|
||||||
|
this.supId.set(supId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProdId() {
|
||||||
|
return prodId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleIntegerProperty prodIdProperty() {
|
||||||
|
return prodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProdId(int prodId) {
|
||||||
|
this.prodId.set(prodId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSupCompany() {
|
||||||
|
return supCompany.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStringProperty supCompanyProperty() {
|
||||||
|
return supCompany;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupCompany(String supCompany) {
|
||||||
|
this.supCompany.set(supCompany);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProdName() {
|
||||||
|
return prodName.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleStringProperty prodNameProperty() {
|
||||||
|
return prodName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProdName(String prodName) {
|
||||||
|
this.prodName.set(prodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost() {
|
||||||
|
return cost.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDoubleProperty costProperty() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(double cost) {
|
||||||
|
this.cost.set(cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,7 @@ public class ProductController {
|
|||||||
try{
|
try{
|
||||||
data = ProductDB.getProductDTO();
|
data = ProductDB.getProductDTO();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
System.out.println(e.getMessage());
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
//put data in the table
|
//put data in the table
|
||||||
@@ -114,7 +114,7 @@ public class ProductController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* open a new dialog for adding a product
|
* open a new dialog for adding a product
|
||||||
* @param event
|
* @param event click event for button
|
||||||
*/
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
void btnAddClicked(ActionEvent event) {
|
void btnAddClicked(ActionEvent event) {
|
||||||
@@ -211,7 +211,7 @@ public class ProductController {
|
|||||||
tvProducts.setItems(data);
|
tvProducts.setItems(data);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,27 @@
|
|||||||
package org.example.petshopdesktop.controllers;
|
package org.example.petshopdesktop.controllers;
|
||||||
|
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.Button;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.TableView;
|
import javafx.scene.control.*;
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.cell.PropertyValueFactory;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import org.example.petshopdesktop.DTOs.ProductDTO;
|
||||||
|
import org.example.petshopdesktop.DTOs.ProductSupplierDTO;
|
||||||
|
import org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController;
|
||||||
|
import org.example.petshopdesktop.controllers.dialogcontrollers.ProductSupplierDialogController;
|
||||||
|
import org.example.petshopdesktop.database.ProductDB;
|
||||||
|
import org.example.petshopdesktop.database.ProductSupplierDB;
|
||||||
|
import org.example.petshopdesktop.models.ProductSupplier;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLIntegrityConstraintViolationException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class ProductSupplierController {
|
public class ProductSupplierController {
|
||||||
|
|
||||||
@@ -19,39 +35,222 @@ public class ProductSupplierController {
|
|||||||
private Button btnEdit;
|
private Button btnEdit;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<?, ?> colCost;
|
private TableColumn<ProductSupplierDTO, Double> colCost;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<?, ?> colProductId;
|
private TableColumn<ProductSupplierDTO, Integer> colProductId;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<?, ?> colProductName;
|
private TableColumn<ProductSupplierDTO, String> colProductName;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<?, ?> colSupplierId;
|
private TableColumn<ProductSupplierDTO, Integer> colSupplierId;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableColumn<?, ?> colSupplierName;
|
private TableColumn<ProductSupplierDTO, String> colSupplierName;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TableView<?> tvProductSuppliers;
|
private TableView<ProductSupplierDTO> tvProductSuppliers;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private TextField txtSearch;
|
private TextField txtSearch;
|
||||||
|
|
||||||
|
//data declaration
|
||||||
|
private ObservableList<ProductSupplierDTO> data = FXCollections.observableArrayList();
|
||||||
|
private String mode = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the table view for table and display it when starting up
|
||||||
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
void btnAddClicked(ActionEvent event) {
|
public void initialize() {
|
||||||
|
//Disable buttons until a row is selected
|
||||||
|
btnEdit.setDisable(true);
|
||||||
|
btnDelete.setDisable(true);
|
||||||
|
//set up table columns
|
||||||
|
colProductId.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,Integer>("prodId"));
|
||||||
|
colProductName.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,String>("prodName"));
|
||||||
|
colSupplierId.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,Integer>("supId"));
|
||||||
|
colSupplierName.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,String>("supCompany"));
|
||||||
|
colCost.setCellValueFactory(new PropertyValueFactory<ProductSupplierDTO,Double>("cost"));
|
||||||
|
|
||||||
|
displayProductSupplier();
|
||||||
|
|
||||||
|
//EventListener to Enable buttons when a row is selected
|
||||||
|
tvProductSuppliers.getSelectionModel().selectedItemProperty().addListener(
|
||||||
|
(observable, oldValue, newValue) -> {
|
||||||
|
btnEdit.setDisable(false);
|
||||||
|
btnDelete.setDisable(false);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//EventListener to search when text is changed on searchbar
|
||||||
|
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||||
|
displayFilteredProductSupplier(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the ProductSupplierDTO to table view
|
||||||
|
*/
|
||||||
|
private void displayProductSupplier() {
|
||||||
|
//Erase old content
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
//get ProductSupplier from database
|
||||||
|
try{
|
||||||
|
data = ProductSupplierDB.getProductSupplierDTO();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
//put data in the table
|
||||||
|
tvProductSuppliers.setItems(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the table given the string from the searchbar
|
||||||
|
* @param filter word to filter table
|
||||||
|
*/
|
||||||
|
private void displayFilteredProductSupplier(String filter){
|
||||||
|
data.clear();
|
||||||
|
try{
|
||||||
|
if (txtSearch.getText() == null || txtSearch.getText().isEmpty()){
|
||||||
|
displayProductSupplier(); //If search bar is empty just display everything
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//Filter the using the keyword
|
||||||
|
data = ProductSupplierDB.getFilteredProductSupplierDTO(filter);
|
||||||
|
tvProductSuppliers.setItems(data);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* open a new dialog for adding a productSupplier
|
||||||
|
* @param event click event for button
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
void btnAddClicked(ActionEvent event) {
|
||||||
|
mode = "Add";
|
||||||
|
openDialog(null,mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a selected productSupplier when delete is clicked
|
||||||
|
* @param event click event for button
|
||||||
|
*/
|
||||||
@FXML
|
@FXML
|
||||||
void btnDeleteClicked(ActionEvent event) {
|
void btnDeleteClicked(ActionEvent event) {
|
||||||
|
int numRows = 0;
|
||||||
|
//set selected item
|
||||||
|
ProductSupplierDTO selectedProductSupplier = tvProductSuppliers.getSelectionModel().getSelectedItem();
|
||||||
|
|
||||||
|
//ask user to confirm
|
||||||
|
Alert question = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
question.setHeaderText("Please confirm delete");
|
||||||
|
question.setContentText("Are you sure you want to delete this product-supplier?");
|
||||||
|
Optional<ButtonType> result = question.showAndWait(); //show alert and wait for response
|
||||||
|
|
||||||
|
//if confirmed,start deletion
|
||||||
|
if (result.isPresent() && result.get() == ButtonType.OK) {
|
||||||
|
int supId = selectedProductSupplier.getSupId();
|
||||||
|
int prodId = selectedProductSupplier.getProdId();
|
||||||
|
|
||||||
|
//try deleting
|
||||||
|
try{
|
||||||
|
numRows = ProductSupplierDB.deleteProductSupplier(supId, prodId);
|
||||||
|
}
|
||||||
|
catch (SQLIntegrityConstraintViolationException e){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText("Delete failed\n" +
|
||||||
|
"the selected product-supplier is being referred in another table");
|
||||||
|
alert.showAndWait();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (SQLException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
//prompt user of any errors
|
||||||
|
if (numRows == 0){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText("Delete failed");
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
//prompt user of delete conformation
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setHeaderText("Database Operation Confirmed");
|
||||||
|
alert.setContentText("Delete successful");
|
||||||
|
alert.showAndWait();
|
||||||
|
//refresh display and reset inputs
|
||||||
|
displayProductSupplier();
|
||||||
|
btnDelete.setDisable(true);
|
||||||
|
btnEdit.setDisable(true);
|
||||||
|
txtSearch.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
void btnEditClicked(ActionEvent event) {
|
void btnEditClicked(ActionEvent event) {
|
||||||
|
//set selected item
|
||||||
|
ProductSupplierDTO selectedProductSupplier = tvProductSuppliers.getSelectionModel().getSelectedItem();
|
||||||
|
|
||||||
|
if (selectedProductSupplier != null) {
|
||||||
|
mode = "Edit";
|
||||||
|
openDialog(selectedProductSupplier,mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to open the new Dialog for edit or adding
|
||||||
|
* depending on the mode given
|
||||||
|
* @param productSupplier the productSupplier entity for editing, null if adding
|
||||||
|
* @param mode the mode the dialog should be in
|
||||||
|
*/
|
||||||
|
private void openDialog(ProductSupplierDTO productSupplier, String mode){
|
||||||
|
//Get new view
|
||||||
|
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/dialogviews/product-supplier-dialog-view.fxml"));
|
||||||
|
Scene scene = null;
|
||||||
|
try{
|
||||||
|
scene = new Scene(fxmlLoader.load());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
ProductSupplierDialogController dialogController = fxmlLoader.getController(); //controller associated with this view
|
||||||
|
dialogController.setMode(mode);
|
||||||
|
if (productSupplier != null) {
|
||||||
|
dialogController.setSelectedIds(productSupplier.getSupId(), productSupplier.getProdId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Open the dialog depending on the mode
|
||||||
|
if(mode.equals("Edit")){
|
||||||
|
//Make it display suppliers details in dialog
|
||||||
|
dialogController.displayProductSupplierDetails(productSupplier);
|
||||||
|
}
|
||||||
|
Stage dialogStage = new Stage();
|
||||||
|
dialogStage.initModality(Modality.APPLICATION_MODAL); //make it modal
|
||||||
|
if(mode.equals("Add")){
|
||||||
|
dialogStage.setTitle("Add Product-Supplier");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dialogStage.setTitle("Edit Product-Supplier");
|
||||||
|
}
|
||||||
|
dialogStage.setScene(scene);
|
||||||
|
dialogStage.showAndWait();
|
||||||
|
|
||||||
|
//When dialog closes update table view and disable edit and delete buttons, and reset search bar
|
||||||
|
displayProductSupplier();
|
||||||
|
btnDelete.setDisable(true);
|
||||||
|
btnEdit.setDisable(true);
|
||||||
|
txtSearch.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ public class SupplierController {
|
|||||||
try{
|
try{
|
||||||
data = SupplierDB.getSuppliers();
|
data = SupplierDB.getSuppliers();
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new RuntimeException(e);
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
tvSuppliers.setItems(data);
|
tvSuppliers.setItems(data);
|
||||||
@@ -121,7 +121,7 @@ public class SupplierController {
|
|||||||
tvSuppliers.setItems(data);
|
tvSuppliers.setItems(data);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
System.out.println("Error while fetching table data: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ public class ProductDialogController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the inputs, then add or update the database depending
|
||||||
|
* on the mode
|
||||||
|
* @param mouseEvent click event for save button
|
||||||
|
*/
|
||||||
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||||
int numRow = 0; //how many rows affected
|
int numRow = 0; //how many rows affected
|
||||||
String errorMsg = ""; //error message for validation
|
String errorMsg = ""; //error message for validation
|
||||||
@@ -164,7 +169,7 @@ public class ProductDialogController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the product data in text fields and combobox
|
* Display the product data in text fields and combobox
|
||||||
* @param product the supplier entity containing data to display
|
* @param product the product entity containing data to display
|
||||||
*/
|
*/
|
||||||
public void displayProductDetails(ProductDTO product){
|
public void displayProductDetails(ProductDTO product){
|
||||||
if (product!=null){
|
if (product!=null){
|
||||||
@@ -176,7 +181,7 @@ public class ProductDialogController {
|
|||||||
//get the right combobox selection
|
//get the right combobox selection
|
||||||
for (Category category : cbProdCategory.getItems()) {
|
for (Category category : cbProdCategory.getItems()) {
|
||||||
if(category.getCategoryId() == product.getCategoryId()){
|
if(category.getCategoryId() == product.getCategoryId()){
|
||||||
cbProdCategory.setValue(category);
|
cbProdCategory.getSelectionModel().select(category);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,245 @@
|
|||||||
|
package org.example.petshopdesktop.controllers.dialogcontrollers;
|
||||||
|
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.event.EventHandler;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.input.MouseEvent;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import org.example.petshopdesktop.DTOs.ProductSupplierDTO;
|
||||||
|
import org.example.petshopdesktop.Validator;
|
||||||
|
import org.example.petshopdesktop.database.ProductDB;
|
||||||
|
import org.example.petshopdesktop.database.ProductSupplierDB;
|
||||||
|
import org.example.petshopdesktop.database.SupplierDB;
|
||||||
|
import org.example.petshopdesktop.models.Product;
|
||||||
|
import org.example.petshopdesktop.models.ProductSupplier;
|
||||||
|
import org.example.petshopdesktop.models.Supplier;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLIntegrityConstraintViolationException;
|
||||||
|
|
||||||
|
public class ProductSupplierDialogController {
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button btnCancel;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Button btnSave;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ComboBox<Product> cbProduct;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ComboBox<Supplier> cbSupplier;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label lblMode;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label lblProductSupplierId;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private TextField txtCost;
|
||||||
|
|
||||||
|
private String mode = null;
|
||||||
|
private int selectedSupId = -1;
|
||||||
|
private int selectedProdId = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add event listeners to buttons and set up combobox
|
||||||
|
*/
|
||||||
|
@FXML
|
||||||
|
void initialize() { //Set up mouse handlers for buttons
|
||||||
|
btnSave.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(MouseEvent mouseEvent) {
|
||||||
|
buttonSaveClicked(mouseEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnCancel.setOnMouseClicked(new EventHandler<MouseEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(MouseEvent mouseEvent) {
|
||||||
|
closeStage(mouseEvent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Set up combobox for selecting product and supplier
|
||||||
|
try{
|
||||||
|
ObservableList<Supplier> suppliers = FXCollections.observableArrayList(); //empty list
|
||||||
|
ObservableList<Product> products = FXCollections.observableArrayList(); //empty list
|
||||||
|
|
||||||
|
//get suppliers and products from DB
|
||||||
|
suppliers = SupplierDB.getSuppliers();
|
||||||
|
products = ProductDB.getProducts();
|
||||||
|
|
||||||
|
//Populate combobox
|
||||||
|
cbSupplier.setItems(suppliers);
|
||||||
|
cbProduct.setItems(products);
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the inputs, then add or update the database depending
|
||||||
|
* on the mode
|
||||||
|
* @param mouseEvent click event for save button
|
||||||
|
*/
|
||||||
|
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||||
|
int numRows = 0;
|
||||||
|
String errorMsg = ""; //error message for validation
|
||||||
|
|
||||||
|
//Check Validation (input required)
|
||||||
|
errorMsg += Validator.isPresent(txtCost.getText(), "Cost");
|
||||||
|
if (cbProduct.getSelectionModel().getSelectedItem() == null) {
|
||||||
|
errorMsg += "Product is required \n";
|
||||||
|
}
|
||||||
|
if (cbSupplier.getSelectionModel().getSelectedItem() == null) {
|
||||||
|
errorMsg += "Supplier is required \n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//Check validation (length size)
|
||||||
|
errorMsg += Validator.isLessThanVarChars(txtCost.getText(), "Cost", 12);
|
||||||
|
|
||||||
|
//Check validation (format)
|
||||||
|
errorMsg += Validator.isNonNegativeDouble(txtCost.getText(), "Cost");
|
||||||
|
|
||||||
|
if(errorMsg.isEmpty()){ //no validation errors
|
||||||
|
ProductSupplier productSupplier = collectProductSupplier(); //get productSupplier info
|
||||||
|
if (mode.equals("Add")) { //add mode
|
||||||
|
try{
|
||||||
|
numRows = ProductSupplierDB.insertProductSupplier(productSupplier);
|
||||||
|
}
|
||||||
|
catch(SQLIntegrityConstraintViolationException e){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText("Add failed \n" +
|
||||||
|
"the product-supplier link is already in the database");
|
||||||
|
alert.showAndWait();
|
||||||
|
numRows = -1; //Update numRow so alert only shows once
|
||||||
|
closeStage(mouseEvent);
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { //edit
|
||||||
|
try{
|
||||||
|
numRows = ProductSupplierDB.updateProductSupplier(selectedSupId, selectedProdId, productSupplier);
|
||||||
|
}
|
||||||
|
catch(SQLIntegrityConstraintViolationException e){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText("Edit failed \n" +
|
||||||
|
"the product-supplier link is already in the database");
|
||||||
|
alert.showAndWait();
|
||||||
|
numRows = -1; //Update numRow so alert only shows once
|
||||||
|
closeStage(mouseEvent);
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if no rows were affected then there was an error (prompt user of error)
|
||||||
|
if (numRows == 0){
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Database Operation Error");
|
||||||
|
alert.setContentText(mode + " failed");
|
||||||
|
alert.showAndWait();
|
||||||
|
closeStage(mouseEvent);
|
||||||
|
}
|
||||||
|
else if (numRows > 0){
|
||||||
|
//tell the user operation was successful
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setHeaderText("Database Operation Confirmed");
|
||||||
|
alert.setContentText(mode + " succeeded");
|
||||||
|
alert.showAndWait();
|
||||||
|
closeStage(mouseEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { //Display validation errors
|
||||||
|
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||||
|
alert.setHeaderText("Input Error");
|
||||||
|
alert.setContentText(errorMsg);
|
||||||
|
alert.showAndWait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* collect the data for new/updated productSupplier
|
||||||
|
* @return productSupplier entity with data
|
||||||
|
*/
|
||||||
|
private ProductSupplier collectProductSupplier() {
|
||||||
|
ProductSupplier productSupplier = null;
|
||||||
|
|
||||||
|
productSupplier = new ProductSupplier(
|
||||||
|
cbSupplier.getSelectionModel().getSelectedItem().getSupId(),
|
||||||
|
cbProduct.getSelectionModel().getSelectedItem().getProdId(),
|
||||||
|
Double.parseDouble(txtCost.getText())
|
||||||
|
);
|
||||||
|
|
||||||
|
return productSupplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the productsupplier data in text fields and combobox
|
||||||
|
* @param productSupplier
|
||||||
|
*/
|
||||||
|
public void displayProductSupplierDetails(ProductSupplierDTO productSupplier){
|
||||||
|
if(productSupplier != null){
|
||||||
|
txtCost.setText(productSupplier.getCost() + "");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the right combobox selection (product)
|
||||||
|
for (Product product : cbProduct.getItems()) {
|
||||||
|
if(product.getProdId() == productSupplier.getProdId()){
|
||||||
|
cbProduct.getSelectionModel().select(product);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the right combobox selection (supplier)
|
||||||
|
for (Supplier supplier : cbSupplier.getItems()) {
|
||||||
|
if (supplier.getSupId() == productSupplier.getSupId()) {
|
||||||
|
cbSupplier.getSelectionModel().select(supplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the window
|
||||||
|
* @param mouseEvent mouse event to close
|
||||||
|
*/
|
||||||
|
private void closeStage(MouseEvent mouseEvent) {
|
||||||
|
Node node = (Node) mouseEvent.getSource();
|
||||||
|
Stage stage = (Stage) node.getScene().getWindow();
|
||||||
|
stage.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the mode of the dialog
|
||||||
|
* @param mode the mode for the dialog
|
||||||
|
*/
|
||||||
|
public void setMode(String mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
lblMode.setText(mode + " Product");
|
||||||
|
lblProductSupplierId.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the current supplier and productId for (needed for update since compound primary key)
|
||||||
|
* @param supId supplier id
|
||||||
|
* @param prodId product id
|
||||||
|
*/
|
||||||
|
public void setSelectedIds(int supId, int prodId){
|
||||||
|
this.selectedSupId = supId;
|
||||||
|
this.selectedProdId = prodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -67,6 +67,11 @@ public class SupplierDialogController {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the inputs, then add or update the database depending
|
||||||
|
* on the mode
|
||||||
|
* @param mouseEvent click event for save button
|
||||||
|
*/
|
||||||
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
private void buttonSaveClicked(MouseEvent mouseEvent) {
|
||||||
int numRow = 0; //how many rows affected
|
int numRow = 0; //how many rows affected
|
||||||
String errorMsg = ""; //error message for validation
|
String errorMsg = ""; //error message for validation
|
||||||
|
|||||||
@@ -0,0 +1,197 @@
|
|||||||
|
package org.example.petshopdesktop.database;
|
||||||
|
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import org.example.petshopdesktop.DTOs.ProductDTO;
|
||||||
|
import org.example.petshopdesktop.DTOs.ProductSupplierDTO;
|
||||||
|
import org.example.petshopdesktop.models.Product;
|
||||||
|
import org.example.petshopdesktop.models.ProductSupplier;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class ProductSupplierDB {
|
||||||
|
/**
|
||||||
|
* gets all the productSupplier into an observable list
|
||||||
|
* @return a list of all the productSupplierDTOs
|
||||||
|
* @throws SQLException if failed to find productSupplier in the database
|
||||||
|
*/
|
||||||
|
public static ObservableList<ProductSupplierDTO> getProductSupplierDTO() throws SQLException{
|
||||||
|
//Connect to the database
|
||||||
|
ObservableList<ProductSupplierDTO> productSuppliers = FXCollections.observableArrayList();
|
||||||
|
Connection conn = ConnectionDB.getConnection();
|
||||||
|
|
||||||
|
//Execute Query
|
||||||
|
Statement stmt = conn.createStatement();
|
||||||
|
String sql = "SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " +
|
||||||
|
"FROM productsupplier ps " +
|
||||||
|
"LEFT JOIN product p " +
|
||||||
|
"ON p.prodId = ps.prodId " +
|
||||||
|
"LEFT JOIN supplier s " +
|
||||||
|
"ON s.supId = ps.supId";
|
||||||
|
ResultSet rs = stmt.executeQuery(sql);
|
||||||
|
|
||||||
|
//While there is still data add productSupplier to list
|
||||||
|
while(rs.next()){
|
||||||
|
ProductSupplierDTO productSupplier = new ProductSupplierDTO(
|
||||||
|
rs.getInt(1),
|
||||||
|
rs.getInt(2),
|
||||||
|
rs.getString(3),
|
||||||
|
rs.getString(4),
|
||||||
|
rs.getDouble(5)
|
||||||
|
);
|
||||||
|
productSuppliers.add(productSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
//close connection and return products
|
||||||
|
conn.close();
|
||||||
|
return productSuppliers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of ProductSupplierDTOs that is filtered by a given string
|
||||||
|
* @param filter the word to filter table
|
||||||
|
* @return ObservableList of ProductSupplierDTOs with the filtered data
|
||||||
|
* @throws SQLException if getting productSuppliers failed
|
||||||
|
*/
|
||||||
|
public static ObservableList<ProductSupplierDTO> getFilteredProductSupplierDTO (String filter) throws SQLException {
|
||||||
|
//connect to the database
|
||||||
|
ObservableList<ProductSupplierDTO> productSuppliers = FXCollections.observableArrayList();
|
||||||
|
Connection conn = ConnectionDB.getConnection();
|
||||||
|
|
||||||
|
//Get SQL query for filter word
|
||||||
|
String sql =
|
||||||
|
"SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " +
|
||||||
|
"FROM product p " +
|
||||||
|
"LEFT JOIN productsupplier ps " +
|
||||||
|
"ON p.prodId = ps.prodId " +
|
||||||
|
"LEFT JOIN supplier s " +
|
||||||
|
"ON s.supId = ps.supId " +
|
||||||
|
"WHERE " +
|
||||||
|
"prodName LIKE ? OR " +
|
||||||
|
"supCompany LIKE ? OR " +
|
||||||
|
"cost LIKE ?";
|
||||||
|
|
||||||
|
//add % wildcard so query can use LIKE to filter data
|
||||||
|
String filteredString = "%" + filter + "%";
|
||||||
|
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||||
|
stmt.setString(1, filteredString);
|
||||||
|
stmt.setString(2, filteredString);
|
||||||
|
stmt.setString(3, filteredString);
|
||||||
|
|
||||||
|
//execute query
|
||||||
|
ResultSet rs = stmt.executeQuery();
|
||||||
|
|
||||||
|
//While there is still data add productSupplier to the list
|
||||||
|
while(rs.next()){
|
||||||
|
ProductSupplierDTO productSupplier = new ProductSupplierDTO(
|
||||||
|
rs.getInt(1),
|
||||||
|
rs.getInt(2),
|
||||||
|
rs.getString(3),
|
||||||
|
rs.getString(4),
|
||||||
|
rs.getDouble(5)
|
||||||
|
);
|
||||||
|
productSuppliers.add(productSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
conn.close();
|
||||||
|
return productSuppliers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new productSupplier to the database
|
||||||
|
* @param productSupplier productSupplier entity to be inserted
|
||||||
|
* @return number of rows affected
|
||||||
|
* @throws SQLException if insert failed
|
||||||
|
*/
|
||||||
|
public static int insertProductSupplier(ProductSupplier productSupplier) throws SQLException{
|
||||||
|
int numRows = 0;
|
||||||
|
|
||||||
|
Connection conn = ConnectionDB.getConnection();
|
||||||
|
String sql = "INSERT INTO productsupplier (prodId, supId, cost) " +
|
||||||
|
"VALUES (?, ?, ?)";
|
||||||
|
|
||||||
|
//These are the values from productSupplier to put into query above
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||||
|
stmt.setInt(1, productSupplier.getProdId());
|
||||||
|
stmt.setInt(2, productSupplier.getSupId());
|
||||||
|
stmt.setDouble(3, productSupplier.getCost());
|
||||||
|
|
||||||
|
//update number of rows affected, return and close connection
|
||||||
|
numRows = stmt.executeUpdate();
|
||||||
|
conn.close();
|
||||||
|
|
||||||
|
return numRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a productSupplier by deleting old productSupplier and inserting new one
|
||||||
|
* @param oldProdId old product id (used to change primary compound key)
|
||||||
|
* @param oldSupId old supplier id (used to change primary compound key)
|
||||||
|
* @param productSupplier productSupplier entity with new info to update (including new primary compound key)
|
||||||
|
* @return number of rows affected in database
|
||||||
|
* @throws SQLException if update failed
|
||||||
|
*/
|
||||||
|
public static int updateProductSupplier(int oldSupId, int oldProdId, ProductSupplier productSupplier) throws SQLException{
|
||||||
|
int numRows = 0;
|
||||||
|
Connection conn = ConnectionDB.getConnection();
|
||||||
|
|
||||||
|
//Make transaction so update can be rolled back if insert failed
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
try{
|
||||||
|
//Delete old data first
|
||||||
|
String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?";
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||||
|
stmt.setInt(1, oldSupId);
|
||||||
|
stmt.setInt(2, oldProdId);
|
||||||
|
numRows = stmt.executeUpdate();
|
||||||
|
|
||||||
|
//Then change the data by inserting a new relation with given keys (only if delete worked)
|
||||||
|
if(numRows > 0){
|
||||||
|
sql = "INSERT INTO productsupplier (prodId, supId, cost) " +
|
||||||
|
"VALUES (?, ?, ?)";
|
||||||
|
stmt = conn.prepareStatement(sql);
|
||||||
|
stmt.setInt(1, productSupplier.getProdId());
|
||||||
|
stmt.setInt(2, productSupplier.getSupId());
|
||||||
|
stmt.setDouble(3, productSupplier.getCost());
|
||||||
|
numRows = stmt.executeUpdate();
|
||||||
|
}
|
||||||
|
//Commit changes if both delete and insert worked
|
||||||
|
conn.commit();
|
||||||
|
}
|
||||||
|
catch(SQLException e){
|
||||||
|
//Rollback CRUD failed
|
||||||
|
conn.rollback();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
//Set auto commit back to true before closing connection
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
conn.close();
|
||||||
|
}
|
||||||
|
return numRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a productSupplier from the database
|
||||||
|
* @param prodId id of the product
|
||||||
|
* @param supId id of the supplier
|
||||||
|
* @return number of rows affected in the database
|
||||||
|
* @throws SQLException if delete failed
|
||||||
|
*/
|
||||||
|
public static int deleteProductSupplier(int supId, int prodId) throws SQLException{
|
||||||
|
int numRows = 0;
|
||||||
|
Connection conn = ConnectionDB.getConnection();
|
||||||
|
|
||||||
|
String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?";
|
||||||
|
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||||
|
stmt.setInt(1, supId);
|
||||||
|
stmt.setInt(2, prodId);
|
||||||
|
|
||||||
|
numRows = stmt.executeUpdate();
|
||||||
|
conn.close();
|
||||||
|
|
||||||
|
return numRows;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -83,4 +83,9 @@ public class Product {
|
|||||||
public void setProdDesc(String prodDesc) {
|
public void setProdDesc(String prodDesc) {
|
||||||
this.prodDesc.set(prodDesc);
|
this.prodDesc.set(prodDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getProdName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.example.petshopdesktop.models;
|
||||||
|
|
||||||
|
import javafx.beans.property.SimpleDoubleProperty;
|
||||||
|
import javafx.beans.property.SimpleIntegerProperty;
|
||||||
|
|
||||||
|
public class ProductSupplier {
|
||||||
|
private SimpleIntegerProperty supId;
|
||||||
|
private SimpleIntegerProperty prodId;
|
||||||
|
private SimpleDoubleProperty cost;
|
||||||
|
|
||||||
|
//constructor
|
||||||
|
public ProductSupplier(int supId, int prodId, double cost) {
|
||||||
|
this.supId = new SimpleIntegerProperty(supId);
|
||||||
|
this.prodId = new SimpleIntegerProperty(prodId);
|
||||||
|
this.cost = new SimpleDoubleProperty(cost);
|
||||||
|
}
|
||||||
|
|
||||||
|
//getter and setters
|
||||||
|
public int getSupId() {
|
||||||
|
return supId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleIntegerProperty supIdProperty() {
|
||||||
|
return supId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSupId(int supId) {
|
||||||
|
this.supId.set(supId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getProdId() {
|
||||||
|
return prodId.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleIntegerProperty prodIdProperty() {
|
||||||
|
return prodId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProdId(int prodId) {
|
||||||
|
this.prodId.set(prodId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCost() {
|
||||||
|
return cost.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleDoubleProperty costProperty() {
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(double cost) {
|
||||||
|
this.cost.set(cost);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -106,4 +106,9 @@ public class Supplier {
|
|||||||
public String getSupFullName() {
|
public String getSupFullName() {
|
||||||
return getSupContactFirstName() + " " + getSupContactLastName();
|
return getSupContactFirstName() + " " + getSupContactLastName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getSupCompany();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.geometry.Insets?>
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.ComboBox?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.TextField?>
|
||||||
|
<?import javafx.scene.layout.ColumnConstraints?>
|
||||||
|
<?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/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductSupplierDialogController">
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||||
|
<children>
|
||||||
|
<VBox alignment="CENTER_LEFT" prefHeight="93.0" prefWidth="358.0">
|
||||||
|
<children>
|
||||||
|
<Label fx:id="lblMode" prefHeight="42.0" prefWidth="351.0" text="Mode Product-Supplier" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font name="Comic Sans MS Bold" size="30.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<Label fx:id="lblProductSupplierId" text="ID: 1" textFill="#ffe66d">
|
||||||
|
<font>
|
||||||
|
<Font size="14.0" />
|
||||||
|
</font>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets top="10.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
|
</padding>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets />
|
||||||
|
</HBox.margin>
|
||||||
|
</VBox>
|
||||||
|
<Region prefHeight="93.0" prefWidth="98.0" HBox.hgrow="ALWAYS" />
|
||||||
|
<Button fx:id="btnCancel" layoutX="391.0" layoutY="38.0" mnemonicParsing="false" style="-fx-background-color: #E74c3c; -fx-cursor: hand; -fx-background-radius: 8;" text="Cancel" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="14.0" />
|
||||||
|
</font>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="12.0" left="24.0" right="24.0" top="12.0" />
|
||||||
|
</padding>
|
||||||
|
</Button>
|
||||||
|
<Button fx:id="btnSave" layoutX="520.0" layoutY="38.0" mnemonicParsing="false" style="-fx-background-color: #3fe06a; -fx-cursor: hand; -fx-background-radius: 8;" text="Save" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="14.0" />
|
||||||
|
</font>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="12.0" left="24.0" right="24.0" top="12.0" />
|
||||||
|
</padding>
|
||||||
|
</Button>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<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;">
|
||||||
|
<children>
|
||||||
|
<GridPane hgap="25.0" VBox.vgrow="ALWAYS">
|
||||||
|
<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>
|
||||||
|
<Label text="Product:" textFill="#2c3e50">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="16.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<ComboBox fx:id="cbProduct" prefHeight="29.0" prefWidth="336.0" promptText="Select Category" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
|
||||||
|
</padding>
|
||||||
|
</ComboBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1">
|
||||||
|
<children>
|
||||||
|
<Label text="Supplier:" textFill="#2c3e50">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="16.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<ComboBox fx:id="cbSupplier" prefHeight="29.0" prefWidth="336.0" promptText="Select Category" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10; -fx-background-color: white;">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="3.0" left="10.0" right="10.0" top="3.0" />
|
||||||
|
</padding>
|
||||||
|
</ComboBox>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="1">
|
||||||
|
<children>
|
||||||
|
<Label text="Cost" textFill="#2c3e50">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="16.0" />
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<TextField fx:id="txtCost" style="-fx-border-color: #E8EBED; -fx-border-width: 2; -fx-border-radius: 10; -fx-background-radius: 10;">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="7.0" left="10.0" right="10.0" top="7.0" />
|
||||||
|
</padding>
|
||||||
|
</TextField>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
|
||||||
|
<VBox prefHeight="200.0" prefWidth="100.0" spacing="8.0" GridPane.rowIndex="2" />
|
||||||
|
</children>
|
||||||
|
<VBox.margin>
|
||||||
|
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
|
||||||
|
</VBox.margin>
|
||||||
|
</GridPane>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0" />
|
||||||
|
</padding>
|
||||||
|
</VBox>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||||
|
</padding>
|
||||||
|
</VBox>
|
||||||
Reference in New Issue
Block a user