refactor: restructure application using MVP architecture
This commit is contained in:
@@ -2,39 +2,46 @@ package ru.project;
|
||||
|
||||
import com.googlecode.lanterna.gui2.MultiWindowTextGUI;
|
||||
import com.googlecode.lanterna.screen.Screen;
|
||||
import com.googlecode.lanterna.screen.TerminalScreen;
|
||||
import com.googlecode.lanterna.terminal.DefaultTerminalFactory;
|
||||
import ru.project.ui.MainMenu;
|
||||
import ru.project.ui.Navigator;
|
||||
import ru.project.model.AppState;
|
||||
import ru.project.presenter.MainPresenter;
|
||||
import ru.project.view.MainView;
|
||||
|
||||
public final class App {
|
||||
|
||||
private App() {}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
DefaultTerminalFactory factory = new DefaultTerminalFactory();
|
||||
|
||||
Screen screen = new TerminalScreen(factory.createTerminal());
|
||||
|
||||
screen.startScreen();
|
||||
public static void main(String[] args) {
|
||||
Screen screen = null;
|
||||
|
||||
try {
|
||||
DefaultTerminalFactory terminalFactory = new DefaultTerminalFactory();
|
||||
|
||||
screen = terminalFactory.createScreen();
|
||||
screen.startScreen();
|
||||
|
||||
MultiWindowTextGUI gui = new MultiWindowTextGUI(screen);
|
||||
|
||||
// Application state
|
||||
AppState state = new AppState();
|
||||
MainView view = new MainView();
|
||||
|
||||
// Controllers
|
||||
CollectionController collectionController = new CollectionController(state);
|
||||
MainPresenter presenter = new MainPresenter(state, view, gui);
|
||||
|
||||
// Navigation
|
||||
Navigator navigator = new Navigator(gui, collectionController);
|
||||
presenter.start();
|
||||
|
||||
// Application entry point
|
||||
gui.addWindowAndWait(new MainMenu(navigator));
|
||||
} catch (Exception e) {
|
||||
System.err.println("Произошла ошибка при выполнении программы:");
|
||||
e.printStackTrace();
|
||||
|
||||
} finally {
|
||||
screen.stopScreen();
|
||||
if (screen != null) {
|
||||
try {
|
||||
screen.stopScreen();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Не удалось корректно завершить работу терминала:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package ru.project;
|
||||
|
||||
public class AppState {
|
||||
|
||||
private DataCollection collection;
|
||||
|
||||
public DataCollection getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(DataCollection collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public boolean hasCollection() {
|
||||
return collection != null;
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package ru.project;
|
||||
|
||||
public class CollectionController {
|
||||
|
||||
private final AppState state;
|
||||
|
||||
public CollectionController(AppState state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public void createCollection() {
|
||||
DataCollection collection = new DataCollection();
|
||||
|
||||
collection.add("Charlie");
|
||||
collection.add("Alice");
|
||||
collection.add("Bob");
|
||||
collection.add("Alice");
|
||||
|
||||
state.setCollection(collection);
|
||||
}
|
||||
|
||||
public DataCollection getCollection() {
|
||||
return state.getCollection();
|
||||
}
|
||||
|
||||
public boolean hasCollection() {
|
||||
return state.hasCollection();
|
||||
}
|
||||
|
||||
public void sortCollection() {
|
||||
if (!state.hasCollection()) {
|
||||
return;
|
||||
}
|
||||
|
||||
state.getCollection().sort();
|
||||
}
|
||||
|
||||
public boolean contains(String element) {
|
||||
return state.hasCollection() && state.getCollection().contains(element);
|
||||
}
|
||||
|
||||
public int countOccurrences(String element) {
|
||||
if (!state.hasCollection()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return state.getCollection().count(element);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package ru.project;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class DataCollection {
|
||||
|
||||
private final List<String> elements = new ArrayList<>();
|
||||
|
||||
public void add(String element) {
|
||||
elements.add(element);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
Collections.sort(elements);
|
||||
}
|
||||
|
||||
public boolean contains(String element) {
|
||||
return elements.contains(element);
|
||||
}
|
||||
|
||||
public int count(String element) {
|
||||
int count = 0;
|
||||
|
||||
for (String current : elements) {
|
||||
if (current.equals(element)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public List<String> getElements() {
|
||||
return Collections.unmodifiableList(elements);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (elements.isEmpty()) {
|
||||
return "Коллекция пуста";
|
||||
}
|
||||
|
||||
return String.join(", ", elements);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package ru.project.model;
|
||||
|
||||
import ru.project.collection.MyLinkedList;
|
||||
import ru.project.collection.MyList;
|
||||
import ru.project.student.Student;
|
||||
|
||||
public class AppState {
|
||||
|
||||
private MyList<Student> collection;
|
||||
private String currentFilePath;
|
||||
|
||||
public AppState() {
|
||||
this.collection = new MyLinkedList<>();
|
||||
this.currentFilePath = null;
|
||||
}
|
||||
|
||||
public MyList<Student> getCollection() {
|
||||
return collection;
|
||||
}
|
||||
|
||||
public void setCollection(MyList<Student> collection) {
|
||||
this.collection = collection;
|
||||
}
|
||||
|
||||
public String getCurrentFilePath() {
|
||||
return currentFilePath;
|
||||
}
|
||||
|
||||
public void setCurrentFilePath(String currentFilePath) {
|
||||
this.currentFilePath = currentFilePath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package ru.project.presenter;
|
||||
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import ru.project.collection.MyList;
|
||||
import ru.project.model.AppState;
|
||||
import ru.project.student.Student;
|
||||
import ru.project.view.CollectionView;
|
||||
|
||||
public class CollectionPresenter {
|
||||
|
||||
private final AppState state;
|
||||
private final CollectionView view;
|
||||
private final WindowBasedTextGUI gui;
|
||||
|
||||
public CollectionPresenter(AppState state, CollectionView view, WindowBasedTextGUI gui) {
|
||||
this.state = state;
|
||||
this.view = view;
|
||||
this.gui = gui;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
MyList<Student> collection = state.getCollection();
|
||||
|
||||
if (collection == null || collection.isEmpty()) {
|
||||
view.showEmptyMessage(gui);
|
||||
return;
|
||||
}
|
||||
|
||||
view.showCollection(gui, collection);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
package ru.project.presenter;
|
||||
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import com.googlecode.lanterna.gui2.dialogs.MessageDialog;
|
||||
import com.googlecode.lanterna.gui2.dialogs.MessageDialogButton;
|
||||
import ru.project.model.AppState;
|
||||
import ru.project.view.CollectionView;
|
||||
import ru.project.view.MainView;
|
||||
|
||||
public class MainPresenter {
|
||||
|
||||
private final AppState state;
|
||||
private final MainView view;
|
||||
private final WindowBasedTextGUI gui;
|
||||
private final CollectionPresenter collectionPresenter;
|
||||
|
||||
public MainPresenter(AppState state, MainView view, WindowBasedTextGUI gui) {
|
||||
this.state = state;
|
||||
this.view = view;
|
||||
this.gui = gui;
|
||||
this.collectionPresenter = new CollectionPresenter(state, new CollectionView(), gui);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
bindActions();
|
||||
view.show(gui);
|
||||
}
|
||||
|
||||
private void bindActions() {
|
||||
view.setShowCollectionAction(this::showCollection);
|
||||
view.setCreateCollectionAction(this::createCollection);
|
||||
view.setSaveCollectionAction(this::saveCollection);
|
||||
view.setSortCollectionAction(this::sortCollection);
|
||||
view.setSearchCollectionAction(this::searchCollection);
|
||||
view.setCountOccurrencesAction(this::countOccurrences);
|
||||
view.setExitAction(this::exit);
|
||||
}
|
||||
|
||||
private void showCollection() {
|
||||
collectionPresenter.start();
|
||||
}
|
||||
|
||||
private void createCollection() {
|
||||
showMessage("Меню создания коллекции.");
|
||||
}
|
||||
|
||||
private void saveCollection() {
|
||||
showMessage("Меню сохранения коллекции.");
|
||||
}
|
||||
|
||||
private void sortCollection() {
|
||||
showMessage("Меню сортировки коллекции.");
|
||||
}
|
||||
|
||||
private void searchCollection() {
|
||||
showMessage("Меню поиска элемента.");
|
||||
}
|
||||
|
||||
private void countOccurrences() {
|
||||
showMessage("Меню подсчёта количества вхождений.");
|
||||
}
|
||||
|
||||
private void exit() {
|
||||
view.close();
|
||||
}
|
||||
|
||||
private void showMessage(String message) {
|
||||
MessageDialog.showMessageDialog(gui, "Информация", message, MessageDialogButton.OK);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class CollectionView extends EmptyMenu {
|
||||
|
||||
public CollectionView(CollectionController controller) {
|
||||
super("Текущая коллекция");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class CountOccurrencesMenu extends EmptyMenu {
|
||||
|
||||
public CountOccurrencesMenu(CollectionController controller) {
|
||||
super("Подсчёт количества вхождений");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class CreateCollectionMenu extends EmptyMenu {
|
||||
|
||||
public CreateCollectionMenu(CollectionController controller) {
|
||||
super("Создание новой коллекции");
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import com.googlecode.lanterna.gui2.BasicWindow;
|
||||
import com.googlecode.lanterna.gui2.Button;
|
||||
import com.googlecode.lanterna.gui2.Direction;
|
||||
import com.googlecode.lanterna.gui2.Label;
|
||||
import com.googlecode.lanterna.gui2.LinearLayout;
|
||||
import com.googlecode.lanterna.gui2.Panel;
|
||||
|
||||
public abstract class EmptyMenu extends BasicWindow {
|
||||
|
||||
protected EmptyMenu(String title) {
|
||||
super(title);
|
||||
|
||||
Panel panel = new Panel(new LinearLayout(Direction.VERTICAL));
|
||||
|
||||
panel.addComponent(new Label("Раздел находится в разработке"));
|
||||
|
||||
panel.addComponent(new Button("Назад", this::close));
|
||||
|
||||
setComponent(panel);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import com.googlecode.lanterna.gui2.BasicWindow;
|
||||
import com.googlecode.lanterna.gui2.Button;
|
||||
import com.googlecode.lanterna.gui2.Direction;
|
||||
import com.googlecode.lanterna.gui2.LinearLayout;
|
||||
import com.googlecode.lanterna.gui2.Panel;
|
||||
|
||||
public class MainMenu extends BasicWindow {
|
||||
|
||||
public MainMenu(Navigator navigator) {
|
||||
super("ГЛАВНОЕ МЕНЮ");
|
||||
|
||||
Panel panel = new Panel(new LinearLayout(Direction.VERTICAL));
|
||||
|
||||
panel.addComponent(new Button("Показать текущую коллекцию", navigator::showCollectionView));
|
||||
|
||||
panel.addComponent(new Button("Создать новую коллекцию", navigator::showCreateCollection));
|
||||
|
||||
panel.addComponent(
|
||||
new Button("Сохранить текущую коллекцию в файл", navigator::showSaveCollection));
|
||||
|
||||
panel.addComponent(new Button("Сортировать текущую коллекцию", navigator::showSortCollection));
|
||||
|
||||
panel.addComponent(new Button("Найти элемент", navigator::showSearchElement));
|
||||
|
||||
panel.addComponent(
|
||||
new Button("Подсчитать количество вхождений", navigator::showCountOccurrences));
|
||||
|
||||
panel.addComponent(new Button("Завершить выполнение программы", this::close));
|
||||
|
||||
setComponent(panel);
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import com.googlecode.lanterna.gui2.BasicWindow;
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class Navigator {
|
||||
|
||||
private final WindowBasedTextGUI gui;
|
||||
private final CollectionController collectionController;
|
||||
|
||||
public Navigator(WindowBasedTextGUI gui, CollectionController collectionController) {
|
||||
this.gui = gui;
|
||||
this.collectionController = collectionController;
|
||||
}
|
||||
|
||||
public void show(BasicWindow window) {
|
||||
gui.addWindowAndWait(window);
|
||||
}
|
||||
|
||||
public void showCollectionView() {
|
||||
show(new CollectionView(collectionController));
|
||||
}
|
||||
|
||||
public void showCreateCollection() {
|
||||
show(new CreateCollectionMenu(collectionController));
|
||||
}
|
||||
|
||||
public void showSaveCollection() {
|
||||
show(new SaveCollectionMenu(collectionController));
|
||||
}
|
||||
|
||||
public void showSortCollection() {
|
||||
show(new SortCollectionMenu(collectionController));
|
||||
}
|
||||
|
||||
public void showSearchElement() {
|
||||
show(new SearchElementMenu(collectionController));
|
||||
}
|
||||
|
||||
public void showCountOccurrences() {
|
||||
show(new CountOccurrencesMenu(collectionController));
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class SaveCollectionMenu extends EmptyMenu {
|
||||
|
||||
public SaveCollectionMenu(CollectionController controller) {
|
||||
super("Сохранение текущей коллекции");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class SearchElementMenu extends EmptyMenu {
|
||||
|
||||
public SearchElementMenu(CollectionController controller) {
|
||||
super("Поиск элемента");
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package ru.project.ui;
|
||||
|
||||
import ru.project.CollectionController;
|
||||
|
||||
public class SortCollectionMenu extends EmptyMenu {
|
||||
|
||||
public SortCollectionMenu(CollectionController controller) {
|
||||
super("Сортировка текущей коллекции");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package ru.project.view;
|
||||
|
||||
import com.googlecode.lanterna.gui2.BasicWindow;
|
||||
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.MyList;
|
||||
import ru.project.student.Student;
|
||||
|
||||
public class CollectionView {
|
||||
|
||||
public void showCollection(WindowBasedTextGUI gui, MyList<Student> collection) {
|
||||
BasicWindow window = new BasicWindow("Текущая коллекция");
|
||||
|
||||
Panel panel = new Panel();
|
||||
panel.setLayoutManager(new LinearLayout());
|
||||
|
||||
for (int i = 0; i < collection.size(); i++) {
|
||||
Student student = collection.get(i);
|
||||
|
||||
panel.addComponent(new Label((i + 1) + ". " + student));
|
||||
}
|
||||
|
||||
panel.addComponent(new Button("Вернуться", window::close));
|
||||
|
||||
window.setComponent(panel);
|
||||
|
||||
gui.addWindowAndWait(window);
|
||||
}
|
||||
|
||||
public void showEmptyMessage(WindowBasedTextGUI gui) {
|
||||
BasicWindow window = new BasicWindow("Текущая коллекция");
|
||||
|
||||
Panel panel = new Panel();
|
||||
panel.setLayoutManager(new LinearLayout());
|
||||
|
||||
panel.addComponent(new Label("Текущая коллекция пуста."));
|
||||
|
||||
panel.addComponent(new Button("Вернуться", window::close));
|
||||
|
||||
window.setComponent(panel);
|
||||
|
||||
gui.addWindowAndWait(window);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package ru.project.view;
|
||||
|
||||
import com.googlecode.lanterna.gui2.ActionListBox;
|
||||
import com.googlecode.lanterna.gui2.BasicWindow;
|
||||
import com.googlecode.lanterna.gui2.LinearLayout;
|
||||
import com.googlecode.lanterna.gui2.Panel;
|
||||
import com.googlecode.lanterna.gui2.WindowBasedTextGUI;
|
||||
|
||||
public class MainView {
|
||||
|
||||
private final BasicWindow window;
|
||||
private final ActionListBox menu;
|
||||
|
||||
public MainView() {
|
||||
window = new BasicWindow("Главное меню");
|
||||
|
||||
Panel panel = new Panel();
|
||||
panel.setLayoutManager(new LinearLayout());
|
||||
|
||||
menu = new ActionListBox();
|
||||
|
||||
panel.addComponent(menu);
|
||||
|
||||
window.setComponent(panel);
|
||||
}
|
||||
|
||||
public void setShowCollectionAction(Runnable action) {
|
||||
menu.addItem("Показать текущую коллекцию", action);
|
||||
}
|
||||
|
||||
public void setCreateCollectionAction(Runnable action) {
|
||||
menu.addItem("Меню создания новой коллекции", action);
|
||||
}
|
||||
|
||||
public void setSaveCollectionAction(Runnable action) {
|
||||
menu.addItem("Меню сохранения текущей коллекции в файл", action);
|
||||
}
|
||||
|
||||
public void setSortCollectionAction(Runnable action) {
|
||||
menu.addItem("Меню сортировки текущей коллекции", action);
|
||||
}
|
||||
|
||||
public void setSearchCollectionAction(Runnable action) {
|
||||
menu.addItem("Меню поиска элемента в текущей коллекции", action);
|
||||
}
|
||||
|
||||
public void setCountOccurrencesAction(Runnable action) {
|
||||
menu.addItem("Меню подсчёта количества вхождений элемента", action);
|
||||
}
|
||||
|
||||
public void setExitAction(Runnable action) {
|
||||
menu.addItem("Завершить выполнение программы", action);
|
||||
}
|
||||
|
||||
public void show(WindowBasedTextGUI gui) {
|
||||
gui.addWindowAndWait(window);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user