diff --git a/app/src/main/java/ru/project/model/AppState.java b/app/src/main/java/ru/project/model/AppState.java index 375877e..70f3beb 100644 --- a/app/src/main/java/ru/project/model/AppState.java +++ b/app/src/main/java/ru/project/model/AppState.java @@ -7,13 +7,9 @@ import ru.project.student.Student; public class AppState { private MyList mainCollection; - private MyList customDataCollection; - private String currentFilePath; public AppState() { this.mainCollection = new MyLinkedList<>(); - this.customDataCollection = new MyLinkedList<>(); - this.currentFilePath = null; } public MyList getMainCollection() { @@ -23,21 +19,4 @@ public class AppState { public void setMainCollection(MyList currentCollection) { this.mainCollection = currentCollection; } - - public MyList getCustomDataCollection() { - return customDataCollection; - } - - public void setCustomDataCollection(MyList customDataCollection) { - - this.customDataCollection = customDataCollection; - } - - public String getCurrentFilePath() { - return currentFilePath; - } - - public void setCurrentFilePath(String currentFilePath) { - this.currentFilePath = currentFilePath; - } } diff --git a/app/src/main/java/ru/project/ui/common/CollectionSizeInputWindow.java b/app/src/main/java/ru/project/ui/common/CollectionSizeInputWindow.java new file mode 100644 index 0000000..57b1d3a --- /dev/null +++ b/app/src/main/java/ru/project/ui/common/CollectionSizeInputWindow.java @@ -0,0 +1,51 @@ +package ru.project.ui.common; + +import com.googlecode.lanterna.gui2.WindowBasedTextGUI; +import java.util.function.Consumer; + +public class CollectionSizeInputWindow { + + private final WindowBasedTextGUI gui; + private final Integer currentSize; + private final Consumer onSizeEntered; + + public CollectionSizeInputWindow( + WindowBasedTextGUI gui, Integer currentSize, Consumer onSizeEntered) { + + this.gui = gui; + this.currentSize = currentSize; + this.onSizeEntered = onSizeEntered; + } + + public void showModal() { + InputValueWindow window = + new InputValueWindow( + gui, + "Размер коллекции", + "Введите размер коллекции:", + currentSize != null && currentSize > 0 ? String.valueOf(currentSize) : null, + this::handleSizeEntered); + + window.showModal(); + } + + private boolean handleSizeEntered(String value) { + try { + int size = Integer.parseInt(value); + + if (size <= 0) { + MessageWindow.showModal(gui, "Размер должен быть больше 0."); + + return false; + } + + onSizeEntered.accept(size); + return true; + + } catch (NumberFormatException e) { + MessageWindow.showModal(gui, "Введите целое число."); + + return false; + } + } +} diff --git a/app/src/main/java/ru/project/ui/creation/CreateCollectionMenu.java b/app/src/main/java/ru/project/ui/creation/CreateCollectionMenu.java index d8a1674..e56c4aa 100644 --- a/app/src/main/java/ru/project/ui/creation/CreateCollectionMenu.java +++ b/app/src/main/java/ru/project/ui/creation/CreateCollectionMenu.java @@ -5,94 +5,75 @@ 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.ui.base.BaseModalWindow; -import ru.project.ui.common.InputValueWindow; import ru.project.ui.common.MessageWindow; -import ru.project.ui.creation.manual.CustomDataSettingsWindow; +import ru.project.ui.creation.file.FileDataSettingsWindow; +import ru.project.ui.creation.file.FileFillSettings; +import ru.project.ui.creation.file.FileFillStrategy; +import ru.project.ui.creation.manual.ManualDataSettingsWindow; +import ru.project.ui.creation.manual.ManualFillSettings; +import ru.project.ui.creation.manual.ManualFillStrategy; public class CreateCollectionMenu extends BaseModalWindow { - private int collectionSize; - private FillMethod selectedFillMethod; + private final AppState state; + + private FillMethod selectedFillMethod; + private FillStrategy fillStrategy; - private final Label sizeLabel; private final Label fillMethodLabel; - private final CustomDataSettingsWindow customDataSettingsWindow; + private final ManualDataSettingsWindow manualDataSettingsWindow; + private final FileDataSettingsWindow fileDataSettingsWindow; public CreateCollectionMenu(WindowBasedTextGUI gui, AppState state) { + super("Создание новой коллекции", gui); - collectionSize = 0; - selectedFillMethod = FillMethod.CUSTOM; + this.state = state; + this.selectedFillMethod = FillMethod.CUSTOM; + this.fillStrategy = null; - customDataSettingsWindow = new CustomDataSettingsWindow(gui, state, () -> collectionSize); + this.manualDataSettingsWindow = new ManualDataSettingsWindow(gui, this::setManualFillStrategy); + this.fileDataSettingsWindow = new FileDataSettingsWindow(gui, this::setFileFillStrategy); Panel panel = new Panel(); panel.setLayoutManager(new LinearLayout()); - sizeLabel = new Label("Размер: не задан"); - fillMethodLabel = new Label("Способ заполнения: " + getFillMethodName(selectedFillMethod)); - panel.addComponent(sizeLabel); panel.addComponent(fillMethodLabel); - panel.addComponent(new Button("Задать размер", this::showCollectionSizeInputValueWindow)); - panel.addComponent(new Button("Выбрать способ заполнения", this::selectFillMethod)); panel.addComponent( new Button("Настроить текущий способ заполнения", this::setupCurrentFillMethod)); - panel.addComponent(new Button("Создать новую коллекцию", () -> updateMainCollection(state))); + panel.addComponent(new Button("Создать новую коллекцию", this::updateMainCollection)); panel.addComponent(new Button("Выйти", this::close)); setComponent(panel); } - private void showCollectionSizeInputValueWindow() { - InputValueWindow window = - new InputValueWindow( - gui, - "Размер коллекции", - "Введите размер коллекции:", - collectionSize > 0 ? String.valueOf(collectionSize) : null, - this::handleSizeEntered); - - window.showModal(); + private void setManualFillStrategy(ManualFillSettings settings) { + fillStrategy = new ManualFillStrategy(settings); } - private boolean handleSizeEntered(String value) { - try { - int enteredSize = Integer.parseInt(value); - if (enteredSize <= 0) { - MessageWindow.showModal(gui, "Размер должен быть больше 0."); - return false; - } - collectionSize = enteredSize; - sizeLabel.setText("Размер: " + collectionSize); - return true; - } catch (NumberFormatException e) { - MessageWindow.showModal(gui, "Введите целое число."); - return false; - } + private void setFileFillStrategy(FileFillSettings settings) { + fillStrategy = new FileFillStrategy(settings); } + // private void setRandomFillStrategy(RandomFillSettings settings) { + // fillStrategy = new RandomFillStrategy(settings); + // } + private void setupCurrentFillMethod() { switch (selectedFillMethod) { - case CUSTOM -> { - customDataSettingsWindow.showModal(); - } + case CUSTOM -> manualDataSettingsWindow.showModal(); - case FILE -> - // TODO - MessageWindow.showModal(gui, "Не реализовано."); + case FILE -> fileDataSettingsWindow.showModal(); case RANDOM -> MessageWindow.showModal( @@ -106,6 +87,7 @@ public class CreateCollectionMenu extends BaseModalWindow { gui, fillMethod -> { selectedFillMethod = fillMethod; + fillMethodLabel.setText( "Способ заполнения: " + getFillMethodName(selectedFillMethod)); }); @@ -113,57 +95,22 @@ public class CreateCollectionMenu extends BaseModalWindow { menu.showModal(); } - private void updateMainCollection(AppState state) { - if (collectionSize <= 0) { - MessageWindow.showModal(gui, "Сначала задайте размер коллекции."); + private void updateMainCollection() { + if (fillStrategy == null) { + MessageWindow.showModal(gui, "Сначала настройте способ заполнения."); + return; } - switch (selectedFillMethod) { - case CUSTOM: - createCollectionFromCustomData(state); - break; - - case RANDOM: - createCollectionFromRandomData(state); - break; - - case FILE: - createCollectionFromFileData(state); - break; - } - } - - private void createCollectionFromCustomData(AppState state) { - MyList customDataCollection = state.getCustomDataCollection(); - - MyList mainCollection = new MyLinkedList<>(); - - for (int i = 0; i < customDataCollection.size(); i++) { - mainCollection.add(customDataCollection.get(i)); - } - - state.setMainCollection(mainCollection); + state.setMainCollection(fillStrategy.create()); MessageWindow.showModal(gui, "Коллекция успешно создана."); } - private void createCollectionFromRandomData(AppState state) { - // TODO - MessageWindow.showModal(gui, "Не реализовано."); - } - - private void createCollectionFromFileData(AppState state) { - // TODO - MessageWindow.showModal(gui, "Не реализовано."); - } - private String getFillMethodName(FillMethod fillMethod) { return switch (fillMethod) { case CUSTOM -> "Пользовательские данные"; - case RANDOM -> "Случайные данные"; - case FILE -> "Данные из файла"; }; } diff --git a/app/src/main/java/ru/project/ui/creation/FillStrategy.java b/app/src/main/java/ru/project/ui/creation/FillStrategy.java new file mode 100644 index 0000000..f4931d8 --- /dev/null +++ b/app/src/main/java/ru/project/ui/creation/FillStrategy.java @@ -0,0 +1,9 @@ +package ru.project.ui.creation; + +import ru.project.collection.MyList; +import ru.project.student.Student; + +public interface FillStrategy { + + MyList create(); +} diff --git a/app/src/main/java/ru/project/ui/creation/manual/CustomDataSettingsWindow.java b/app/src/main/java/ru/project/ui/creation/manual/ManualDataSettingsWindow.java similarity index 64% rename from app/src/main/java/ru/project/ui/creation/manual/CustomDataSettingsWindow.java rename to app/src/main/java/ru/project/ui/creation/manual/ManualDataSettingsWindow.java index 19d31b1..dd02eeb 100644 --- a/app/src/main/java/ru/project/ui/creation/manual/CustomDataSettingsWindow.java +++ b/app/src/main/java/ru/project/ui/creation/manual/ManualDataSettingsWindow.java @@ -5,28 +5,28 @@ 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 java.util.function.Supplier; +import java.util.function.Consumer; 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.BaseModalWindow; import ru.project.ui.common.CollectionDisplayWindow; +import ru.project.ui.common.CollectionSizeInputWindow; import ru.project.ui.common.InputValueWindow; import ru.project.ui.common.MessageWindow; -public class CustomDataSettingsWindow extends BaseModalWindow { +public class ManualDataSettingsWindow extends BaseModalWindow { - private final AppState state; - private final Supplier requestedCollectionSize; private final StudentBuilder studentBuilder; - private String groupNumber; - private Double averageGrade; - private Integer recordBookNumber; - private Integer selectedObjectIndex; + private Integer lastRequestedCollectionSize; + private String lastRequestedGroupNumber; + private Double lastRequestedAverageGrade; + private Integer lastRequestedRecordBookNumber; + private Integer lastRequestedSelectedObjectIndex; + private final Label sizeLabel; private final Label groupNumberLabel; private final Label averageGradeLabel; private final Label recordBookNumberLabel; @@ -34,19 +34,23 @@ public class CustomDataSettingsWindow extends BaseModalWindow { private MyList preparedCustomDataCollection; - public CustomDataSettingsWindow( - WindowBasedTextGUI gui, AppState state, Supplier collectionSize) { + private final ManualFillSettings settings; + private final Consumer onApply; + + public ManualDataSettingsWindow(WindowBasedTextGUI gui, Consumer onApply) { super("Настройка пользовательских данных", gui); - this.state = state; - this.requestedCollectionSize = collectionSize; + this.onApply = onApply; + this.settings = new ManualFillSettings(); this.studentBuilder = new StudentBuilder(); Panel panel = new Panel(); panel.setLayoutManager(new LinearLayout()); + sizeLabel = new Label("Размер: не задан"); + groupNumberLabel = new Label("Номер группы: не задан"); averageGradeLabel = new Label("Средний балл: не задан"); @@ -55,11 +59,14 @@ public class CustomDataSettingsWindow extends BaseModalWindow { indexLabel = new Label("Индекс объекта: не задан"); + panel.addComponent(sizeLabel); panel.addComponent(groupNumberLabel); panel.addComponent(averageGradeLabel); panel.addComponent(recordBookNumberLabel); panel.addComponent(indexLabel); + panel.addComponent(new Button("Задать размер", this::showCollectionSizeInputWindow)); + panel.addComponent(new Button("Задать номер группы", this::setGroupNumber)); panel.addComponent(new Button("Задать средний балл", this::setAverageGrade)); @@ -79,25 +86,65 @@ public class CustomDataSettingsWindow extends BaseModalWindow { setComponent(panel); } + private void showCollectionSizeInputWindow() { + CollectionSizeInputWindow window = + new CollectionSizeInputWindow( + gui, preparedCustomDataCollection.size(), this::handleCollectionSizeEntered); + + window.showModal(); + } + + private void handleCollectionSizeEntered(int size) { + MyList resizedCollection = new MyLinkedList<>(); + + int currentCollectionSize = preparedCustomDataCollection.size(); + + int elementsToCopy = Math.min(currentCollectionSize, size); + + for (int i = 0; i < elementsToCopy; i++) { + resizedCollection.add(preparedCustomDataCollection.get(i)); + } + + for (int i = elementsToCopy; i < size; i++) { + resizedCollection.add(null); + } + + preparedCustomDataCollection = resizedCollection; + lastRequestedCollectionSize = size; + + if (lastRequestedSelectedObjectIndex != null + && lastRequestedSelectedObjectIndex >= lastRequestedCollectionSize) { + lastRequestedSelectedObjectIndex = null; + indexLabel.setText("Индекс объекта: не задан"); + } + + sizeLabel.setText("Размер: " + lastRequestedCollectionSize); + } + @Override public void showModal() { prepareCustomDataCollection(); + super.showModal(); } private void prepareCustomDataCollection() { + MyList currentCustomDataCollection = settings.getCollection(); + preparedCustomDataCollection = new MyLinkedList<>(); - int targetCollectionSize = requestedCollectionSize.get(); - int currentCustomDataCollectionSize = state.getCustomDataCollection().size(); + int currentCollectionSize = currentCustomDataCollection.size(); - int elementsToCopy = Math.min(currentCustomDataCollectionSize, targetCollectionSize); + int targetSize = + lastRequestedCollectionSize == null ? currentCollectionSize : lastRequestedCollectionSize; + + int elementsToCopy = Math.min(currentCollectionSize, targetSize); for (int i = 0; i < elementsToCopy; i++) { - preparedCustomDataCollection.add(state.getCustomDataCollection().get(i)); + preparedCustomDataCollection.add(currentCustomDataCollection.get(i)); } - for (int i = elementsToCopy; i < targetCollectionSize; i++) { + for (int i = elementsToCopy; i < targetSize; i++) { preparedCustomDataCollection.add(null); } } @@ -108,17 +155,17 @@ public class CustomDataSettingsWindow extends BaseModalWindow { gui, "Номер группы", "Введите номер группы (например, A12):", - groupNumber, + lastRequestedGroupNumber, value -> { if (!value.matches(Student.getGroupNumberPattern())) { MessageWindow.showModal(gui, "Номер группы должен соответствовать формату A12."); return false; } - groupNumber = value; + lastRequestedGroupNumber = value; studentBuilder.setGroupNumber(value); - groupNumberLabel.setText("Номер группы: " + groupNumber); + groupNumberLabel.setText("Номер группы: " + lastRequestedGroupNumber); return true; }); @@ -132,7 +179,7 @@ public class CustomDataSettingsWindow extends BaseModalWindow { gui, "Средний балл", "Введите средний балл от 0.0 до 5.0:", - averageGrade == null ? null : String.valueOf(averageGrade), + lastRequestedAverageGrade == null ? null : String.valueOf(lastRequestedAverageGrade), value -> { try { double parsedValue = Double.parseDouble(value); @@ -145,11 +192,11 @@ public class CustomDataSettingsWindow extends BaseModalWindow { return false; } - averageGrade = parsedValue; + lastRequestedAverageGrade = parsedValue; studentBuilder.setAverageGrade(parsedValue); - averageGradeLabel.setText("Средний балл: " + averageGrade); + averageGradeLabel.setText("Средний балл: " + lastRequestedAverageGrade); return true; @@ -169,7 +216,9 @@ public class CustomDataSettingsWindow extends BaseModalWindow { gui, "Номер зачётной книжки", "Введите номер зачётной книжки:", - recordBookNumber == null ? null : String.valueOf(recordBookNumber), + lastRequestedRecordBookNumber == null + ? null + : String.valueOf(lastRequestedRecordBookNumber), value -> { try { int parsedValue = Integer.parseInt(value); @@ -181,11 +230,12 @@ public class CustomDataSettingsWindow extends BaseModalWindow { return false; } - recordBookNumber = parsedValue; + lastRequestedRecordBookNumber = parsedValue; studentBuilder.setRecordBookNumber(parsedValue); - recordBookNumberLabel.setText("Номер зачётной книжки: " + recordBookNumber); + recordBookNumberLabel.setText( + "Номер зачётной книжки: " + lastRequestedRecordBookNumber); return true; @@ -205,34 +255,31 @@ public class CustomDataSettingsWindow extends BaseModalWindow { gui, "Индекс объекта", "Введите индекс объекта:", - selectedObjectIndex == null ? null : String.valueOf(selectedObjectIndex), + lastRequestedSelectedObjectIndex == null + ? null + : String.valueOf(lastRequestedSelectedObjectIndex), value -> { try { int index = Integer.parseInt(value); if (index < 0) { MessageWindow.showModal(gui, "Индекс объекта не может быть отрицательным."); - return false; } - int size = requestedCollectionSize.get(); - - if (index >= size) { + if (index >= preparedCustomDataCollection.size()) { MessageWindow.showModal(gui, "Индекс должен быть меньше размера коллекции."); - return false; } - selectedObjectIndex = index; + lastRequestedSelectedObjectIndex = index; - indexLabel.setText("Индекс объекта: " + selectedObjectIndex); + indexLabel.setText("Индекс объекта: " + lastRequestedSelectedObjectIndex); return true; } catch (NumberFormatException e) { MessageWindow.showModal(gui, "Введите целое число."); - return false; } }); @@ -246,28 +293,28 @@ public class CustomDataSettingsWindow extends BaseModalWindow { return; } - if (selectedObjectIndex == null) { + if (lastRequestedSelectedObjectIndex == null) { MessageWindow.showModal(gui, "Сначала задайте индекс объекта."); return; } - if (selectedObjectIndex >= preparedCustomDataCollection.size()) { + if (lastRequestedSelectedObjectIndex >= preparedCustomDataCollection.size()) { MessageWindow.showModal(gui, "Индекс объекта выходит за границы подготовленной коллекции."); return; } Student student = studentBuilder.build(); - preparedCustomDataCollection.set(selectedObjectIndex, student); + preparedCustomDataCollection.set(lastRequestedSelectedObjectIndex, student); MessageWindow.showModal(gui, "Данные объекта успешно заданы."); } private void apply() { - state.setCustomDataCollection(preparedCustomDataCollection); - prepareCustomDataCollection(); + settings.setCollection(preparedCustomDataCollection); + onApply.accept(settings); - MessageWindow.showModal(gui, "Пользовательские данные успешно применены."); + MessageWindow.showModal(gui, "Настройки создания коллекции вручную успешно применены."); } private void preview() { @@ -284,6 +331,8 @@ public class CustomDataSettingsWindow extends BaseModalWindow { } private boolean hasStudentData() { - return groupNumber != null && averageGrade != null && recordBookNumber != null; + return lastRequestedGroupNumber != null + && lastRequestedAverageGrade != null + && lastRequestedRecordBookNumber != null; } } diff --git a/app/src/main/java/ru/project/ui/creation/manual/ManualFillSettings.java b/app/src/main/java/ru/project/ui/creation/manual/ManualFillSettings.java new file mode 100644 index 0000000..ff82f46 --- /dev/null +++ b/app/src/main/java/ru/project/ui/creation/manual/ManualFillSettings.java @@ -0,0 +1,22 @@ +package ru.project.ui.creation.manual; + +import ru.project.collection.MyLinkedList; +import ru.project.collection.MyList; +import ru.project.student.Student; + +public class ManualFillSettings { + + private MyList manualDataCollection; + + public ManualFillSettings() { + this.manualDataCollection = new MyLinkedList<>(); + } + + public MyList getCollection() { + return manualDataCollection; + } + + public void setCollection(MyList collection) { + this.manualDataCollection = collection; + } +} diff --git a/app/src/main/java/ru/project/ui/creation/manual/ManualFillStrategy.java b/app/src/main/java/ru/project/ui/creation/manual/ManualFillStrategy.java new file mode 100644 index 0000000..1a5c54e --- /dev/null +++ b/app/src/main/java/ru/project/ui/creation/manual/ManualFillStrategy.java @@ -0,0 +1,28 @@ +package ru.project.ui.creation.manual; + +import ru.project.collection.MyLinkedList; +import ru.project.collection.MyList; +import ru.project.student.Student; +import ru.project.ui.creation.FillStrategy; + +public class ManualFillStrategy implements FillStrategy { + + private final ManualFillSettings settings; + + public ManualFillStrategy(ManualFillSettings settings) { + this.settings = settings; + } + + @Override + public MyList create() { + MyList mainCollection = new MyLinkedList<>(); + + MyList manualDataCollection = settings.getCollection(); + + for (int i = 0; i < manualDataCollection.size(); i++) { + mainCollection.add(manualDataCollection.get(i)); + } + + return mainCollection; + } +}