feat(search): add collection search menu and filter settings
- add search menu with filter configuration and result actions - add support for AND and OR filter relations - add range filters for group number, average grade, and record book number - update current collection menu to delegate search operations
This commit is contained in:
@@ -4,6 +4,7 @@ import com.googlecode.lanterna.gui2.ActionListBox;
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import ru.project.model.AppState;
|
||||
import ru.project.ui.base.BaseModalWindow;
|
||||
import ru.project.ui.collection.search.SearchCollectionMenu;
|
||||
import ru.project.ui.collection.sorting.SortCollectionMenu;
|
||||
import ru.project.ui.common.CollectionDisplayWindow;
|
||||
import ru.project.ui.common.CollectionFileSaveWindow;
|
||||
@@ -13,8 +14,8 @@ public class CurrentCollectionMenu extends BaseModalWindow {
|
||||
private final AppState state;
|
||||
|
||||
private final SortCollectionMenu sortCollectionMenu;
|
||||
private final SearchCollectionMenu searchCollectionMenu;
|
||||
|
||||
// private final SearchCollectionMenu searchCollectionMenu;
|
||||
// private final CountOccurrencesMenu countOccurrencesMenu;
|
||||
|
||||
public CurrentCollectionMenu(WindowBasedTextGUI gui, AppState state) {
|
||||
@@ -25,18 +26,18 @@ public class CurrentCollectionMenu extends BaseModalWindow {
|
||||
|
||||
this.sortCollectionMenu = new SortCollectionMenu(gui, state);
|
||||
|
||||
// this.searchCollectionMenu = new SearchCollectionMenu(gui, state);
|
||||
this.searchCollectionMenu = new SearchCollectionMenu(gui, state);
|
||||
|
||||
// this.countCollectionMenu = new CountOccurrencesMenu(gui, state);
|
||||
|
||||
ActionListBox menu = new ActionListBox();
|
||||
|
||||
menu.addItem("Показать коллекцию...", this::showCurrentCollection);
|
||||
|
||||
menu.addItem("Сохранить коллекцию в файл...", this::saveCurrentCollection);
|
||||
|
||||
menu.addItem("Меню сортировки коллекции", sortCollectionMenu::showModal);
|
||||
|
||||
menu.addItem("Меню поиска элемента в коллекции", this::searchCollection);
|
||||
menu.addItem("Меню поиска элемента в коллекции", searchCollectionMenu::showModal);
|
||||
|
||||
menu.addItem("Меню подсчёта количества вхождений элемента", this::countOccurrences);
|
||||
|
||||
@@ -57,12 +58,6 @@ public class CurrentCollectionMenu extends BaseModalWindow {
|
||||
window.showModal();
|
||||
}
|
||||
|
||||
private void searchCollection() {
|
||||
// SearchCollectionMenu searchCollectionMenu = new SearchCollectionMenu(gui, state);
|
||||
//
|
||||
// searchCollectionMenu.showModal();
|
||||
}
|
||||
|
||||
private void countOccurrences() {
|
||||
// CountOccurrencesMenu countOccurrencesMenu = new CountOccurrencesMenu(gui, state);
|
||||
//
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package ru.project.ui.collection.search;
|
||||
|
||||
public enum FilterRelation {
|
||||
AND,
|
||||
OR
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
package ru.project.ui.collection.search;
|
||||
|
||||
import com.googlecode.lanterna.gui2.ActionListBox;
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import ru.project.collection.MyLinkedList;
|
||||
import ru.project.collection.MyList;
|
||||
import ru.project.model.AppState;
|
||||
import ru.project.search.AverageGradeRangeCriteria;
|
||||
import ru.project.search.CompositeStudentSearchCriteria;
|
||||
import ru.project.search.GroupNumberRangeCriteria;
|
||||
import ru.project.search.RecordBookNumberRangeCriteria;
|
||||
import ru.project.search.SearchOperation;
|
||||
import ru.project.search.StudentSearchCriteria;
|
||||
import ru.project.search.StudentSearchService;
|
||||
import ru.project.student.Student;
|
||||
import ru.project.ui.base.BaseModalWindow;
|
||||
import ru.project.ui.common.CollectionDisplayWindow;
|
||||
import ru.project.ui.common.CollectionFileSaveWindow;
|
||||
import ru.project.ui.common.MessageWindow;
|
||||
|
||||
public class SearchCollectionMenu extends BaseModalWindow {
|
||||
|
||||
private final AppState state;
|
||||
|
||||
private final SearchSettingsWindow searchSettingsWindow;
|
||||
|
||||
private SearchSettings searchSettings;
|
||||
private MyList<Student> searchResultCollection;
|
||||
|
||||
public SearchCollectionMenu(WindowBasedTextGUI gui, AppState state) {
|
||||
|
||||
super("Меню поиска элемента в коллекции", gui);
|
||||
|
||||
this.state = state;
|
||||
this.searchSettings = new SearchSettings();
|
||||
this.searchResultCollection = new MyLinkedList<>();
|
||||
|
||||
this.searchSettingsWindow =
|
||||
new SearchSettingsWindow(gui, settings -> this.searchSettings = settings);
|
||||
|
||||
ActionListBox menu = new ActionListBox();
|
||||
|
||||
menu.addItem("Выполнить поиск", this::updateSearchResult);
|
||||
|
||||
menu.addItem("Показать результат поиска", this::showSearchResult);
|
||||
|
||||
menu.addItem("Сохранить результат поиска в файл", this::saveSearchResult);
|
||||
|
||||
menu.addItem("Настроить процесс поиска...", searchSettingsWindow::showModal);
|
||||
|
||||
menu.addItem("Выйти", this::close);
|
||||
|
||||
setComponent(menu);
|
||||
}
|
||||
|
||||
private void updateSearchResult() {
|
||||
MyList<Student> collection = state.getMainCollection();
|
||||
|
||||
if (collection == null || collection.isEmpty()) {
|
||||
MessageWindow.showModal(gui, "Коллекция для поиска пуста.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasEnabledFilters()) {
|
||||
MessageWindow.showModal(gui, "Не выбран ни один фильтр.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasValidFilterRanges()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StudentSearchCriteria criteria = createSearchCriteria();
|
||||
|
||||
StudentSearchService searchService = new StudentSearchService(criteria);
|
||||
|
||||
searchResultCollection = searchService.find(collection);
|
||||
|
||||
MessageWindow.showModal(gui, "Результат поиска обновлён.");
|
||||
}
|
||||
|
||||
private StudentSearchCriteria createSearchCriteria() {
|
||||
SearchOperation operation =
|
||||
searchSettings.getRelation() == FilterRelation.AND
|
||||
? SearchOperation.INTERSECTION
|
||||
: SearchOperation.UNION;
|
||||
|
||||
CompositeStudentSearchCriteria compositeCriteria =
|
||||
new CompositeStudentSearchCriteria(operation);
|
||||
|
||||
if (searchSettings.isGroupNumberFilterEnabled()) {
|
||||
compositeCriteria.add(
|
||||
new GroupNumberRangeCriteria(
|
||||
searchSettings.getMinGroupNumber(), searchSettings.getMaxGroupNumber()));
|
||||
}
|
||||
|
||||
if (searchSettings.isAverageGradeFilterEnabled()) {
|
||||
compositeCriteria.add(
|
||||
new AverageGradeRangeCriteria(
|
||||
searchSettings.getMinAverageGrade(), searchSettings.getMaxAverageGrade()));
|
||||
}
|
||||
|
||||
if (searchSettings.isRecordBookNumberFilterEnabled()) {
|
||||
compositeCriteria.add(
|
||||
new RecordBookNumberRangeCriteria(
|
||||
searchSettings.getMinRecordBookNumber(), searchSettings.getMaxRecordBookNumber()));
|
||||
}
|
||||
|
||||
return compositeCriteria;
|
||||
}
|
||||
|
||||
private boolean hasEnabledFilters() {
|
||||
return searchSettings.isGroupNumberFilterEnabled()
|
||||
|| searchSettings.isAverageGradeFilterEnabled()
|
||||
|| searchSettings.isRecordBookNumberFilterEnabled();
|
||||
}
|
||||
|
||||
private boolean hasValidFilterRanges() {
|
||||
StringBuilder errors = new StringBuilder();
|
||||
|
||||
if (!hasValidGroupNumberRange()) {
|
||||
errors.append("Для фильтра по номеру группы задайте минимальное и максимальное значения.\n");
|
||||
}
|
||||
|
||||
if (!hasValidAverageGradeRange()) {
|
||||
errors.append("Для фильтра по среднему баллу задайте минимальное и максимальное значения.\n");
|
||||
}
|
||||
|
||||
if (!hasValidRecordBookNumberRange()) {
|
||||
errors.append(
|
||||
"Для фильтра по номеру зачётной книжки задайте минимальное и максимальное значения.\n");
|
||||
}
|
||||
|
||||
if (errors.length() > 0) {
|
||||
MessageWindow.showModal(gui, errors.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean hasValidGroupNumberRange() {
|
||||
if (!searchSettings.isGroupNumberFilterEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return searchSettings.getMinGroupNumber() != null && searchSettings.getMaxGroupNumber() != null;
|
||||
}
|
||||
|
||||
private boolean hasValidAverageGradeRange() {
|
||||
if (!searchSettings.isAverageGradeFilterEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return searchSettings.getMinAverageGrade() != null
|
||||
&& searchSettings.getMaxAverageGrade() != null;
|
||||
}
|
||||
|
||||
private boolean hasValidRecordBookNumberRange() {
|
||||
if (!searchSettings.isRecordBookNumberFilterEnabled()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return searchSettings.getMinRecordBookNumber() != null
|
||||
&& searchSettings.getMaxRecordBookNumber() != null;
|
||||
}
|
||||
|
||||
private void showSearchResult() {
|
||||
if (searchResultCollection == null || searchResultCollection.isEmpty()) {
|
||||
|
||||
MessageWindow.showModal(gui, "Результат поиска пуст.");
|
||||
return;
|
||||
}
|
||||
|
||||
CollectionDisplayWindow window = new CollectionDisplayWindow(gui, searchResultCollection);
|
||||
|
||||
window.showModal();
|
||||
}
|
||||
|
||||
private void saveSearchResult() {
|
||||
if (searchResultCollection == null || searchResultCollection.isEmpty()) {
|
||||
|
||||
MessageWindow.showModal(gui, "Результат поиска пуст.");
|
||||
return;
|
||||
}
|
||||
|
||||
CollectionFileSaveWindow window = new CollectionFileSaveWindow(gui, searchResultCollection);
|
||||
|
||||
window.showModal();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package ru.project.ui.collection.search;
|
||||
|
||||
public class SearchSettings {
|
||||
|
||||
private FilterRelation relation;
|
||||
|
||||
private boolean groupNumberFilterEnabled;
|
||||
private boolean averageGradeFilterEnabled;
|
||||
private boolean recordBookNumberFilterEnabled;
|
||||
|
||||
private String minGroupNumber;
|
||||
private String maxGroupNumber;
|
||||
|
||||
private Double minAverageGrade;
|
||||
private Double maxAverageGrade;
|
||||
|
||||
private Integer minRecordBookNumber;
|
||||
private Integer maxRecordBookNumber;
|
||||
|
||||
public SearchSettings() {
|
||||
this.relation = FilterRelation.AND;
|
||||
|
||||
this.groupNumberFilterEnabled = false;
|
||||
this.averageGradeFilterEnabled = false;
|
||||
this.recordBookNumberFilterEnabled = false;
|
||||
|
||||
this.minGroupNumber = null;
|
||||
this.maxGroupNumber = null;
|
||||
|
||||
this.minAverageGrade = null;
|
||||
this.maxAverageGrade = null;
|
||||
|
||||
this.minRecordBookNumber = null;
|
||||
this.maxRecordBookNumber = null;
|
||||
}
|
||||
|
||||
public FilterRelation getRelation() {
|
||||
return relation;
|
||||
}
|
||||
|
||||
public void setRelation(FilterRelation relation) {
|
||||
this.relation = relation;
|
||||
}
|
||||
|
||||
public boolean isGroupNumberFilterEnabled() {
|
||||
return groupNumberFilterEnabled;
|
||||
}
|
||||
|
||||
public void setGroupNumberFilterEnabled(boolean enabled) {
|
||||
this.groupNumberFilterEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isAverageGradeFilterEnabled() {
|
||||
return averageGradeFilterEnabled;
|
||||
}
|
||||
|
||||
public void setAverageGradeFilterEnabled(boolean enabled) {
|
||||
this.averageGradeFilterEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isRecordBookNumberFilterEnabled() {
|
||||
return recordBookNumberFilterEnabled;
|
||||
}
|
||||
|
||||
public void setRecordBookNumberFilterEnabled(boolean enabled) {
|
||||
this.recordBookNumberFilterEnabled = enabled;
|
||||
}
|
||||
|
||||
public String getMinGroupNumber() {
|
||||
return minGroupNumber;
|
||||
}
|
||||
|
||||
public void setMinGroupNumber(String minGroupNumber) {
|
||||
this.minGroupNumber = minGroupNumber;
|
||||
}
|
||||
|
||||
public String getMaxGroupNumber() {
|
||||
return maxGroupNumber;
|
||||
}
|
||||
|
||||
public void setMaxGroupNumber(String maxGroupNumber) {
|
||||
this.maxGroupNumber = maxGroupNumber;
|
||||
}
|
||||
|
||||
public Double getMinAverageGrade() {
|
||||
return minAverageGrade;
|
||||
}
|
||||
|
||||
public void setMinAverageGrade(Double minAverageGrade) {
|
||||
this.minAverageGrade = minAverageGrade;
|
||||
}
|
||||
|
||||
public Double getMaxAverageGrade() {
|
||||
return maxAverageGrade;
|
||||
}
|
||||
|
||||
public void setMaxAverageGrade(Double maxAverageGrade) {
|
||||
this.maxAverageGrade = maxAverageGrade;
|
||||
}
|
||||
|
||||
public Integer getMinRecordBookNumber() {
|
||||
return minRecordBookNumber;
|
||||
}
|
||||
|
||||
public void setMinRecordBookNumber(Integer minRecordBookNumber) {
|
||||
this.minRecordBookNumber = minRecordBookNumber;
|
||||
}
|
||||
|
||||
public Integer getMaxRecordBookNumber() {
|
||||
return maxRecordBookNumber;
|
||||
}
|
||||
|
||||
public void setMaxRecordBookNumber(Integer maxRecordBookNumber) {
|
||||
this.maxRecordBookNumber = maxRecordBookNumber;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
package ru.project.ui.collection.search;
|
||||
|
||||
import com.googlecode.lanterna.gui2.Button;
|
||||
import com.googlecode.lanterna.gui2.CheckBox;
|
||||
import com.googlecode.lanterna.gui2.Label;
|
||||
import com.googlecode.lanterna.gui2.LinearLayout;
|
||||
import com.googlecode.lanterna.gui2.Panel;
|
||||
import com.googlecode.lanterna.gui2.RadioBoxList;
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import ru.project.student.Student;
|
||||
import ru.project.ui.base.BaseModalWindow;
|
||||
import ru.project.ui.common.InputValueWindow;
|
||||
import ru.project.ui.common.MessageWindow;
|
||||
|
||||
public class SearchSettingsWindow extends BaseModalWindow {
|
||||
|
||||
private final SearchSettings settings;
|
||||
private final Consumer<SearchSettings> onApply;
|
||||
|
||||
private final CheckBox groupNumberFilterCheckBox;
|
||||
private final CheckBox averageGradeFilterCheckBox;
|
||||
private final CheckBox recordBookNumberFilterCheckBox;
|
||||
|
||||
private final Label minGroupNumberLabel;
|
||||
private final Label maxGroupNumberLabel;
|
||||
|
||||
private final Label minAverageGradeLabel;
|
||||
private final Label maxAverageGradeLabel;
|
||||
|
||||
private final Label minRecordBookNumberLabel;
|
||||
private final Label maxRecordBookNumberLabel;
|
||||
|
||||
private final RadioBoxList<String> relationList;
|
||||
|
||||
public SearchSettingsWindow(WindowBasedTextGUI gui, Consumer<SearchSettings> onApply) {
|
||||
|
||||
super("Настройка процесса поиска", gui);
|
||||
|
||||
this.settings = new SearchSettings();
|
||||
this.onApply = onApply;
|
||||
|
||||
Panel panel = new Panel();
|
||||
panel.setLayoutManager(new LinearLayout());
|
||||
|
||||
panel.addComponent(new Label("Отношение фильтров:"));
|
||||
|
||||
relationList = new RadioBoxList<>();
|
||||
relationList.addItem("И");
|
||||
relationList.addItem("ИЛИ");
|
||||
relationList.setCheckedItemIndex(0);
|
||||
|
||||
panel.addComponent(relationList);
|
||||
|
||||
groupNumberFilterCheckBox = new CheckBox("Фильтр по номеру группы");
|
||||
|
||||
averageGradeFilterCheckBox = new CheckBox("Фильтр по среднему баллу");
|
||||
|
||||
recordBookNumberFilterCheckBox = new CheckBox("Фильтр по номеру зачётной книжки");
|
||||
|
||||
panel.addComponent(groupNumberFilterCheckBox);
|
||||
|
||||
minGroupNumberLabel =
|
||||
new Label("Минимум номера группы: " + getValueOrDefault(settings.getMinGroupNumber()));
|
||||
|
||||
maxGroupNumberLabel =
|
||||
new Label("Максимум номера группы: " + getValueOrDefault(settings.getMaxGroupNumber()));
|
||||
|
||||
panel.addComponent(minGroupNumberLabel);
|
||||
panel.addComponent(maxGroupNumberLabel);
|
||||
|
||||
panel.addComponent(new Button("Задать минимум номера группы...", this::setMinGroupNumber));
|
||||
|
||||
panel.addComponent(new Button("Задать максимум номера группы...", this::setMaxGroupNumber));
|
||||
|
||||
panel.addComponent(averageGradeFilterCheckBox);
|
||||
|
||||
minAverageGradeLabel =
|
||||
new Label("Минимум среднего балла: " + getValueOrDefault(settings.getMinAverageGrade()));
|
||||
|
||||
maxAverageGradeLabel =
|
||||
new Label("Максимум среднего балла: " + getValueOrDefault(settings.getMaxAverageGrade()));
|
||||
|
||||
panel.addComponent(minAverageGradeLabel);
|
||||
panel.addComponent(maxAverageGradeLabel);
|
||||
|
||||
panel.addComponent(new Button("Задать минимум среднего балла...", this::setMinAverageGrade));
|
||||
|
||||
panel.addComponent(new Button("Задать максимум среднего балла...", this::setMaxAverageGrade));
|
||||
|
||||
panel.addComponent(recordBookNumberFilterCheckBox);
|
||||
|
||||
minRecordBookNumberLabel =
|
||||
new Label(
|
||||
"Минимум номера зачётной книжки: "
|
||||
+ getValueOrDefault(settings.getMinRecordBookNumber()));
|
||||
|
||||
maxRecordBookNumberLabel =
|
||||
new Label(
|
||||
"Максимум номера зачётной книжки: "
|
||||
+ getValueOrDefault(settings.getMaxRecordBookNumber()));
|
||||
|
||||
panel.addComponent(minRecordBookNumberLabel);
|
||||
panel.addComponent(maxRecordBookNumberLabel);
|
||||
|
||||
panel.addComponent(
|
||||
new Button("Задать минимум номера зачётной книжки...", this::setMinRecordBookNumber));
|
||||
|
||||
panel.addComponent(
|
||||
new Button("Задать максимум номера зачётной книжки...", this::setMaxRecordBookNumber));
|
||||
|
||||
panel.addComponent(new Button("Применить", this::apply));
|
||||
|
||||
panel.addComponent(new Button("Выйти", this::close));
|
||||
|
||||
setComponent(panel);
|
||||
}
|
||||
|
||||
private void setMinGroupNumber() {
|
||||
showGroupNumberInput(
|
||||
"Минимальный номер группы",
|
||||
settings.getMinGroupNumber(),
|
||||
value -> {
|
||||
if (!value.matches(Student.getGroupNumberPattern())) {
|
||||
|
||||
MessageWindow.showModal(gui, "Номер группы должен соответствовать формату A12.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (settings.getMaxGroupNumber() != null
|
||||
&& value.compareTo(settings.getMaxGroupNumber()) > 0) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Минимальный номер группы не может быть больше максимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMinGroupNumber(value);
|
||||
|
||||
minGroupNumberLabel.setText("Минимум номера группы: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void setMaxGroupNumber() {
|
||||
showGroupNumberInput(
|
||||
"Максимальный номер группы",
|
||||
settings.getMaxGroupNumber(),
|
||||
value -> {
|
||||
if (!value.matches(Student.getGroupNumberPattern())) {
|
||||
|
||||
MessageWindow.showModal(gui, "Номер группы должен соответствовать формату A12.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (settings.getMinGroupNumber() != null
|
||||
&& value.compareTo(settings.getMinGroupNumber()) < 0) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Максимальный номер группы не может быть меньше минимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMaxGroupNumber(value);
|
||||
|
||||
maxGroupNumberLabel.setText("Максимум номера группы: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void showGroupNumberInput(String title, String initialValue, Predicate<String> onSave) {
|
||||
|
||||
InputValueWindow window =
|
||||
new InputValueWindow(
|
||||
gui, title, "Введите номер группы (например, A12):", initialValue, onSave);
|
||||
|
||||
window.showModal();
|
||||
}
|
||||
|
||||
private void setMinAverageGrade() {
|
||||
showAverageGradeInput(
|
||||
"Минимальный средний балл",
|
||||
settings.getMinAverageGrade(),
|
||||
value -> {
|
||||
if (settings.getMaxAverageGrade() != null && value > settings.getMaxAverageGrade()) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Минимальный средний балл не может быть больше максимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMinAverageGrade(value);
|
||||
|
||||
minAverageGradeLabel.setText("Минимум среднего балла: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void setMaxAverageGrade() {
|
||||
showAverageGradeInput(
|
||||
"Максимальный средний балл",
|
||||
settings.getMaxAverageGrade(),
|
||||
value -> {
|
||||
if (settings.getMinAverageGrade() != null && value < settings.getMinAverageGrade()) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Максимальный средний балл не может быть меньше минимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMaxAverageGrade(value);
|
||||
|
||||
maxAverageGradeLabel.setText("Максимум среднего балла: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void showAverageGradeInput(String title, Double initialValue, Predicate<Double> onSave) {
|
||||
|
||||
InputValueWindow window =
|
||||
new InputValueWindow(
|
||||
gui,
|
||||
title,
|
||||
"Введите значение от 0.0 до 5.0:",
|
||||
initialValue == null ? null : String.valueOf(initialValue),
|
||||
value -> {
|
||||
try {
|
||||
double parsedValue = Double.parseDouble(value);
|
||||
|
||||
if (parsedValue < Student.getMinAverageGrade()
|
||||
|| parsedValue > Student.getMaxAverageGrade()) {
|
||||
|
||||
MessageWindow.showModal(gui, "Средний балл должен быть от 0.0 до 5.0.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return onSave.test(parsedValue);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
MessageWindow.showModal(gui, "Введите корректное число.");
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
window.showModal();
|
||||
}
|
||||
|
||||
private void setMinRecordBookNumber() {
|
||||
showRecordBookNumberInput(
|
||||
"Минимальный номер зачётной книжки",
|
||||
settings.getMinRecordBookNumber(),
|
||||
value -> {
|
||||
if (settings.getMaxRecordBookNumber() != null
|
||||
&& value > settings.getMaxRecordBookNumber()) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Минимальный номер зачётной книжки не может быть больше максимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMinRecordBookNumber(value);
|
||||
|
||||
minRecordBookNumberLabel.setText("Минимум номера зачётной книжки: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void setMaxRecordBookNumber() {
|
||||
showRecordBookNumberInput(
|
||||
"Максимальный номер зачётной книжки",
|
||||
settings.getMaxRecordBookNumber(),
|
||||
value -> {
|
||||
if (settings.getMinRecordBookNumber() != null
|
||||
&& value < settings.getMinRecordBookNumber()) {
|
||||
|
||||
MessageWindow.showModal(
|
||||
gui, "Максимальный номер зачётной книжки не может быть меньше минимального.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
settings.setMaxRecordBookNumber(value);
|
||||
|
||||
maxRecordBookNumberLabel.setText("Максимум номера зачётной книжки: " + value);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void showRecordBookNumberInput(
|
||||
String title, Integer initialValue, Predicate<Integer> onSave) {
|
||||
|
||||
InputValueWindow window =
|
||||
new InputValueWindow(
|
||||
gui,
|
||||
title,
|
||||
"Введите номер зачётной книжки:",
|
||||
initialValue == null ? null : String.valueOf(initialValue),
|
||||
value -> {
|
||||
try {
|
||||
int parsedValue = Integer.parseInt(value);
|
||||
|
||||
if (parsedValue < Student.getMinRecordBookNumber()) {
|
||||
|
||||
MessageWindow.showModal(gui, "Номер зачётной книжки должен быть положительным.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return onSave.test(parsedValue);
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
MessageWindow.showModal(gui, "Введите целое число.");
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
window.showModal();
|
||||
}
|
||||
|
||||
private void apply() {
|
||||
settings.setGroupNumberFilterEnabled(groupNumberFilterCheckBox.isChecked());
|
||||
|
||||
settings.setAverageGradeFilterEnabled(averageGradeFilterCheckBox.isChecked());
|
||||
|
||||
settings.setRecordBookNumberFilterEnabled(recordBookNumberFilterCheckBox.isChecked());
|
||||
|
||||
settings.setRelation(
|
||||
relationList.getCheckedItemIndex() == 0 ? FilterRelation.AND : FilterRelation.OR);
|
||||
|
||||
onApply.accept(settings);
|
||||
|
||||
MessageWindow.showModal(gui, "Настройки процесса поиска успешно применены.");
|
||||
}
|
||||
|
||||
private String getValueOrDefault(Object value) {
|
||||
return value == null ? "не задан" : String.valueOf(value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user