implemented new design
This commit is contained in:
parent
fa666efaf8
commit
43c8792d70
@ -13,14 +13,18 @@ import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Comparator;
|
||||
|
||||
import static at.ionas999.questioncatalog.Utils.showConfirmationButton;
|
||||
|
||||
@ -30,7 +34,9 @@ public class ViewController {
|
||||
@FXML
|
||||
private ComboBox<QuestionCatalog> selectBox;
|
||||
@FXML
|
||||
private Button editButton, deleteButton;
|
||||
private ComboBox<SortOption> sortComboBox;
|
||||
@FXML
|
||||
private Button editButton, deleteButton, addButton;
|
||||
@FXML
|
||||
private TextField answerField, questionField;
|
||||
@FXML
|
||||
@ -38,30 +44,87 @@ public class ViewController {
|
||||
|
||||
private ObjectProperty<Question> currentQuestion = new SimpleObjectProperty<>();
|
||||
private FilteredList<Question> questions;
|
||||
private SortedList<Question> sortedQuestions;
|
||||
private final BooleanProperty isInEditState = new SimpleBooleanProperty(false);
|
||||
private final BooleanProperty isInAddState = new SimpleBooleanProperty(false);
|
||||
|
||||
private EventHandler<ActionEvent> originalEditAction;
|
||||
private EventHandler<ActionEvent> originalDeleteAction;
|
||||
|
||||
private enum SortOption {
|
||||
CREATION_ORDER("Sort by Creation"),
|
||||
QUESTION_ASC("Question (A-Z)"),
|
||||
QUESTION_DESC("Question (Z-A)");
|
||||
|
||||
private final String displayName;
|
||||
|
||||
SortOption(String displayName) {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void initialize() throws SQLException {
|
||||
//der Add btn ist mit ai erstellt worden (Claude 3.7)
|
||||
ObservableList<QuestionCatalog> catalogs = FXCollections.observableList(QuestionCatalogService.GetCatalogsWithoutQuestions());
|
||||
selectBox.setItems(catalogs);
|
||||
selectBox.getSelectionModel().selectedItemProperty().addListener((_, _, newVal) -> loadQuestions(newVal));
|
||||
questionListView.getSelectionModel().selectedItemProperty().addListener((_, _, newVal) -> updateCurrentQuestion(newVal));
|
||||
|
||||
editButton.textProperty().bind(Bindings.when(isInEditState.not()).then("Edit").otherwise("Save"));
|
||||
questionField.editableProperty().bind(isInEditState);
|
||||
answerField.editableProperty().bind(isInEditState);
|
||||
deleteButton.disableProperty().bind(isInEditState);
|
||||
questionListView.disableProperty().bind(isInEditState);
|
||||
sortComboBox.setItems(FXCollections.observableArrayList(SortOption.values()));
|
||||
sortComboBox.getSelectionModel().select(SortOption.CREATION_ORDER);
|
||||
sortComboBox.getSelectionModel().selectedItemProperty().addListener((_, _, newOption) -> {
|
||||
if (sortedQuestions != null) {
|
||||
applySorting(newOption);
|
||||
}
|
||||
});
|
||||
|
||||
BooleanProperty catalogSelected = new SimpleBooleanProperty();
|
||||
catalogSelected.bind(selectBox.getSelectionModel().selectedItemProperty().isNotNull());
|
||||
|
||||
sortComboBox.disableProperty().bind(selectBox.getSelectionModel().selectedItemProperty().isNull());
|
||||
|
||||
originalEditAction = editButton.getOnAction();
|
||||
originalDeleteAction = deleteButton.getOnAction();
|
||||
|
||||
editButton.textProperty().bind(
|
||||
Bindings.when(isInAddState)
|
||||
.then("Save New")
|
||||
.otherwise(Bindings.when(isInEditState).then("Save").otherwise("Edit"))
|
||||
);
|
||||
|
||||
questionField.editableProperty().bind(isInEditState.or(isInAddState).and(catalogSelected));
|
||||
answerField.editableProperty().bind(isInEditState.or(isInAddState).and(catalogSelected));
|
||||
|
||||
questionField.disableProperty().bind(catalogSelected.not());
|
||||
answerField.disableProperty().bind(catalogSelected.not());
|
||||
|
||||
// Update button and control disabling to handle add mode
|
||||
deleteButton.disableProperty().bind(
|
||||
isInEditState.or(catalogSelected.not()).or(
|
||||
isInAddState.and(
|
||||
questionField.textProperty().isEmpty().or(answerField.textProperty().isEmpty())
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
addButton.disableProperty().bind(isInEditState.or(isInAddState).or(catalogSelected.not()));
|
||||
|
||||
questionListView.disableProperty().bind(isInEditState.or(isInAddState).or(catalogSelected.not()));
|
||||
|
||||
// Disable searchField if no catalog is selected
|
||||
searchField.disableProperty().bind(selectBox.getSelectionModel().selectedItemProperty().isNull());
|
||||
|
||||
// Disable editButton if fields are empty
|
||||
editButton.disableProperty().bind(
|
||||
questionField.textProperty().isEmpty()
|
||||
.or(answerField.textProperty().isEmpty())
|
||||
.or(selectBox.getSelectionModel().selectedItemProperty().isNull())
|
||||
);
|
||||
|
||||
deleteButton.disableProperty().bind(
|
||||
questionField.textProperty().isEmpty()
|
||||
.or(answerField.textProperty().isEmpty())
|
||||
@ -74,22 +137,51 @@ public class ViewController {
|
||||
String finalNewValue = newValue;
|
||||
questions.setPredicate(x -> x.getQuestion().toLowerCase().contains(finalNewValue.toLowerCase()));
|
||||
});
|
||||
|
||||
questionListView.setOnKeyPressed(this::handleKeyPress);
|
||||
}
|
||||
|
||||
private void handleKeyPress(KeyEvent event) {
|
||||
if (event.getCode() == KeyCode.DELETE) {
|
||||
if (currentQuestion.get() != null && !isInEditState.get()) {
|
||||
deleteQuestion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadQuestions(QuestionCatalog catalog) {
|
||||
if (catalog == null) return;
|
||||
try {
|
||||
questions = new FilteredList<>(
|
||||
FXCollections.observableList
|
||||
(QuestionService.GetQuestionsFromCatalog(
|
||||
catalog.getId())));
|
||||
FXCollections.observableList(
|
||||
QuestionService.GetQuestionsFromCatalog(catalog.getId())));
|
||||
|
||||
questionListView.setItems(questions);
|
||||
sortedQuestions = new SortedList<>(questions);
|
||||
|
||||
applySorting(sortComboBox.getValue());
|
||||
|
||||
questionListView.setItems(sortedQuestions);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void applySorting(SortOption sortOption) {
|
||||
if (sortOption == null) return;
|
||||
|
||||
switch (sortOption) {
|
||||
case CREATION_ORDER:
|
||||
sortedQuestions.setComparator(Comparator.comparingInt(Question::getId));
|
||||
break;
|
||||
case QUESTION_ASC:
|
||||
sortedQuestions.setComparator(Comparator.comparing(Question::getQuestion));
|
||||
break;
|
||||
case QUESTION_DESC:
|
||||
sortedQuestions.setComparator(Comparator.comparing(Question::getQuestion).reversed());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCurrentQuestion(Question question) {
|
||||
if (question == null) return;
|
||||
currentQuestion.set(question);
|
||||
@ -119,6 +211,92 @@ public class ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void addQuestion() {
|
||||
if (selectBox.getValue() == null) return;
|
||||
|
||||
// Enter add mode
|
||||
isInAddState.set(true);
|
||||
|
||||
// Clear fields and selection
|
||||
questionField.clear();
|
||||
answerField.clear();
|
||||
questionListView.getSelectionModel().clearSelection();
|
||||
currentQuestion.set(null);
|
||||
|
||||
// Change delete button to cancel
|
||||
deleteButton.setText("Cancel");
|
||||
|
||||
// Set temporary actions
|
||||
deleteButton.setOnAction(e -> cancelAddQuestion());
|
||||
editButton.setOnAction(e -> saveNewQuestion());
|
||||
|
||||
// Focus the question field
|
||||
questionField.requestFocus();
|
||||
}
|
||||
|
||||
private void saveNewQuestion() {
|
||||
String questionText = questionField.getText().trim();
|
||||
String answerText = answerField.getText().trim();
|
||||
|
||||
if (questionText.isEmpty() || answerText.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Use a temporary ID that will be ignored by AddQuestionToDb
|
||||
int catalogId = selectBox.getValue().getId();
|
||||
Question newQuestion = new Question(0, questionText, answerText, catalogId);
|
||||
|
||||
boolean success = QuestionService.AddQuestionToDb(newQuestion);
|
||||
|
||||
if (success) {
|
||||
// Refresh the questions list to include the new question
|
||||
loadQuestions(selectBox.getValue());
|
||||
|
||||
// Exit add mode
|
||||
resetAfterAdd();
|
||||
|
||||
// Show success message
|
||||
showAlert(Alert.AlertType.INFORMATION, "Success",
|
||||
"Question Added", "Question was added successfully.");
|
||||
} else {
|
||||
showAlert(Alert.AlertType.ERROR, "Error",
|
||||
"Failed to add question", "Could not add question to the database.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
showAlert(Alert.AlertType.ERROR, "Error",
|
||||
"Error adding question", "An error occurred: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelAddQuestion() {
|
||||
resetAfterAdd();
|
||||
}
|
||||
|
||||
private void resetAfterAdd() {
|
||||
// Exit add mode
|
||||
isInAddState.set(false);
|
||||
|
||||
// Restore original button state
|
||||
deleteButton.setText("Delete");
|
||||
deleteButton.setOnAction(originalDeleteAction);
|
||||
editButton.setOnAction(originalEditAction);
|
||||
|
||||
// Try to restore selection
|
||||
if (!questionListView.getItems().isEmpty()) {
|
||||
questionListView.getSelectionModel().selectFirst();
|
||||
}
|
||||
}
|
||||
|
||||
private void showAlert(Alert.AlertType type, String title, String header, String content) {
|
||||
Alert alert = new Alert(type);
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(header);
|
||||
alert.setContentText(content);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onBackToMainPageClick(ActionEvent actionEvent) throws IOException {
|
||||
Stage stage = Utils.getStageFromActionEven(actionEvent);
|
||||
|
||||
@ -45,8 +45,12 @@
|
||||
<Label text="Questions:" style="-fx-font-size: 14; -fx-font-weight: bold;"/>
|
||||
<TextField fx:id="searchField" promptText="Search questions..."
|
||||
style="-fx-background-color: white; -fx-border-color: #bdc3c7;"/>
|
||||
<ComboBox fx:id="sortComboBox" promptText="Sort by..."
|
||||
style="-fx-background-color: white; -fx-border-color: #bdc3c7; -fx-max-width: 1000;"/>
|
||||
<ListView fx:id="questionListView" VBox.vgrow="ALWAYS"
|
||||
style="-fx-background-color: white; -fx-border-color: #bdc3c7;"/>
|
||||
<Button fx:id="addButton" text="Add Question" onAction="#addQuestion"
|
||||
style="-fx-background-color: #27ae60; -fx-text-fill: white;"/>
|
||||
</VBox>
|
||||
</left>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user