Compare commits

...

9 commits

Author SHA1 Message Date
b61100f3f9
#27: WIP
All checks were successful
Quality Check / Linting Check (push) Successful in 16s
Quality Check / Linting Check (pull_request) Successful in 23s
Quality Check / Javadoc Check (push) Successful in 39s
Quality Check / Javadoc Check (pull_request) Successful in 36s
Signed-off-by: Dominik Säume <Dominik.Saeume@hmmh.de>
2024-05-22 19:38:24 +02:00
97373930ec Merge pull request 'NOTICKET: Bugfix for Treatment locking' (#52) from bugfixes into main
All checks were successful
Quality Check / Linting Check (push) Successful in 19s
Javadoc Deploy / Javadoc (push) Successful in 36s
Quality Check / Javadoc Check (push) Successful in 34s
Reviewed-on: #52
2024-05-22 17:15:36 +00:00
a437b00921 NOTICKET: Bugfix for Treatment locking
All checks were successful
Quality Check / Linting Check (push) Successful in 29s
Quality Check / Linting Check (pull_request) Successful in 30s
Quality Check / Javadoc Check (push) Successful in 49s
Quality Check / Javadoc Check (pull_request) Successful in 47s
Signed-off-by: Dominik Säume <Dominik.Saeume@hmmh.de>
2024-05-22 16:57:03 +00:00
efea16e5b1 Merge pull request '#24 story/medikamente-als-veraltet-markieren' (#46) from story/medikamente-als-veraltet-markieren into main
All checks were successful
Quality Check / Linting Check (push) Successful in 19s
Quality Check / Javadoc Check (push) Successful in 32s
Javadoc Deploy / Javadoc (push) Successful in 20s
Reviewed-on: #46
Reviewed-by: SZUT-Ole <ole.kueck@hmmh.de>
Reviewed-by: Dominik Säume <dominik.saeume@hmmh.de>
2024-05-22 16:52:01 +00:00
Dorian Nemec
db572dfa95
#24: Javadoc & Cleanup
All checks were successful
Quality Check / Linting Check (push) Successful in 18s
Quality Check / Linting Check (pull_request) Successful in 23s
Quality Check / Javadoc Check (push) Successful in 39s
Quality Check / Javadoc Check (pull_request) Successful in 37s
Signed-off-by: Dominik Säume <Dominik.Saeume@hmmh.de>
2024-05-22 18:49:53 +02:00
Dorian Nemec
02232cd27f
#24: Implement Deprecated and Available medications 2024-05-22 17:50:07 +02:00
arminribic
e584e220a5
#24: Logik implementiert und UI fertig gestellt 2024-05-22 17:47:19 +02:00
Dorian Nemec
9fac5b34a3
#24: Implemented isDeprecated in Dao 2024-05-22 17:46:40 +02:00
Dorian Nemec
6300509873
#24: UI Veraltete Medikamenten addiert 2024-05-22 17:46:25 +02:00
18 changed files with 962 additions and 125 deletions

Binary file not shown.

View file

@ -12,6 +12,12 @@ import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import de.hitec.nhplus.Main;
import de.hitec.nhplus.datastorage.DaoFactory;
import de.hitec.nhplus.medication.Ingredient;
import de.hitec.nhplus.medication.Medication;
import de.hitec.nhplus.medication.database.MedicationDao;
/**
* {@link Fixture} for {@link Medication}.
*
@ -20,11 +26,13 @@ import java.util.*;
public class MedicationFixture implements Fixture<Medication> {
private static final String SCHEMA = "/de/hitec/nhplus/medication/database/Medication.sql";
private static final String INGREDIENT_SCHEMA = "/de/hitec/nhplus/medication/database/Medication_Ingredient.sql";
private static final String ALTERNATIVE_SCHEMA = "/de/hitec/nhplus/medication/database/Medication_Alternative.sql";
@Override
public void dropTable(Connection connection) throws SQLException {
connection.createStatement().execute("DROP TABLE IF EXISTS medication");
connection.createStatement().execute("DROP TABLE IF EXISTS medication_ingredient");
connection.createStatement().execute("DROP TABLE IF EXISTS medication_ingredient");
connection.createStatement().execute("DROP TABLE IF EXISTS medication_alternative");
}
@Override
@ -32,16 +40,25 @@ public class MedicationFixture implements Fixture<Medication> {
final InputStream schema = Main.class.getResourceAsStream(SCHEMA);
final InputStream ingredientSchema = Main.class.getResourceAsStream(INGREDIENT_SCHEMA);
final InputStream alternativeSchema = Main.class.getResourceAsStream(ALTERNATIVE_SCHEMA);
assert schema != null;
assert ingredientSchema != null;
assert alternativeSchema != null;
String SQL = new Scanner(schema, StandardCharsets.UTF_8)
.useDelimiter("\\A")
.next();
.useDelimiter("\\A")
.next();
String ingredientSQL = ";" + new Scanner(ingredientSchema, StandardCharsets.UTF_8)
.useDelimiter("\\A")
.next();
.useDelimiter("\\A")
.next();
String alternativeSQL = ";" + new Scanner(alternativeSchema, StandardCharsets.UTF_8)
.useDelimiter("\\A")
.next();
connection.createStatement().execute(SQL);
connection.createStatement().execute(ingredientSQL);
connection.createStatement().execute(alternativeSQL);
}
@ -67,57 +84,61 @@ public class MedicationFixture implements Fixture<Medication> {
Ingredient warfarinnatrium = new Ingredient("Warfarinnatrium");
medications.add(new Medication(
"Metformin",
"AstraZeneca",
List.of(
metforminhydrochlorid,
cellulose,
povidon,
magnesiumstearat
),
"Übelkeit, Durchfall, Laktatazidose (selten)",
"Oral",
100
"Metformin",
"AstraZeneca",
List.of(
metforminhydrochlorid,
cellulose,
povidon,
magnesiumstearat
),
"Übelkeit, Durchfall, Laktatazidose (selten)",
"Oral",
100,
new ArrayList<>()
));
medications.add(new Medication(
"Lisinopril",
"Teva Pharmaceuticals",
List.of(
lisinoprilDihydrat,
mannitol,
calciumphosphat,
magnesiumstearat
),
"Schwindel, trockener Husten",
"Oral",
150
"Lisinopril",
"Teva Pharmaceuticals",
List.of(
lisinoprilDihydrat,
mannitol,
calciumphosphat,
magnesiumstearat
),
"Schwindel, trockener Husten",
"Oral",
150,
new ArrayList<>()
));
medications.add(new Medication(
"Simvastatin",
"Mylan",
List.of(
simvastatin,
laktose,
cellulose,
magnesiumstearat
),
"Muskelschmerzen, Leberprobleme(selten)",
"Oral",
80
"Simvastatin",
"Mylan",
List.of(
simvastatin,
laktose,
cellulose,
magnesiumstearat
),
"Muskelschmerzen, Leberprobleme(selten)",
"Oral",
80,
new ArrayList<>()
));
medications.add(new Medication(
"Enoxaparin",
"Sanofi",
List.of(
enoxaparinNatrium,
benzylalkohol,
wasser
),
"Blutungen, Reaktionen an der Injektionsstelle",
"Unterhautinjektion",
120
"Enoxaparin",
"Sanofi",
List.of(
enoxaparinNatrium,
benzylalkohol,
wasser
),
"Blutungen, Reaktionen an der Injektionsstelle",
"Unterhautinjektion",
120,
new ArrayList<>()
));
medications.add(new Medication(
Medication deprecatedMedication = new Medication(
"Levothyroxin",
"Sandoz",
List.of(
@ -128,25 +149,43 @@ public class MedicationFixture implements Fixture<Medication> {
),
"Herzrasen, Gewichtsverlust",
"Oral",
90
));
90,
new ArrayList<>()
);
deprecatedMedication.setIsDeprecated(true);
medications.add(deprecatedMedication);
medications.add(new Medication(
"Warfarin",
"Apotex Inc.",
List.of(
warfarinnatrium,
laktose,
staerke,
magnesiumstearat
),
"Blutungen, Blutergüsse",
"Oral",
110
"Warfarin",
"Apotex Inc.",
List.of(
warfarinnatrium,
laktose,
staerke,
magnesiumstearat
),
"Blutungen, Blutergüsse",
"Oral",
110,
new ArrayList<>()
));
MedicationDao dao = DaoFactory.getInstance().createMedicationDAO();
Map<String, Medication> medicationsByName = new HashMap<>();
for (Medication medication : medications) {
dao.create(medication);
}
List<Medication> createdMedications = dao.readAll();
Map<String, Medication> medicationsByName = new HashMap<>();
for (Medication medication : createdMedications){
switch (medication.getName()){
case "Warfarin":
medication.setAlternativeMedication(List.of(
createdMedications.get(0),
createdMedications.get(3)
));
break;
default:
break;
}
dao.update(medication);
medicationsByName.put(medication.getName(), medication);
}
return medicationsByName;

View file

@ -80,10 +80,16 @@ public class MainWindowController {
Permissions.MANAGEMENT | Permissions.OWNER
)
));
tabManager.setupTab(mainTabPane, new TabStruct(
"Medikamente",
"/de/hitec/nhplus/medication/AllMedicationView.fxml",
Permissions.MANAGEMENT
tabManager.setupSubTabPane(mainTabPane, "Medikamente", Permissions.MANAGEMENT, List.of(
new TabStruct(
"Medikamente",
"/de/hitec/nhplus/medication/AllMedicationView.fxml",
Permissions.MANAGEMENT
), new TabStruct(
"Veraltete Medikamente",
"/de/hitec/nhplus/medication/DeprecatedMedicationView.fxml",
Permissions.MANAGEMENT
)
));

View file

@ -7,6 +7,8 @@ import java.util.stream.Collectors;
import de.hitec.nhplus.Main;
import de.hitec.nhplus.datastorage.DaoFactory;
import de.hitec.nhplus.login.Permissions;
import de.hitec.nhplus.main.MainWindowController;
import de.hitec.nhplus.medication.database.MedicationDao;
import de.hitec.nhplus.nurse.Nurse;
import de.hitec.nhplus.patient.Patient;
@ -15,9 +17,11 @@ import de.hitec.nhplus.treatment.TreatmentModalController;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.SelectionModel;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
@ -48,16 +52,32 @@ public class AllMedicationController {
private TableColumn<Medication, String> columnAdministrationMethod;
@FXML
private TableColumn<Medication, Integer> columnCurrentStock;
@FXML
public TableColumn<Medication, String> columnAlternativeMedication;
@FXML
public Button buttonChangeAvailable;
@FXML
public Button buttonAdd;
@FXML
public Button buttonDelete;
private final ObservableList<Medication> medications = FXCollections.observableArrayList();
private MedicationDao dao;
private boolean hasEditPermissions;
public MedicationDao getDao() {
return dao;
}
/**
* Initialization method that is called after the binding of all the fields.
*/
@FXML
public void initialize() {
readAllAndShowInTableView();
int editPermissions = Permissions.MANAGEMENT | Permissions.OWNER;
int userPermissions = MainWindowController.getInstance().getUser().getPermissions();
hasEditPermissions = (userPermissions & editPermissions) != 0;
this.readAllAndShowInTableView();
this.columnId.setCellValueFactory(new PropertyValueFactory<>("id"));
this.columnName.setCellValueFactory(new PropertyValueFactory<>("name"));
@ -73,15 +93,38 @@ public class AllMedicationController {
return new SimpleStringProperty(
ingredients
.stream()
.map(ingredient -> ingredient.getName())
.map(Ingredient::getName)
.collect(Collectors.joining("\n"))
);
});
this.columnPossibleSideEffects.setCellValueFactory(new PropertyValueFactory<>("possibleSideEffects"));
this.columnAdministrationMethod.setCellValueFactory(new PropertyValueFactory<>("administrationMethod"));
this.columnCurrentStock.setCellValueFactory(new PropertyValueFactory<>("currentStock"));
this.columnAlternativeMedication.setCellValueFactory(
cellData -> {
Medication medication = cellData.getValue();
List<Medication> alternatives = medication.getAlternativeMedication();
if (alternatives.isEmpty()) {
return new SimpleStringProperty("");
}
return new SimpleStringProperty(
alternatives
.stream()
.map(med -> med.getName() + ", " + med.getManufacturer())
.collect(Collectors.joining("\n"))
);
}
);
this.tableView.setItems(this.medications);
if (!hasEditPermissions) {
this.buttonAdd.setDisable(true);
this.buttonDelete.setDisable(true);
this.buttonChangeAvailable.setDisable(true);
}
}
/**
@ -90,7 +133,7 @@ public class AllMedicationController {
public void readAllAndShowInTableView() {
this.dao = DaoFactory.getInstance().createMedicationDAO();
try {
this.medications.setAll(dao.readAll());
this.medications.setAll(dao.readAllAvailable());
} catch (SQLException exception) {
exception.printStackTrace();
}
@ -120,6 +163,38 @@ public class AllMedicationController {
}
}
@FXML
public void handleChangeAvailable() {
Medication selectedItem = this.tableView.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
try {
selectedItem.setIsDeprecated(true);
this.dao.update(selectedItem);
} catch (SQLException exception) {
exception.printStackTrace();
}
this.readAllAndShowInTableView();
}
@FXML
public void handleDelete() {
Medication selectedItem = this.tableView.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
try {
this.dao.delete(selectedItem.getId());
} catch (SQLException exception) {
exception.printStackTrace();
}
this.readAllAndShowInTableView();
}
/**
* Internal method to create a {@link MedicationModalController MedicationModal}.
*

View file

@ -0,0 +1,108 @@
package de.hitec.nhplus.medication;
import de.hitec.nhplus.datastorage.DaoFactory;
import de.hitec.nhplus.medication.database.MedicationDao;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
/**
* The controller for viewing all deprecated {@link Medication}s.
*
* @author Armin Ribic
* @author Dorian Nemec
*/
public class DeprecatedMedicationController {
@FXML
private TableView<Medication> tableView;
@FXML
private TableColumn<Medication, Integer> columnId;
@FXML
private TableColumn<Medication, String> columnName;
@FXML
private TableColumn<Medication, String> columnManufacturer;
@FXML
private TableColumn<Medication, String> columnIngredient;
@FXML
private TableColumn<Medication, String> columnPossibleSideEffects;
@FXML
private TableColumn<Medication, String> columnAdministrationMethod;
@FXML
private TableColumn<Medication, Integer> columnCurrentStock;
@FXML
public Button buttonChangeAvailable;
private final ObservableList<Medication> medications = FXCollections.observableArrayList();
private MedicationDao dao;
/**
* Initialization method that is called after the binding of all the fields.
*/
public void initialize() {
this.readAllAndShowInTableView();
this.columnId.setCellValueFactory(new PropertyValueFactory<>("id"));
this.columnName.setCellValueFactory(new PropertyValueFactory<>("name"));
this.columnManufacturer.setCellValueFactory(new PropertyValueFactory<>("manufacturer"));
this.columnIngredient.setCellValueFactory(
cellData -> {
Medication medication = cellData.getValue();
List<Ingredient> ingredients = medication.getIngredients();
if (ingredients.isEmpty()) {
return new SimpleStringProperty("");
}
return new SimpleStringProperty(
ingredients
.stream()
.map(ingredient -> ingredient.getName())
.collect(Collectors.joining("\n"))
);
});
this.columnPossibleSideEffects.setCellValueFactory(new PropertyValueFactory<>("possibleSideEffects"));
this.columnAdministrationMethod.setCellValueFactory(new PropertyValueFactory<>("administrationMethod"));
this.columnCurrentStock.setCellValueFactory(new PropertyValueFactory<>("currentStock"));
this.tableView.setItems(this.medications);
}
/**
* Internal method to read all data and set it to the table view.
*/
public void readAllAndShowInTableView() {
this.medications.clear();
this.dao = DaoFactory.getInstance().createMedicationDAO();
try {
this.medications.setAll(this.dao.readAllDeprecated());
} catch (SQLException exception) {
exception.printStackTrace();
}
}
@FXML
public void handleChangeAvailable() {
Medication selectedItem = tableView.getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
try {
selectedItem.setIsDeprecated(false);
this.dao.update(selectedItem);
} catch (SQLException exception) {
exception.printStackTrace();
}
this.readAllAndShowInTableView();
}
}

View file

@ -1,5 +1,6 @@
package de.hitec.nhplus.medication;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.property.SimpleStringProperty;
@ -17,12 +18,14 @@ import java.util.stream.Collectors;
*/
public class Medication {
private SimpleIntegerProperty id;
private final SimpleStringProperty name;
private final SimpleStringProperty manufacturer;
private final SimpleListProperty<Ingredient> ingredients;
private final SimpleStringProperty possibleSideEffects;
private final SimpleStringProperty administrationMethod;
private final SimpleIntegerProperty currentStock;
private SimpleStringProperty name;
private SimpleStringProperty manufacturer;
private SimpleListProperty<Ingredient> ingredients;
private SimpleStringProperty possibleSideEffects;
private SimpleStringProperty administrationMethod;
private SimpleIntegerProperty currentStock;
private SimpleListProperty<Medication> alternativeMedication;
private SimpleBooleanProperty isDeprecated;
/**
* This constructor allows instantiating a {@link Medication} object,
@ -37,7 +40,8 @@ public class Medication {
List<Ingredient> ingredients,
String possibleSideEffects,
String administrationMethod,
int currentStock
int currentStock,
List<Medication> alternativeMedication
) {
this.name = new SimpleStringProperty(name);
this.manufacturer = new SimpleStringProperty(manufacturer);
@ -45,6 +49,8 @@ public class Medication {
this.possibleSideEffects = new SimpleStringProperty(possibleSideEffects);
this.administrationMethod = new SimpleStringProperty(administrationMethod);
this.currentStock = new SimpleIntegerProperty(currentStock);
this.alternativeMedication = new SimpleListProperty<>(FXCollections.observableArrayList(alternativeMedication));
this.isDeprecated = new SimpleBooleanProperty(false);
}
/**
@ -57,7 +63,9 @@ public class Medication {
List<Ingredient> ingredients,
String possibleSideEffects,
String administrationMethod,
int currentStock
int currentStock,
List<Medication> alternativeMedication,
boolean isDeprecated
) {
this.id = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(name);
@ -66,6 +74,23 @@ public class Medication {
this.possibleSideEffects = new SimpleStringProperty(possibleSideEffects);
this.administrationMethod = new SimpleStringProperty(administrationMethod);
this.currentStock = new SimpleIntegerProperty(currentStock);
this.alternativeMedication = new SimpleListProperty<>(FXCollections.observableArrayList(alternativeMedication));
this.isDeprecated = new SimpleBooleanProperty(isDeprecated);
}
public void replace(Medication medication){
if(medication == null){
return;
}
this.id = medication.idProperty();
this.name = medication.nameProperty();
this.manufacturer = medication.manufacturerProperty();
this.ingredients = medication.ingredientsProperty();
this.possibleSideEffects = medication.possibleSideEffectsProperty();
this.administrationMethod = medication.administrationMethodProperty();
this.currentStock = medication.currentStockProperty();
this.alternativeMedication = medication.alternativeMedicationProperty();
this.isDeprecated = medication.isDeprecatedProperty();
}
public int getId() {
@ -84,6 +109,18 @@ public class Medication {
return name;
}
public boolean isDeprecated() {
return isDeprecated.get();
}
public SimpleBooleanProperty isDeprecatedProperty() {
return isDeprecated;
}
public void setIsDeprecated(boolean isDeprecated) {
this.isDeprecated.set(isDeprecated);
}
public void setName(String name) {
this.name.set(name);
}
@ -124,6 +161,18 @@ public class Medication {
this.possibleSideEffects.set(possibleSideEffects);
}
public ObservableList<Medication> getAlternativeMedication() {
return alternativeMedication.get();
}
public SimpleListProperty<Medication> alternativeMedicationProperty() {
return alternativeMedication;
}
public void setAlternativeMedication(List<Medication> alternativeMedication) {
this.alternativeMedication.set(FXCollections.observableArrayList(alternativeMedication));
}
public String getAdministrationMethod() {
return administrationMethod.get();
}
@ -162,6 +211,14 @@ public class Medication {
.add("Possible Side Effects: " + this.getPossibleSideEffects())
.add("Administration Method: " + this.getAdministrationMethod())
.add("Current Stock: " + this.getCurrentStock())
.add("Alternative Medication" + this.getAlternativeMedication())
.toString();
}
public String getComboBoxString() {
return new StringJoiner(System.lineSeparator())
.add("Name: " + this.getName())
.add("Hersteller: " + this.getManufacturer())
.toString();
}
}

View file

@ -0,0 +1,146 @@
package de.hitec.nhplus.medication;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Text;
import org.controlsfx.control.SearchableComboBox;
import java.util.List;
/**
* A custom implementation of the {@link ListCell} for {@link Ingredient}s.
* This implementation contains an automatic resizing of the parent {@link ListView}.
*
* @author Dominik Säume
*/
public class MedicationListCell extends ListCell<Medication> {
private final Button deleteButton;
private final SearchableComboBox<Medication> comboBox;
private static final double BUILTIN_BORDER_WIDTH = 1;
private static final double CELL_SPACING = 4;
private static final double CELL_PADDING = 4;
private static final double BUTTON_PADDING_X = 8;
private static final double BUTTON_PADDING_Y = 4;
private final double totalSpacing;
private boolean firstUpdate = true;
public MedicationListCell(List<Medication> allOtherMedications) {
this.setPadding(new Insets(CELL_PADDING));
comboBox = new SearchableComboBox<>();
ObservableList<Medication> list = FXCollections.observableArrayList();
list.setAll(allOtherMedications);
comboBox.setItems(list);
comboBox.setPromptText("Alternatve Auswählen");
comboBox.setCellFactory(this::comboBoxFactory);
comboBox.setButtonCell(comboBoxButtonFactory());
comboBox.valueProperty().addListener(this::onComboBoxChange);
deleteButton = new Button("-");
deleteButton.setPadding(new Insets(
BUTTON_PADDING_Y,
BUTTON_PADDING_X,
BUTTON_PADDING_Y,
BUTTON_PADDING_X
));
deleteButton.setOnAction(this::handleDeleteButton);
// Calculate Delete Button Width
Text textNode = new Text(deleteButton.getText());
textNode.setFont(deleteButton.getFont());
double calculatedDeleteButtonWidth = textNode.getLayoutBounds().getWidth() + BUTTON_PADDING_X * 2;
totalSpacing = BUILTIN_BORDER_WIDTH * 2 // List View
+ CELL_PADDING * 2
+ CELL_SPACING
+ calculatedDeleteButtonWidth;
}
/**
* A Callback for use as a Listener for the {@link MedicationListCell#comboBox}.
*/
private void onComboBoxChange(
ObservableValue<? extends Medication> observableValue,
Medication oldValue,
Medication newValue
) {
getItem().replace(comboBox.getValue());
ListView<Medication> listView = getListView();
double max = listView.lookupAll("*")
.stream()
.filter(node -> node instanceof MedicationListCell)
.mapToDouble(node -> comboBox.getWidth())
.max()
.orElse(0);
listView.setMinWidth(max + totalSpacing);
}
@Override
protected void updateItem(Medication item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setGraphic(null);
} else {
if (
firstUpdate
&& comboBox.getSelectionModel().getSelectedItem() == null
&& item.getName() != null
&& comboBox.getItems().contains(item)
) {
comboBox.getSelectionModel().select(item);
}
firstUpdate = false;
BorderPane cellPane = new BorderPane();
cellPane.setCenter(comboBox);
cellPane.setRight(deleteButton);
BorderPane.setMargin(deleteButton, new Insets(0, 0, 0, CELL_SPACING));
setGraphic(cellPane);
}
}
private ListCell comboBoxFactory(Object param) {
return new ListCell<Medication>() {
@Override
protected void updateItem(Medication med, boolean empty) {
super.updateItem(med, empty);
setText(
empty || med == null
? null
: med.getComboBoxString()
);
}
};
}
private ListCell comboBoxButtonFactory() {
return new ListCell<Medication>() {
@Override
protected void updateItem(Medication med, boolean empty) {
super.updateItem(med, empty);
setText(
empty || med == null
? comboBox.getPromptText()
: med.getComboBoxString()
);
}
};
}
private void handleDeleteButton(ActionEvent event) {
if (getItem() == null) {
getListView().getItems().remove(getItem());
}
}
}

View file

@ -1,6 +1,5 @@
package de.hitec.nhplus.medication;
import de.hitec.nhplus.treatment.Treatment;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
@ -13,7 +12,10 @@ import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static de.hitec.nhplus.utils.Validator.*;
@ -38,12 +40,17 @@ public class MedicationModalController {
public TextArea textAreaPossibleSideEffects;
@FXML
public Button buttonSave;
@FXML
public ListView<Medication> listViewAlternativeMedication;
private Stage stage;
private Medication medication;
private final ObservableList<Ingredient> ingredients = FXCollections.observableArrayList();
private final ObservableList<Medication> alternativeMediaction = FXCollections.observableArrayList();
private AllMedicationController controller;
private boolean isNewMedication = false;
private List<Medication> allOtherMedications;
/**
* Initialization method that is called after the binding of all the fields.
@ -67,15 +74,20 @@ public class MedicationModalController {
new ArrayList<>(),
"",
"",
0
0,
new ArrayList<>()
);
this.buttonSave.setDisable(true);
}
listViewIngredients.setCellFactory(cellData -> new IngredientListCell());
listViewIngredients.setItems(ingredients);
showData();
listViewAlternativeMedication.setCellFactory(cellData -> new MedicationListCell(allOtherMedications));
listViewAlternativeMedication.setItems(alternativeMediaction);
ChangeListener<String> inputMedicationValidationListener = (observableValue, oldText, newText) -> {
boolean isValid = isValidMedicationName(textFieldName.getText())
&& isValidMedicationManufacturer(textFieldManufacturer.getText())
@ -96,6 +108,22 @@ public class MedicationModalController {
*/
private void showData() {
ingredients.setAll(medication.getIngredients());
alternativeMediaction.setAll(medication.getAlternativeMedication());
Map<Integer, Medication> currentAlternatives = alternativeMediaction
.stream()
.collect(Collectors.toMap(Medication::getId, med -> med));
try {
allOtherMedications = controller.getDao().readAll();
if (!isNewMedication) {
allOtherMedications = allOtherMedications
.stream()
.filter(med -> med.getId() != medication.getId())
.map(med -> currentAlternatives.getOrDefault(med.getId(), med))
.toList();
}
} catch (Exception exception) {
exception.printStackTrace();
}
textFieldName.setText(medication.getName());
textFieldManufacturer.setText(medication.getManufacturer());
textFieldAdministrationMethod.setText(medication.getAdministrationMethod());
@ -119,6 +147,15 @@ public class MedicationModalController {
.toList()
);
this.medication.setAlternativeMedication(
alternativeMediaction
.stream()
.distinct()
.filter(Predicate.not(Objects::isNull))
.filter(Predicate.not(med -> med.idProperty() == null))
.toList()
);
if (isNewMedication) {
controller.createMedication(medication);
} else {
@ -138,4 +175,16 @@ public class MedicationModalController {
public void handleAddIngredient() {
ingredients.add(new Ingredient(""));
}
public void handleAddAlternativeMedication() {
alternativeMediaction.add(new Medication(
null,
null,
new ArrayList<>(),
null,
null,
-1,
new ArrayList<>()
));
}
}

View file

@ -8,10 +8,7 @@ import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
* The {@link MedicationDao} is an implementation of the{@link de.hitec.nhplus.datastorage.Dao Dao}
@ -32,8 +29,8 @@ public class MedicationDao implements Dao<Medication> {
connection.setAutoCommit(false); //Switch to Manual Commit, to do an SQL Transaction
final String medicationSQL = """
INSERT INTO medication
(name, manufacturer, possibleSideEffects, administrationMethod, currentStock)
VALUES (?, ?, ?, ?, ?);
(name, manufacturer, possibleSideEffects, administrationMethod, currentStock, isDeprecated)
VALUES (?, ?, ?, ?, ?, ?);
""";
PreparedStatement medicationStatement = this.connection.prepareStatement(medicationSQL);
medicationStatement.setString(1, medication.getName());
@ -41,6 +38,7 @@ public class MedicationDao implements Dao<Medication> {
medicationStatement.setString(3, medication.getPossibleSideEffects());
medicationStatement.setString(4, medication.getAdministrationMethod());
medicationStatement.setInt(5, medication.getCurrentStock());
medicationStatement.setBoolean(6, medication.isDeprecated());
medicationStatement.execute();
ResultSet generatedKeys = connection.createStatement().executeQuery("SELECT last_insert_rowid()");
@ -63,36 +61,45 @@ public class MedicationDao implements Dao<Medication> {
ingredientStatement.setString(2, ingredient.getName());
ingredientStatement.execute();
}
final String alternativeMedicationSQL = """
INSERT INTO medication_alternative
(id, alternativeId)
VALUES (?, ?);
""";
for (Medication alternative : medication.getAlternativeMedication()) {
PreparedStatement alternativeStatement = this.connection.prepareStatement(alternativeMedicationSQL);
alternativeStatement.setInt(1, newId);
alternativeStatement.setInt(2, alternative.getId());
alternativeStatement.execute();
}
}
@Override
public Medication read(int id) throws SQLException {
final String SQL = """
SELECT medication.*, medication_ingredient.id
FROM medication
LEFT JOIN medication_ingredient ON medication.id = medication_ingredient.id
WHERE medication.id = ?
""";
PreparedStatement statement = this.connection.prepareStatement(SQL);
statement.setInt(1, id);
ResultSet result = statement.executeQuery();
ResultSet result = getReadStatement(id).executeQuery();
return getInstanceFromResultSet(result);
}
@Override
public List<Medication> readAll() throws SQLException {
final String SQL = """
SELECT medication.*, medication_ingredient.name
FROM medication LEFT JOIN
SELECT medication.*, medication_ingredient.name, medication_alternative.alternativeId
FROM medication
LEFT JOIN
medication_ingredient ON medication.id = medication_ingredient.id
LEFT JOIN
medication_alternative ON medication.id = medication_alternative.id
""";
ResultSet result = connection.prepareStatement(SQL).executeQuery();
List<Medication> medications = new ArrayList<>();
Map<Integer, Medication> medications = new HashMap<>();
Map<Integer, List<Ingredient>> ingredientMap = new HashMap<>();
Map<Integer, Set<Integer>> alternativesMap = new HashMap<>();
int currentMedicationId;
int lastMedicationId = -1;
String latIngredient = "";
while (result.next()) {
currentMedicationId = result.getInt(1);
if (currentMedicationId != lastMedicationId) {
@ -103,27 +110,179 @@ public class MedicationDao implements Dao<Medication> {
new ArrayList<>(),
result.getString(4),
result.getString(5),
result.getInt(6)
result.getInt(6),
new ArrayList<>(),
result.getBoolean(7)
);
medications.add(medication);
medications.put(currentMedicationId, medication);
}
List<Ingredient> ingredients = ingredientMap.computeIfAbsent(currentMedicationId, k -> new ArrayList<>());
String ingredientName = result.getString(7);
if(ingredientName == null){
continue;
String ingredientName = result.getString(8);
if (ingredientName != null && !latIngredient.equals(ingredientName)) {
ingredients.add(new Ingredient(ingredientName));
latIngredient = ingredientName;
}
ingredients.add(new Ingredient(ingredientName));
Set<Integer> alternatives = alternativesMap.computeIfAbsent(currentMedicationId, k -> new HashSet<>());
int alternativeId = result.getInt(9);
if (alternativeId != 0) {
alternatives.add(alternativeId);
}
lastMedicationId = currentMedicationId;
}
for (Medication medication : medications) {
for (Medication medication : medications.values()) {
List<Ingredient> ingredients = ingredientMap.get(medication.getId());
if(ingredients.isEmpty()){
if (ingredients.isEmpty()) {
continue;
}
medication.setIngredients(ingredientMap.get(medication.getId()));
Set<Integer> alternativeIds = alternativesMap.get(medication.getId());
List<Medication> alternatives = new ArrayList<>();
for (Integer alternativeId : alternativeIds) {
alternatives.add(medications.get(alternativeId));
}
medication.setAlternativeMedication(alternatives);
}
return medications;
return medications.values().stream().toList();
}
public List<Medication> readAllAvailable() throws SQLException {
final String SQL = """
SELECT medication.*, medication_ingredient.name, medication_alternative.alternativeId
FROM medication
LEFT JOIN
medication_ingredient ON medication.id = medication_ingredient.id
LEFT JOIN
medication_alternative ON medication.id = medication_alternative.id
WHERE medication.isDeprecated = false
""";
ResultSet result = connection.prepareStatement(SQL).executeQuery();
Map<Integer, Medication> medications = new HashMap<>();
Map<Integer, List<Ingredient>> ingredientMap = new HashMap<>();
Map<Integer, Set<Integer>> alternativesMap = new HashMap<>();
int currentMedicationId;
int lastMedicationId = -1;
String latIngredient = "";
while (result.next()) {
currentMedicationId = result.getInt(1);
if (currentMedicationId != lastMedicationId) {
Medication medication = new Medication(
result.getInt(1),
result.getString(2),
result.getString(3),
new ArrayList<>(),
result.getString(4),
result.getString(5),
result.getInt(6),
new ArrayList<>(),
result.getBoolean(7)
);
medications.put(currentMedicationId, medication);
}
List<Ingredient> ingredients = ingredientMap.computeIfAbsent(currentMedicationId, k -> new ArrayList<>());
String ingredientName = result.getString(8);
if (ingredientName != null && !latIngredient.equals(ingredientName)) {
ingredients.add(new Ingredient(ingredientName));
latIngredient = ingredientName;
}
Set<Integer> alternatives = alternativesMap.computeIfAbsent(currentMedicationId, k -> new HashSet<>());
int alternativeId = result.getInt(9);
if (alternativeId != 0) {
alternatives.add(alternativeId);
}
lastMedicationId = currentMedicationId;
}
for (Medication medication : medications.values()) {
List<Ingredient> ingredients = ingredientMap.get(medication.getId());
if (ingredients.isEmpty()) {
continue;
}
medication.setIngredients(ingredientMap.get(medication.getId()));
Set<Integer> alternativeIds = alternativesMap.get(medication.getId());
List<Medication> alternatives = new ArrayList<>();
for (Integer alternativeId : alternativeIds) {
alternatives.add(medications.get(alternativeId));
}
medication.setAlternativeMedication(alternatives);
}
return medications.values().stream().toList();
}
public List<Medication> readAllDeprecated() throws SQLException {
final String SQL = """
SELECT medication.*, medication_ingredient.name, medication_alternative.alternativeId
FROM medication
LEFT JOIN
medication_ingredient ON medication.id = medication_ingredient.id
LEFT JOIN
medication_alternative ON medication.id = medication_alternative.id
WHERE medication.isDeprecated = true
""";
ResultSet result = connection.prepareStatement(SQL).executeQuery();
Map<Integer, Medication> medications = new HashMap<>();
Map<Integer, List<Ingredient>> ingredientMap = new HashMap<>();
Map<Integer, Set<Integer>> alternativesMap = new HashMap<>();
int currentMedicationId;
int lastMedicationId = -1;
String latIngredient = "";
while (result.next()) {
currentMedicationId = result.getInt(1);
if (currentMedicationId != lastMedicationId) {
Medication medication = new Medication(
result.getInt(1),
result.getString(2),
result.getString(3),
new ArrayList<>(),
result.getString(4),
result.getString(5),
result.getInt(6),
new ArrayList<>(),
result.getBoolean(7)
);
medications.put(currentMedicationId, medication);
}
List<Ingredient> ingredients = ingredientMap.computeIfAbsent(currentMedicationId, k -> new ArrayList<>());
String ingredientName = result.getString(8);
if (ingredientName != null && !latIngredient.equals(ingredientName)) {
ingredients.add(new Ingredient(ingredientName));
latIngredient = ingredientName;
}
Set<Integer> alternatives = alternativesMap.computeIfAbsent(currentMedicationId, k -> new HashSet<>());
int alternativeId = result.getInt(9);
if (alternativeId != 0) {
alternatives.add(alternativeId);
}
lastMedicationId = currentMedicationId;
}
for (Medication medication : medications.values()) {
List<Ingredient> ingredients = ingredientMap.get(medication.getId());
if (ingredients.isEmpty()) {
continue;
}
medication.setIngredients(ingredientMap.get(medication.getId()));
Set<Integer> alternativeIds = alternativesMap.get(medication.getId());
List<Medication> alternatives = new ArrayList<>();
for (Integer alternativeId : alternativeIds) {
alternatives.add(medications.get(alternativeId));
}
medication.setAlternativeMedication(alternatives);
}
return medications.values().stream().toList();
}
@Override
@ -134,7 +293,8 @@ public class MedicationDao implements Dao<Medication> {
manufacturer = ?,
possibleSideEffects = ?,
administrationMethod = ?,
currentStock = ?
currentStock = ?,
isDeprecated = ?
WHERE id = ?
""";
PreparedStatement preparedStatement = this.connection.prepareStatement(SQL);
@ -143,7 +303,8 @@ public class MedicationDao implements Dao<Medication> {
preparedStatement.setString(3, medication.getPossibleSideEffects());
preparedStatement.setString(4, medication.getAdministrationMethod());
preparedStatement.setInt(5, medication.getCurrentStock());
preparedStatement.setInt(6, medication.getId());
preparedStatement.setBoolean(6, medication.isDeprecated());
preparedStatement.setInt(7, medication.getId());
preparedStatement.executeUpdate();
final String ingredientDeleteSQL = """
@ -164,6 +325,25 @@ public class MedicationDao implements Dao<Medication> {
statement.setString(2, ingredient.getName());
statement.execute();
}
final String alternativeDeleteSQL = """
DELETE FROM medication_alternative WHERE id = ?
""";
PreparedStatement alternativeStatement = this.connection.prepareStatement(alternativeDeleteSQL);
alternativeStatement.setInt(1, medication.getId());
alternativeStatement.executeUpdate();
final String alternativeCreateSQL = """
INSERT INTO medication_alternative
(id, alternativeId)
VALUES (?, ?);
""";
for (Medication alternative : medication.getAlternativeMedication()) {
PreparedStatement statement = this.connection.prepareStatement(alternativeCreateSQL);
statement.setInt(1, medication.getId());
statement.setInt(2, alternative.getId());
statement.execute();
}
}
@Override
@ -176,6 +356,23 @@ public class MedicationDao implements Dao<Medication> {
preparedStatement.executeUpdate();
}
/**
* @param id The ID of the database entry to read.
* @return A {@link PreparedStatement} to read a specific entry by its ID.
*/
public PreparedStatement getReadStatement(int id) throws SQLException {
final String SQL = """
SELECT medication.*, medication_ingredient.name, medication_alternative.alternativeId
FROM medication
LEFT JOIN medication_ingredient ON medication.id = medication_ingredient.id
LEFT JOIN medication_alternative ON medication.id = medication_alternative.id
WHERE medication.id = ?
""";
PreparedStatement statement = this.connection.prepareStatement(SQL);
statement.setInt(1, id);
return statement;
}
/**
* Constructs a {@link Medication} object from the {@link ResultSet} obtained after executing a database query.
* This method is used internally to map the {@link ResultSet} data to a {@link Medication} object.
@ -188,18 +385,41 @@ public class MedicationDao implements Dao<Medication> {
result.getInt(1),
result.getString(2),
result.getString(3),
List.of(),
new ArrayList<>(),
result.getString(4),
result.getString(5),
result.getInt(6)
result.getInt(6),
new ArrayList<>(),
result.getBoolean(7)
);
List<Ingredient> ingredients = new ArrayList<>();
List<Medication> alternatives = new ArrayList<>();
while (result.next()) {
ingredients.add(new Ingredient(result.getString(2)));
String ingredientName = result.getString(8);
if (ingredientName != null) {
ingredients.add(new Ingredient(ingredientName));
}
int alternativeId = result.getInt(9);
if (alternativeId != 0) {
ResultSet alternativeResult = getReadStatement(alternativeId).executeQuery();
Medication alternativeMedication = new Medication(
alternativeResult.getInt(1),
alternativeResult.getString(2),
alternativeResult.getString(3),
new ArrayList<>(),
alternativeResult.getString(4),
alternativeResult.getString(5),
alternativeResult.getInt(6),
new ArrayList<>(),
alternativeResult.getBoolean(7)
);
alternatives.add(alternativeMedication);
}
}
medication.setIngredients(ingredients);
medication.setAlternativeMedication(alternatives);
return medication;
}
}

View file

@ -112,6 +112,4 @@ public class NurseDao extends DaoImp<Nurse> {
statement.setInt(1, id);
return statement;
}
}

View file

@ -78,7 +78,7 @@ public class AllTreatmentController {
*/
@FXML
public void initialize() {
readAllAndShowInTableView();
comboBoxPatientSelection.setItems(patientSelection);
comboBoxPatientSelection.getSelectionModel().select("alle");
@ -112,7 +112,7 @@ public class AllTreatmentController {
);
this.createComboBoxData();
readAllAndShowInTableView();
}
/**
@ -312,6 +312,8 @@ public class AllTreatmentController {
@FXML
public void handleLock(){
Treatment selectedItem = this.tableView.getSelectionModel().getSelectedItem();
LocalDate today = LocalDate.now();
if (selectedItem == null){
return;
}
@ -322,6 +324,13 @@ public class AllTreatmentController {
}catch (SQLException exception){
exception.printStackTrace();
}
if (selectedItem.calculateDeleteDate().isBefore(today) || selectedItem.calculateDeleteDate().equals(today)){
try {
dao.delete(selectedItem.getId());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
readAllAndShowInTableView();
}

View file

@ -3,6 +3,7 @@ module de.hitec.nhplus {
requires javafx.fxml;
requires java.sql;
requires org.xerial.sqlitejdbc;
requires org.controlsfx.controls;
exports de.hitec.nhplus;
opens de.hitec.nhplus to javafx.fxml;

View file

@ -49,6 +49,11 @@
minWidth="100.0"
text="Lagerbestand"
/>
<TableColumn
fx:id="columnAlternativeMedication"
minWidth="100.0"
text="Alternative Medikamente"
/>
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
@ -73,8 +78,16 @@
fx:id="buttonDelete"
mnemonicParsing="false"
prefWidth="90.0"
onAction="#handleDelete"
text="Löschen"
/>
<Button
fx:id="buttonChangeAvailable"
mnemonicParsing="false"
onAction="#handleChangeAvailable"
prefWidth="155.0"
text="Veraltet-Status ändern"
/>
</HBox>
</right>
</BorderPane>

View file

@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<BorderPane xmlns="http://javafx.com/javafx"
xmlns:fx="http://javafx.com/fxml"
fx:controller="de.hitec.nhplus.medication.DeprecatedMedicationController"
>
<padding>
<Insets top="8" left="8" right="8" bottom="8"/>
</padding>
<center>
<TableView fx:id="tableView">
<columns>
<TableColumn
fx:id="columnId"
minWidth="40.0"
text="ID"
/>
<TableColumn
fx:id="columnName"
minWidth="140.0"
text="Name"
/>
<TableColumn
fx:id="columnManufacturer"
minWidth="140.0"
text="Hersteller"
/>
<TableColumn
fx:id="columnIngredient"
minWidth="140.0"
text="Inhaltsstoffe"
/>
<TableColumn
fx:id="columnPossibleSideEffects"
minWidth="200.0"
text="Mögliche Nebenwirkungen"
/>
<TableColumn
fx:id="columnAdministrationMethod"
minWidth="180.0"
text="Verabreichungsmethode"
/>
<TableColumn
fx:id="columnCurrentStock"
minWidth="100.0"
text="Lagerbestand"
/>
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY"/>
</columnResizePolicy>
</TableView>
</center>
<bottom>
<BorderPane>
<BorderPane.margin>
<Insets top="8.0"/>
</BorderPane.margin>
<right>
<HBox spacing="8.0">
<Button
fx:id="buttonChangeAvailable"
mnemonicParsing="false"
prefWidth="155.0"
onAction="#handleChangeAvailable"
text="Veraltet-Status ändern"
/>
</HBox>
</right>
</BorderPane>
</bottom>
</BorderPane>

View file

@ -3,6 +3,7 @@
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import org.controlsfx.control.SearchableComboBox?>
<BorderPane
xmlns="http://javafx.com/javafx/17.0.2-ea"
xmlns:fx="http://javafx.com/fxml/1"
@ -77,16 +78,13 @@
</padding>
<left>
<BorderPane>
<BorderPane.margin>
<Insets right="8"/>
</BorderPane.margin>
<top>
<Label text="Inhaltsstoffe:"/>
</top>
<center>
<ListView fx:id="listViewIngredients" minWidth="200">
<BorderPane.margin>
<Insets top="8"/>
<Insets top="4"/>
</BorderPane.margin>
</ListView>
</center>
@ -105,10 +103,45 @@
</bottom>
</BorderPane>
</left>
<center>
<right>
<BorderPane>
<top>
<Label text="Nebenwirkungen"/>
<Label text="Alternative Medikamente:"/>
</top>
<center>
<ListView fx:id="listViewAlternativeMedication" minWidth="200">
<BorderPane.margin>
<Insets top="4"/>
</BorderPane.margin>
</ListView>
</center>
<bottom>
<AnchorPane>
<BorderPane.margin>
<Insets top="8"/>
</BorderPane.margin>
<Button
onAction="#handleAddAlternativeMedication"
text="+"
AnchorPane.leftAnchor="0"
AnchorPane.rightAnchor="0"
/>
</AnchorPane>
</bottom>
</BorderPane>
</right>
<center>
<BorderPane>
<BorderPane.margin>
<Insets left="8" right="8"/>
</BorderPane.margin>
<top>
<Label text="Nebenwirkungen">
<BorderPane.margin>
<Insets bottom="4"/>
</BorderPane.margin>
</Label>
</top>
<center>
<TextArea fx:id="textAreaPossibleSideEffects"/>

View file

@ -5,5 +5,6 @@ CREATE TABLE medication
manufacturer TEXT NOT NULL,
possibleSideEffects TEXT NOT NULL,
administrationMethod TEXT NOT NULL,
currentStock INTEGER NOT NULL
currentStock INTEGER NOT NULL,
isDeprecated BOOLEAN NOT NULL DEFAULT false
)

View file

@ -0,0 +1,7 @@
CREATE TABLE medication_alternative
(
id INTEGER NOT NULL ,
alternativeId INTEGER NOT NULL ,
FOREIGN KEY (id) REFERENCES medication (id) ON DELETE CASCADE,
FOREIGN KEY (alternativeId) REFERENCES medication (id) ON DELETE CASCADE
)

View file

@ -78,7 +78,6 @@
onAction="#handleDelete"
prefWidth="90.0"
text="Löschen"
/>
</HBox>
</right>