Skip to content

Commit e7b12d7

Browse files
committed
Implemented TableView and search functionality, Error alerts
1 parent e276519 commit e7b12d7

1 file changed

Lines changed: 221 additions & 11 deletions

File tree

src/main/java/sealey/javafxinventorysystem/ModifyProduct.java

Lines changed: 221 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@
33
import javafx.collections.FXCollections;
44
import javafx.collections.ObservableList;
55
import javafx.event.ActionEvent;
6+
import javafx.event.EventHandler;
67
import javafx.fxml.FXML;
78
import javafx.fxml.FXMLLoader;
89
import javafx.fxml.Initializable;
910
import javafx.scene.Parent;
1011
import javafx.scene.Scene;
11-
import javafx.scene.control.Button;
12-
import javafx.scene.control.TableColumn;
13-
import javafx.scene.control.TableView;
14-
import javafx.scene.control.TextField;
12+
import javafx.scene.control.*;
13+
import javafx.scene.control.cell.PropertyValueFactory;
1514
import javafx.stage.Stage;
1615

16+
import sealey.javafxinventorysystem.models.Inventory;
1717
import sealey.javafxinventorysystem.models.Part;
18+
import sealey.javafxinventorysystem.models.Product;
1819

1920
import java.io.IOException;
2021
import java.net.URL;
2122
import java.util.Objects;
23+
import java.util.Optional;
2224
import java.util.ResourceBundle;
25+
import java.util.function.UnaryOperator;
2326

2427
public class ModifyProduct implements Initializable {
2528

@@ -89,6 +92,147 @@ public class ModifyProduct implements Initializable {
8992
@FXML
9093
private TableColumn<Part, Double> table2PriceCol;
9194

95+
ObservableList<Part> bottomTable = FXCollections.observableArrayList();
96+
97+
/*
98+
* notFound() shows a 404 alert dialog box. Called in the filter methods
99+
* */
100+
101+
private void notFound() {
102+
103+
Alert alert = new Alert(Alert.AlertType.INFORMATION);
104+
alert.setTitle("404");
105+
alert.setContentText("Your search did not match any results. Please try again.");
106+
alert.setHeaderText("Not Found");
107+
alert.showAndWait();
108+
}
109+
110+
private boolean confirmation(){
111+
Alert alert = new Alert(Alert.AlertType.WARNING);
112+
alert.setTitle("Confirm Part Removal");
113+
alert.setContentText("Click 'Ok' to proceed.");
114+
alert.setHeaderText("Are you sure you want to remove this part from the product?");
115+
116+
Optional<ButtonType> result = alert.showAndWait();
117+
118+
if (result.get() == ButtonType.OK) {
119+
return true;
120+
} else {
121+
return false;
122+
}
123+
}
124+
125+
void errorMessage(String content){
126+
127+
Alert alert = new Alert(Alert.AlertType.WARNING);
128+
alert.setContentText(content);
129+
alert.setHeaderText("Something went wrong.");
130+
alert.showAndWait();
131+
}
132+
133+
/*
134+
* The search() method is a helper function that returns a boolean indicating whether an integer is already being used as an ID number for an existing product.
135+
* This is only called in the generateID() method to ensure that the auto-generated ID is unique.
136+
*
137+
* @param id Integer to be checked for ID uniqueness
138+
* @return boolean True if ID belongs to existing product, False otherwise
139+
* */
140+
private boolean search(int id){
141+
142+
for(Product p : Inventory.getAllProducts())
143+
{
144+
if(p.getId() == id){
145+
return true;
146+
}
147+
}
148+
return false;
149+
}
150+
151+
/*
152+
* The generateID() method is a helper function that generates an ID number for created part. Always returns the next unique integer in sequential order
153+
*
154+
* @return id Integer that is either 1 (if List is empty), or the next unique integer
155+
* */
156+
private int generateID() {
157+
158+
int id = 1;
159+
for(Part a : Inventory.getAllParts()) {
160+
if(search(id)){
161+
id++;
162+
} else {
163+
return id;
164+
}
165+
}
166+
return id;
167+
}
168+
169+
/*
170+
* The isInt() method checks whether a provided string can be converted to an integer and returns a boolean.
171+
*
172+
* @param str The string to be checked
173+
* @return boolean Returns true if string is also an integer, false if exception is caught
174+
*/
175+
private boolean isInt(String str) {
176+
177+
try {
178+
Integer.valueOf(str);
179+
return true;
180+
} catch (NumberFormatException e) { return false; }
181+
}
182+
183+
void errorMessage(String title, String content, Alert.AlertType type) {
184+
185+
Alert alert = new Alert(Alert.AlertType.NONE);
186+
alert.setAlertType(type);
187+
alert.setTitle(title);
188+
alert.setContentText(content);
189+
alert.showAndWait();
190+
}
191+
192+
boolean checkStockValues(int min, int max, int stock) {
193+
194+
if (max <= stock || min >= stock) {
195+
errorMessage("Invalid Input", "Min should be less than Max, and the Inventory level must be in between", Alert.AlertType.ERROR);
196+
return false;
197+
} else {
198+
return true;
199+
}
200+
}
201+
202+
/*
203+
* The filterParts() method checks a string input (searchPartText TextField)
204+
* and returns a list of Parts whose name contains the string, and/or whose ID is equal to the string.
205+
* Returns an ObservableList containing all parts if the TextField is empty. If the search term does not
206+
* find any matches, error message is displayed in dialog box.
207+
*
208+
* @param search String retrieved from searchPartText
209+
* @return ObservableList of Parts containing all parts whose name contains the search parameter
210+
* and/or whose id is equal to the search parameter, or list of all Parts.
211+
* */
212+
private ObservableList<Part> filterParts(){
213+
214+
String search = searchProductText.getText();
215+
ObservableList<Part> temp = Inventory.lookupPart(search);
216+
217+
if(isInt(search)){
218+
Part a = Inventory.lookupPart(Integer.parseInt(search));
219+
if(a != null){
220+
temp.add(a);
221+
}
222+
}
223+
224+
if(search.isEmpty()){
225+
return Inventory.getAllParts();
226+
}
227+
else if (temp.isEmpty()) {
228+
notFound();
229+
return Inventory.getAllParts();
230+
} else {
231+
return temp;
232+
}
233+
}
234+
235+
92236
@FXML
93237
void onActionCancel(ActionEvent event) throws IOException {
94238

@@ -100,13 +244,17 @@ void onActionCancel(ActionEvent event) throws IOException {
100244
@FXML
101245
void onActionSave(ActionEvent event) throws IOException {
102246

103-
int id = Integer.parseInt(productIDText.getText());
247+
int id = Integer.parseInt(productIDText.getPromptText());
104248
String name = productNameText.getText();
105-
int inv = Integer.parseInt(inventoryText.getText());
106249
double price = Double.parseDouble(priceText.getText());
107-
int max = Integer.parseInt(maxText.getText());
250+
int inv = Integer.parseInt(inventoryText.getText());
108251
int min = Integer.parseInt(minText.getText());
252+
int max = Integer.parseInt(maxText.getText());
253+
254+
Product temp = new Product(id,name,price,inv,min,max);
255+
temp.getAllAssociatedParts().addAll(bottomTable);
109256

257+
Inventory.updateProduct(temp);
110258

111259
stage = (Stage)((Button)event.getSource()).getScene().getWindow();
112260
scene = FXMLLoader.load(Objects.requireNonNull(getClass().getResource("MainWindow.fxml")));
@@ -115,15 +263,77 @@ void onActionSave(ActionEvent event) throws IOException {
115263
}
116264

117265
@FXML
118-
public void onActionAdd(ActionEvent actionEvent) {
266+
void onActionAdd(ActionEvent event) throws IOException {
267+
268+
if(!table1.getSelectionModel().isEmpty()) {
269+
bottomTable.add(table1.getSelectionModel().getSelectedItem());
270+
populateTable2(bottomTable);
271+
} else {
272+
errorMessage("Please select a part.");
273+
}
119274
}
120-
@FXML
121275
public void onActionRemove(ActionEvent actionEvent) {
276+
277+
boolean success = false;
278+
279+
if(!table2.getSelectionModel().isEmpty() && confirmation()){
280+
bottomTable.remove(table2.getSelectionModel().getSelectedItem());
281+
populateTable2(bottomTable);
282+
success = true;
283+
}
284+
285+
if(!success) {
286+
errorMessage("We did not remove a part.");
287+
}
288+
}
289+
290+
public void sendProduct(Product product){
291+
292+
productIDText.setPromptText(String.valueOf(product.getId()));
293+
productNameText.setText(product.getName());
294+
inventoryText.setText(String.valueOf(product.getStock()));
295+
priceText.setText(String.valueOf(product.getPrice()));
296+
maxText.setText(String.valueOf(product.getMax()));
297+
minText.setText(String.valueOf(product.getMin()));
298+
299+
if(!product.getAllAssociatedParts().isEmpty()){
300+
301+
bottomTable.addAll(product.getAllAssociatedParts());
302+
populateTable2(bottomTable);
303+
}
304+
}
305+
306+
private void populateTable1(ObservableList<Part> parts){
307+
308+
table1.setItems(parts);
309+
310+
table1IDCol.setCellValueFactory(new PropertyValueFactory<>("id"));
311+
table1NameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
312+
table1InvCol.setCellValueFactory(new PropertyValueFactory<>("stock"));
313+
table1InvCol.setCellValueFactory(new PropertyValueFactory<>("price"));
314+
}
315+
316+
private void populateTable2(ObservableList<Part> parts) {
317+
318+
table2.setItems(parts);
319+
320+
table2IDCol.setCellValueFactory(new PropertyValueFactory<>("id"));
321+
table2NameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
322+
table2InvCol.setCellValueFactory(new PropertyValueFactory<>("stock"));
323+
table2InvCol.setCellValueFactory(new PropertyValueFactory<>("price"));
122324
}
123325

124326
@Override
125327
public void initialize(URL url, ResourceBundle resourceBundle) {
126-
127-
System.out.println("initialized");
328+
productIDText.setPromptText(String.valueOf(generateID()));
329+
table2.getItems().clear();
330+
populateTable1(Inventory.getAllParts());
331+
332+
searchProductText.setOnAction(new EventHandler<ActionEvent>() {
333+
@Override
334+
public void handle(ActionEvent actionEvent) {
335+
populateTable1(filterParts());
336+
}
337+
});
128338
}
129339
}

0 commit comments

Comments
 (0)