feat: extract abstract OrderedEditableListCell<T>
Abstracts the editable list cell code to make it extendable. Also includes fix for index (now starts at 1)
This commit is contained in:
parent
40d157cc6c
commit
5dd6c89f73
4 changed files with 86 additions and 149 deletions
|
|
@ -1,78 +1,18 @@
|
||||||
package client.scenes.recipe;
|
package client.scenes.recipe;
|
||||||
|
|
||||||
import javafx.scene.control.ListCell;
|
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.input.KeyCode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom ListCell for displaying and editing ingredients in an
|
* A custom {@link OrderedEditableListCell<String>} for displaying and editing ingredients in an
|
||||||
* IngredientList. Allows inline editing of ingredient names.
|
* IngredientList. Allows inline editing of ingredient names.
|
||||||
*
|
*
|
||||||
* @see IngredientListCtrl
|
* @see IngredientListCtrl
|
||||||
*/
|
*/
|
||||||
public class IngredientListCell extends ListCell<String> {
|
public class IngredientListCell extends OrderedEditableListCell<String> {
|
||||||
// TODO: change all this to use actual Ingredient objects
|
// TODO: change all this to use actual Ingredient objects
|
||||||
// and all that :)
|
// and all that :)
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(String item, boolean empty) {
|
protected String fromInput(TextField inputField) {
|
||||||
super.updateItem(item, empty);
|
return inputField.getText();
|
||||||
|
|
||||||
if (empty || item == null) {
|
|
||||||
this.setText(null);
|
|
||||||
} else {
|
|
||||||
this.setText(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startEdit() {
|
|
||||||
super.startEdit();
|
|
||||||
|
|
||||||
TextField textField = new TextField(this.getItem());
|
|
||||||
|
|
||||||
// Commit edit on Enter key press
|
|
||||||
textField.setOnAction(event -> {
|
|
||||||
this.commitEdit(textField.getText());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Cancel edit on Escape key press
|
|
||||||
textField.setOnKeyReleased(event -> {
|
|
||||||
if (event.getCode() == KeyCode.ESCAPE) {
|
|
||||||
this.cancelEdit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setText(null);
|
|
||||||
this.setGraphic(textField);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the input is valid (non-empty).
|
|
||||||
*
|
|
||||||
* @param input The input string to validate.
|
|
||||||
* @return true if valid, false otherwise.
|
|
||||||
*/
|
|
||||||
private boolean isInputValid(String input) {
|
|
||||||
return input != null && !input.trim().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelEdit() {
|
|
||||||
super.cancelEdit();
|
|
||||||
|
|
||||||
this.setText(this.getItem());
|
|
||||||
this.setGraphic(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void commitEdit(String newValue) {
|
|
||||||
this.setGraphic(null);
|
|
||||||
|
|
||||||
if (!isInputValid(newValue)) {
|
|
||||||
newValue = this.getItem(); // Revert to old value if input is invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
super.commitEdit(newValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ public class IngredientListCtrl implements Initializable {
|
||||||
this.ingredientListView.setEditable(true);
|
this.ingredientListView.setEditable(true);
|
||||||
this.ingredientListView.setCellFactory(
|
this.ingredientListView.setCellFactory(
|
||||||
list -> {
|
list -> {
|
||||||
return new RecipeStepListCell();
|
return new IngredientListCell();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ingredientListView.setOnEditCommit(this::handleIngredientEdit);
|
this.ingredientListView.setOnEditCommit(this::handleIngredientEdit);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,78 @@
|
||||||
|
package client.scenes.recipe;
|
||||||
|
|
||||||
|
import javafx.scene.control.ListCell;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.input.KeyCode;
|
||||||
|
|
||||||
|
public abstract class OrderedEditableListCell<T> extends ListCell<T> {
|
||||||
|
/**
|
||||||
|
* Get the display text for the given item, prefixed with its index.
|
||||||
|
* Looks like "1. description".
|
||||||
|
*
|
||||||
|
* @param item The description.
|
||||||
|
* @return The display text.
|
||||||
|
*/
|
||||||
|
private String getDisplayText(String item) {
|
||||||
|
return (this.getIndex() + 1) + ". " + item;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void updateItem(T item, boolean empty) {
|
||||||
|
super.updateItem(item, empty);
|
||||||
|
|
||||||
|
if (empty || item == null) {
|
||||||
|
this.setText(null);
|
||||||
|
} else {
|
||||||
|
this.setText(this.getDisplayText(item.toString()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void startEdit() {
|
||||||
|
super.startEdit();
|
||||||
|
|
||||||
|
TextField textField = new TextField(this.getItem().toString());
|
||||||
|
|
||||||
|
// Commit edit on Enter key press
|
||||||
|
textField.setOnAction(event -> {
|
||||||
|
this.commitEdit(fromInput(textField));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cancel edit on Escape key press
|
||||||
|
textField.setOnKeyReleased(event -> {
|
||||||
|
if (event.getCode() == KeyCode.ESCAPE) {
|
||||||
|
this.cancelEdit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setText(null);
|
||||||
|
this.setGraphic(textField);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract T fromInput(TextField inputField);
|
||||||
|
/**
|
||||||
|
* Check if the input is valid (non-empty).
|
||||||
|
*
|
||||||
|
* @param input The input string to validate.
|
||||||
|
* @return true if valid, false otherwise.
|
||||||
|
*/
|
||||||
|
private boolean isInputValid(String input) {
|
||||||
|
return input != null && !input.trim().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelEdit() {
|
||||||
|
super.cancelEdit();
|
||||||
|
|
||||||
|
this.setText(this.getItem().toString());
|
||||||
|
this.setGraphic(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commitEdit(T newValue) {
|
||||||
|
this.setGraphic(null);
|
||||||
|
|
||||||
|
if (!isInputValid(newValue.toString())) {
|
||||||
|
newValue = this.getItem(); // Revert to old value if input is invalid
|
||||||
|
}
|
||||||
|
|
||||||
|
super.commitEdit(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,96 +1,15 @@
|
||||||
package client.scenes.recipe;
|
package client.scenes.recipe;
|
||||||
|
|
||||||
import javafx.scene.control.ListCell;
|
|
||||||
import javafx.scene.control.TextField;
|
import javafx.scene.control.TextField;
|
||||||
import javafx.scene.input.KeyCode;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom ListCell for displaying and editing ingredients in an
|
* A custom ListCell for displaying and editing ingredients in an
|
||||||
* RecipeStepList. Allows inline editing of ingredient names.
|
* RecipeStepList. Allows inline editing of ingredient names.
|
||||||
*
|
*
|
||||||
* @see RecipeStepListCtrl
|
* @see RecipeStepListCtrl
|
||||||
*/
|
*/
|
||||||
public class RecipeStepListCell extends ListCell<String> {
|
public class RecipeStepListCell extends OrderedEditableListCell<String> {
|
||||||
/**
|
|
||||||
* Get the display text for the given item, prefixed with its index.
|
|
||||||
* Looks like "1. Step description".
|
|
||||||
*
|
|
||||||
* @param item The step description.
|
|
||||||
* @return The display text.
|
|
||||||
*/
|
|
||||||
private String getDisplayText(String item) {
|
|
||||||
return this.getIndex() + ". " + item;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the display text for the current item.
|
|
||||||
* Looks like "1. Step description".
|
|
||||||
*
|
|
||||||
* @return The display text.
|
|
||||||
*/
|
|
||||||
private String getDisplayText() {
|
|
||||||
return this.getDisplayText(this.getItem());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(String item, boolean empty) {
|
protected String fromInput(TextField inputField) {
|
||||||
super.updateItem(item, empty);
|
return inputField.getText();
|
||||||
|
|
||||||
if (empty || item == null) {
|
|
||||||
this.setText(null);
|
|
||||||
} else {
|
|
||||||
this.setText(this.getDisplayText(item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startEdit() {
|
|
||||||
super.startEdit();
|
|
||||||
|
|
||||||
TextField textField = new TextField(this.getItem());
|
|
||||||
|
|
||||||
// Commit edit on Enter key press
|
|
||||||
textField.setOnAction(event -> {
|
|
||||||
this.commitEdit(textField.getText());
|
|
||||||
});
|
|
||||||
|
|
||||||
// Cancel edit on Escape key press
|
|
||||||
textField.setOnKeyReleased(event -> {
|
|
||||||
if (event.getCode() == KeyCode.ESCAPE) {
|
|
||||||
this.cancelEdit();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setText(null);
|
|
||||||
this.setGraphic(textField);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the input is valid (non-empty).
|
|
||||||
*
|
|
||||||
* @param input The input string to validate.
|
|
||||||
* @return true if valid, false otherwise.
|
|
||||||
*/
|
|
||||||
private boolean isInputValid(String input) {
|
|
||||||
return input != null && !input.trim().isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelEdit() {
|
|
||||||
super.cancelEdit();
|
|
||||||
|
|
||||||
this.setText(this.getDisplayText());
|
|
||||||
this.setGraphic(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void commitEdit(String newValue) {
|
|
||||||
this.setGraphic(null);
|
|
||||||
|
|
||||||
if (!isInputValid(newValue)) {
|
|
||||||
newValue = this.getItem(); // Revert to old value if input is invalid
|
|
||||||
}
|
|
||||||
|
|
||||||
super.commitEdit(newValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue