diff --git a/app/src/main/java/ru/project/model/AppState.java b/app/src/main/java/ru/project/model/AppState.java index 9b2a61e..e430057 100644 --- a/app/src/main/java/ru/project/model/AppState.java +++ b/app/src/main/java/ru/project/model/AppState.java @@ -6,20 +6,31 @@ import ru.project.student.Student; public class AppState { - private MyList collection; + private MyList currentCollection; + private MyList customDataCollection; private String currentFilePath; public AppState() { - this.collection = new MyLinkedList<>(); + this.currentCollection = new MyLinkedList<>(); + this.customDataCollection = new MyLinkedList<>(); this.currentFilePath = null; } - public MyList getCollection() { - return collection; + public MyList getCurrentCollection() { + return currentCollection; } - public void setCollection(MyList collection) { - this.collection = collection; + public void setCurrentCollection(MyList currentCollection) { + this.currentCollection = currentCollection; + } + + public MyList getCustomDataCollection() { + return customDataCollection; + } + + public void setCustomDataCollection(MyList customDataCollection) { + + this.customDataCollection = customDataCollection; } public String getCurrentFilePath() { diff --git a/app/src/main/java/ru/project/ui/menu/CreateCollectionMenu.java b/app/src/main/java/ru/project/ui/menu/CreateCollectionMenu.java index 2f7facd..48d2f0c 100644 --- a/app/src/main/java/ru/project/ui/menu/CreateCollectionMenu.java +++ b/app/src/main/java/ru/project/ui/menu/CreateCollectionMenu.java @@ -8,7 +8,8 @@ import com.googlecode.lanterna.gui2.WindowBasedTextGUI; import ru.project.model.AppState; import ru.project.model.FillMethod; import ru.project.ui.base.BaseWindow; -import ru.project.ui.window.CollectionSizeInputWindow; +import ru.project.ui.window.CustomDataSettingsWindow; +import ru.project.ui.window.InputValueWindow; import ru.project.ui.window.MessageWindow; public class CreateCollectionMenu extends BaseWindow { @@ -19,9 +20,13 @@ public class CreateCollectionMenu extends BaseWindow { private final Label sizeLabel; private final Label fillMethodLabel; + private final AppState state; + public CreateCollectionMenu(WindowBasedTextGUI gui, AppState state) { super("Создание новой коллекции", gui); + this.state = state; + collectionSize = 0; selectedFillMethod = FillMethod.CUSTOM; @@ -35,9 +40,12 @@ public class CreateCollectionMenu extends BaseWindow { panel.addComponent(sizeLabel); panel.addComponent(fillMethodLabel); - panel.addComponent(new Button("Задать размер", this::openCollectionSizeInputWindow)); + panel.addComponent(new Button("Задать размер", this::openCollectionSizeInputValueWindow)); - panel.addComponent(new Button("Настроить способ заполнения", this::openFillMethodMenu)); + panel.addComponent(new Button("Выбрать способ заполнения", this::selectFillMethod)); + + panel.addComponent( + new Button("Настроить текущий способ заполнения", this::setupCurrentFillMethod)); panel.addComponent(new Button("Создать новую коллекцию", this::createCollection)); @@ -46,20 +54,53 @@ public class CreateCollectionMenu extends BaseWindow { setComponent(panel); } - private void openCollectionSizeInputWindow() { - CollectionSizeInputWindow window = - new CollectionSizeInputWindow( + private void openCollectionSizeInputValueWindow() { + InputValueWindow window = + new InputValueWindow( gui, - size -> { - collectionSize = size; - sizeLabel.setText("Размер: " + collectionSize); - }); + "Размер коллекции", + "Введите размер коллекции:", + collectionSize > 0 ? String.valueOf(collectionSize) : null, + this::handleSizeEntered); window.show(); } - private void openFillMethodMenu() { - FillMethodSelectionWindow menu = + private boolean handleSizeEntered(String value) { + try { + int enteredSize = Integer.parseInt(value); + if (enteredSize <= 0) { + MessageWindow.show(gui, "Размер должен быть больше 0."); + return false; + } + collectionSize = enteredSize; + sizeLabel.setText("Размер: " + collectionSize); + return true; + } catch (NumberFormatException e) { + MessageWindow.show(gui, "Введите целое число."); + return false; + } + } + + private void setupCurrentFillMethod() { + switch (selectedFillMethod) { + case CUSTOM -> { + BaseWindow window = new CustomDataSettingsWindow(gui, state, collectionSize); + + window.show(); + } + + case FILE -> + // TODO + MessageWindow.show(gui, "Не реализовано."); + + case RANDOM -> + MessageWindow.show(gui, "Для случайных данных дополнительные настройки не требуются."); + } + } + + private void selectFillMethod() { + BaseWindow menu = new FillMethodSelectionWindow( gui, fillMethod -> { @@ -73,7 +114,7 @@ public class CreateCollectionMenu extends BaseWindow { private void createCollection() { if (collectionSize <= 0) { - MessageWindow.create(gui, "Сначала задайте размер коллекции."); + MessageWindow.show(gui, "Сначала задайте размер коллекции."); return; } @@ -94,17 +135,17 @@ public class CreateCollectionMenu extends BaseWindow { private void createCollectionFromCustomData() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void createCollectionFromRandomData() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void createCollectionFromFileData() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private String getFillMethodName(FillMethod fillMethod) { diff --git a/app/src/main/java/ru/project/ui/menu/MainMenu.java b/app/src/main/java/ru/project/ui/menu/MainMenu.java index 3b3fbcb..308277e 100644 --- a/app/src/main/java/ru/project/ui/menu/MainMenu.java +++ b/app/src/main/java/ru/project/ui/menu/MainMenu.java @@ -2,9 +2,11 @@ package ru.project.ui.menu; import com.googlecode.lanterna.gui2.ActionListBox; import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import ru.project.collection.MyList; import ru.project.model.AppState; +import ru.project.student.Student; import ru.project.ui.base.BaseWindow; -import ru.project.ui.window.CurrentCollectionWindow; +import ru.project.ui.window.CollectionDisplayWindow; import ru.project.ui.window.MessageWindow; public class MainMenu extends BaseWindow { @@ -37,35 +39,37 @@ public class MainMenu extends BaseWindow { } private void showCurrentCollection() { - CurrentCollectionWindow window = new CurrentCollectionWindow(gui, state); + MyList currentCollection = state.getCurrentCollection(); + + BaseWindow window = new CollectionDisplayWindow(gui, currentCollection); window.show(); } private void createCollection() { - CreateCollectionMenu window = new CreateCollectionMenu(gui, state); + BaseWindow window = new CreateCollectionMenu(gui, state); window.show(); } private void saveCollection() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void sortCollection() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void searchCollection() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void countOccurrences() { // TODO - MessageWindow.create(gui, "Не реализовано."); + MessageWindow.show(gui, "Не реализовано."); } private void exit() { diff --git a/app/src/main/java/ru/project/ui/window/CustomDataSettingsWindow.java b/app/src/main/java/ru/project/ui/window/CustomDataSettingsWindow.java new file mode 100644 index 0000000..b59f805 --- /dev/null +++ b/app/src/main/java/ru/project/ui/window/CustomDataSettingsWindow.java @@ -0,0 +1,265 @@ +package ru.project.ui.window; + +import com.googlecode.lanterna.gui2.Button; +import com.googlecode.lanterna.gui2.Label; +import com.googlecode.lanterna.gui2.LinearLayout; +import com.googlecode.lanterna.gui2.Panel; +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import ru.project.collection.MyLinkedList; +import ru.project.collection.MyList; +import ru.project.model.AppState; +import ru.project.student.Student; +import ru.project.student.StudentBuilder; +import ru.project.ui.base.BaseWindow; + +public class CustomDataSettingsWindow extends BaseWindow { + + private final AppState state; + private final int collectionSize; + private final StudentBuilder studentBuilder; + + private String groupNumber; + private Double averageGrade; + private Integer recordBookNumber; + private Integer selectedObjectIndex; + + private final Label groupNumberLabel; + private final Label averageGradeLabel; + private final Label recordBookNumberLabel; + private final Label indexLabel; + + private final MyList preparedCustomDataCollection; + + public CustomDataSettingsWindow(WindowBasedTextGUI gui, AppState state, int collectionSize) { + + super("Настройка пользовательских данных", gui); + + this.state = state; + this.collectionSize = collectionSize; + this.studentBuilder = new StudentBuilder(); + this.preparedCustomDataCollection = new MyLinkedList<>(); + + MyList customDataCollection = state.getCustomDataCollection(); + + int elementsToCopy = Math.min(customDataCollection.size(), collectionSize); + + for (int i = 0; i < elementsToCopy; i++) { + preparedCustomDataCollection.add(customDataCollection.get(i)); + } + + for (int i = elementsToCopy; i < collectionSize; i++) { + preparedCustomDataCollection.add(null); + } + + Panel panel = new Panel(); + panel.setLayoutManager(new LinearLayout()); + + groupNumberLabel = new Label("Номер группы: не задан"); + + averageGradeLabel = new Label("Средний балл: не задан"); + + recordBookNumberLabel = new Label("Номер зачётной книжки: не задан"); + + indexLabel = new Label("Индекс объекта: не задан"); + + panel.addComponent(groupNumberLabel); + panel.addComponent(averageGradeLabel); + panel.addComponent(recordBookNumberLabel); + panel.addComponent(indexLabel); + + panel.addComponent(new Button("Задать номер группы", this::setGroupNumber)); + + panel.addComponent(new Button("Задать средний балл", this::setAverageGrade)); + + panel.addComponent(new Button("Задать номер зачётной книжки", this::setRecordBookNumber)); + + panel.addComponent(new Button("Задать индекс объекта", this::setObjectIndex)); + + panel.addComponent(new Button("Задать данные объекта", this::editObject)); + + panel.addComponent(new Button("Предпросмотр", this::preview)); + + panel.addComponent(new Button("Применить", this::apply)); + + panel.addComponent(new Button("Назад", this::close)); + + setComponent(panel); + } + + private void setGroupNumber() { + InputValueWindow window = + new InputValueWindow( + gui, + "Номер группы", + "Введите номер группы (например, A12):", + groupNumber, + value -> { + if (!value.matches(Student.getGroupNumberPattern())) { + MessageWindow.show(gui, "Номер группы должен соответствовать формату A12."); + return false; + } + + groupNumber = value; + studentBuilder.setGroupNumber(value); + + groupNumberLabel.setText("Номер группы: " + groupNumber); + + return true; + }); + + window.show(); + } + + private void setAverageGrade() { + InputValueWindow window = + new InputValueWindow( + gui, + "Средний балл", + "Введите средний балл от 0.0 до 5.0:", + averageGrade == null ? null : String.valueOf(averageGrade), + value -> { + try { + double parsedValue = Double.parseDouble(value); + + if (parsedValue < Student.getMinAverageGrade() + || parsedValue > Student.getMaxAverageGrade()) { + + MessageWindow.show(gui, "Средний балл должен быть от 0.0 до 5.0."); + return false; + } + + averageGrade = parsedValue; + studentBuilder.setAverageGrade(parsedValue); + + averageGradeLabel.setText("Средний балл: " + averageGrade); + + } catch (NumberFormatException e) { + MessageWindow.show(gui, "Введите корректное число."); + return false; + } + + return true; + }); + + window.show(); + } + + private void setRecordBookNumber() { + InputValueWindow window = + new InputValueWindow( + gui, + "Номер зачётной книжки", + "Введите номер зачётной книжки:", + recordBookNumber == null ? null : String.valueOf(recordBookNumber), + value -> { + try { + int parsedValue = Integer.parseInt(value); + + if (parsedValue < Student.getMinRecordBookNumber()) { + MessageWindow.show(gui, "Номер зачётной книжки должен быть положительным."); + return false; + } + + recordBookNumber = parsedValue; + studentBuilder.setRecordBookNumber(parsedValue); + + recordBookNumberLabel.setText("Номер зачётной книжки: " + recordBookNumber); + + } catch (NumberFormatException e) { + MessageWindow.show(gui, "Введите целое число."); + return false; + } + + return true; + }); + + window.show(); + } + + private void setObjectIndex() { + InputValueWindow window = + new InputValueWindow( + gui, + "Индекс объекта", + "Введите индекс объекта:", + selectedObjectIndex == null ? null : String.valueOf(selectedObjectIndex), + value -> { + try { + int index = Integer.parseInt(value); + + if (index < 0) { + MessageWindow.show(gui, "Индекс объекта не может быть отрицательным."); + return false; + } + + if (index >= collectionSize) { + MessageWindow.show(gui, "Индекс должен быть меньше размера коллекции."); + return false; + } + + selectedObjectIndex = index; + + indexLabel.setText("Индекс объекта: " + selectedObjectIndex); + + return true; + + } catch (NumberFormatException e) { + MessageWindow.show(gui, "Введите целое число."); + return false; + } + }); + + window.show(); + } + + private void editObject() { + if (!hasStudentData()) { + MessageWindow.show(gui, "Сначала задайте все поля студента."); + return; + } + + if (selectedObjectIndex == null) { + MessageWindow.show(gui, "Сначала задайте индекс объекта."); + return; + } + + if (selectedObjectIndex >= preparedCustomDataCollection.size()) { + MessageWindow.show(gui, "Индекс объекта выходит за границы подготовленной коллекции."); + return; + } + + Student student = studentBuilder.build(); + + preparedCustomDataCollection.set(selectedObjectIndex, student); + + MessageWindow.show(gui, "Данные объекта успешно заданы."); + } + + private void apply() { + MyList currentCollection = new MyLinkedList<>(); + + for (int i = 0; i < preparedCustomDataCollection.size(); i++) { + currentCollection.add(preparedCustomDataCollection.get(i)); + } + + state.setCustomDataCollection(preparedCustomDataCollection); + state.setCurrentCollection(currentCollection); + + close(); + } + + private void preview() { + if (!hasStudentData()) { + MessageWindow.show(gui, "Для предпросмотра сначала задайте все поля студента."); + return; + } + + Student student = studentBuilder.build(); + + MessageWindow.show(gui, student.toString()); + } + + private boolean hasStudentData() { + return groupNumber != null && averageGrade != null && recordBookNumber != null; + } +}