diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/FormPlaneConfig.java b/ProjectAirFighter/src/main/java/com/projectairfighter/FormPlaneConfig.java index bf1d8ea..23d17e9 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/FormPlaneConfig.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/FormPlaneConfig.java @@ -19,17 +19,23 @@ import javafx.scene.paint.Color; import javafx.stage.Stage; import java.net.URL; -import java.util.Random; import java.util.ResourceBundle; public class FormPlaneConfig extends Application implements Initializable { - @FXML private Spinner speed; - @FXML private Spinner weight; - @FXML private Spinner countEngine; - @FXML private CheckBox checkBoxRockets; - @FXML private CheckBox checkBoxWings; - @FXML private Canvas canvas; - @FXML private Button buttonCancel; + @FXML + private Spinner speed; + @FXML + private Spinner weight; + @FXML + private Spinner countEngine; + @FXML + private CheckBox checkBoxRockets; + @FXML + private CheckBox checkBoxWings; + @FXML + private Canvas canvas; + @FXML + private Button buttonCancel; private DrawningWarPlane plane; private IDrawableExtras engine = null; @@ -197,12 +203,7 @@ public class FormPlaneConfig extends Application implements Initializable { if (db.hasString()) { String droppedText = db.getString(); if (engine == null) { - IDrawableExtras[] engineDrawings = { - new EllipticalEngineDrawing(), - new TriangleEngineDrawing(), - new RectangleEngineDrawing() - }; - engine = engineDrawings[new Random().nextInt(engineDrawings.length)]; + engine = new RectangleEngineDrawing(); engine.setCountEngines(countEngine.getValue()); } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/FormWarPlaneCollection.java b/ProjectAirFighter/src/main/java/com/projectairfighter/FormWarPlaneCollection.java index e4003ce..49072a7 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/FormWarPlaneCollection.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/FormWarPlaneCollection.java @@ -1,9 +1,12 @@ package com.projectairfighter; import com.projectairfighter.collectiongenericobjects.*; +import com.projectairfighter.drawnings.DrawningPlaneCompareByColor; +import com.projectairfighter.drawnings.DrawningPlaneCompareByType; import com.projectairfighter.drawnings.DrawningWarPlane; import com.projectairfighter.exceptions.CollectionOverflowException; import com.projectairfighter.exceptions.ObjectNotFoundException; +import com.projectairfighter.exceptions.ObjectNotUniqueException; import com.projectairfighter.exceptions.PositionOutOfCollectionException; import javafx.application.Application; import javafx.fxml.FXML; @@ -21,6 +24,7 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; import java.net.URL; +import java.util.Comparator; import java.util.ResourceBundle; import java.util.Stack; @@ -38,8 +42,8 @@ public class FormWarPlaneCollection extends Application implements Initializable @FXML private ListView listViewCollection; private static FormWarPlaneCollection formWarPlaneCollection; - private static final Logger userLogger = LogManager.getLogger("useractions"); - private static final Logger errorsLogger = LogManager.getLogger("errors"); + protected static final Logger userLogger = LogManager.getLogger("useractions"); + protected static final Logger errorsLogger = LogManager.getLogger("errors"); public static void setFormWarPlaneCollection(FormWarPlaneCollection controller) { formWarPlaneCollection = controller; @@ -74,6 +78,9 @@ public class FormWarPlaneCollection extends Application implements Initializable } catch (CollectionOverflowException e) { showError("Ошибка переполнения коллекции"); errorsLogger.warn("Ошибка: {}", e.getMessage()); + } catch (ObjectNotUniqueException ex) { + showError("Такой объект уже присутствует в коллекции"); + errorsLogger.warn("Ошибка: {}", ex.getMessage()); } } @@ -315,8 +322,9 @@ public class FormWarPlaneCollection extends Application implements Initializable private void refreshListBoxItems() { listViewCollection.getItems().clear(); - for (String colName : storageCollection.keys()) { - if (colName != null && !colName.isEmpty()) { + for (int i = 0; i < storageCollection.keys().size(); i++){ + String colName = storageCollection.keys().get(i).name(); + if (!colName.isEmpty()){ listViewCollection.getItems().add(colName); } } @@ -352,6 +360,25 @@ public class FormWarPlaneCollection extends Application implements Initializable refreshListBoxItems(); } + @FXML + private void buttonSortByType() throws PositionOutOfCollectionException, ObjectNotFoundException { + comparePlanes(new DrawningPlaneCompareByType()); + } + + @FXML + private void buttonSortByColor() throws PositionOutOfCollectionException, ObjectNotFoundException { + comparePlanes(new DrawningPlaneCompareByColor()); + } + + private void comparePlanes(Comparator comparator) throws PositionOutOfCollectionException, ObjectNotFoundException { + if (company == null) { + return; + } + + company.sort(comparator); + company.show(canvasWarPlane); + } + private void showAlert(String message) { Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Сообщение"); diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/AbstractCompany.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/AbstractCompany.java index 917f807..94b9683 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/AbstractCompany.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/AbstractCompany.java @@ -1,5 +1,6 @@ package com.projectairfighter.collectiongenericobjects; +import com.projectairfighter.drawnings.DrawningPlaneEquatables; import com.projectairfighter.drawnings.DrawningWarPlane; import com.projectairfighter.exceptions.CollectionOverflowException; import com.projectairfighter.exceptions.ObjectNotFoundException; @@ -7,6 +8,7 @@ import com.projectairfighter.exceptions.PositionOutOfCollectionException; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; +import java.util.Comparator; import java.util.Random; public abstract class AbstractCompany { @@ -33,7 +35,7 @@ public abstract class AbstractCompany { if (collection == null) { return -1; } - return collection.insert(plane); + return collection.insert(plane, new DrawningPlaneEquatables()); } public DrawningWarPlane removePlane(int position) throws PositionOutOfCollectionException, ObjectNotFoundException { @@ -60,6 +62,10 @@ public abstract class AbstractCompany { } } + public void sort(Comparator comparator){ + collection.collectionSort(comparator); + } + protected abstract void drawBackground(GraphicsContext gc); protected abstract void setObjectsPosition() throws PositionOutOfCollectionException, ObjectNotFoundException; diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/CollectionInfo.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/CollectionInfo.java new file mode 100644 index 0000000..26b07ed --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/CollectionInfo.java @@ -0,0 +1,50 @@ +package com.projectairfighter.collectiongenericobjects; + +import java.util.Objects; + +/** + * Класс, хранящий информацию по коллекции + * @param name + * @param collectionType + * @param description + */ + +public record CollectionInfo(String name, CollectionType collectionType, String description) { + + private static final String SEPARATOR = "-"; + + public static CollectionInfo getCollectionInfo(String data) { + String[] strs = data.split(SEPARATOR); + if (strs.length < 1 || strs.length > 3) { + return null; + } + + CollectionType collectionType; + try { + collectionType = CollectionType.valueOf(strs[1]); + } catch (IllegalArgumentException e) { + return null; + } + + return new CollectionInfo(strs[0], collectionType, strs.length > 2 ? strs[2] : ""); + } + + @Override + public String toString() { + return name + SEPARATOR + collectionType + SEPARATOR + description; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + CollectionInfo that = (CollectionInfo) obj; + return Objects.equals(name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(name); + } +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ICollectionGenericObjects.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ICollectionGenericObjects.java index 2811c32..0b3acf8 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ICollectionGenericObjects.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ICollectionGenericObjects.java @@ -4,6 +4,8 @@ import com.projectairfighter.exceptions.CollectionOverflowException; import com.projectairfighter.exceptions.ObjectNotFoundException; import com.projectairfighter.exceptions.PositionOutOfCollectionException; +import java.util.Comparator; + public interface ICollectionGenericObjects { /** * Количество объектов в коллекции @@ -16,6 +18,23 @@ public interface ICollectionGenericObjects { int getMaxCount(); void setMaxCount(int value); + /** + * Добавление объекта в коллекцию + * + * @param obj Добавляемый объект + * @return 1 - вставка прошла удачно, 0 - вставка не удалась + */ + int insert(T obj, Comparator comparator) throws CollectionOverflowException, PositionOutOfCollectionException; + + /** + * Добавление объекта в коллекцию на конкретную позицию + * + * @param obj Добавляемый объект + * @param position Позиция + * @return 1 - вставка прошла удачно, 0 - вставка не удалась + */ + int insert(T obj, int position, Comparator comparator) throws PositionOutOfCollectionException, CollectionOverflowException; + /** * Добавление объекта в коллекцию * @@ -64,5 +83,7 @@ public interface ICollectionGenericObjects { * @return Поэлементный вывод элементов коллекции. */ Iterable getItems(); + + void collectionSort(Comparator comparator); } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ListGenericObjects.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ListGenericObjects.java index 632984f..71eaa2c 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ListGenericObjects.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/ListGenericObjects.java @@ -1,12 +1,10 @@ package com.projectairfighter.collectiongenericobjects; import com.projectairfighter.exceptions.CollectionOverflowException; +import com.projectairfighter.exceptions.ObjectNotUniqueException; import com.projectairfighter.exceptions.PositionOutOfCollectionException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; +import java.util.*; public class ListGenericObjects implements ICollectionGenericObjects { private final List collection; @@ -82,6 +80,58 @@ public class ListGenericObjects implements ICollectionGenericObjects { }; } + @Override + public void collectionSort(Comparator comparator) { + collection.sort(comparator); + } + + @Override + public int insert(T obj, Comparator comparator) throws CollectionOverflowException { + if (comparator == null) { + if (collection.contains(obj)) { + throw new ObjectNotUniqueException(); + } + } else { + for (T item : collection) { + if (comparator.compare(item, obj) != 0) { + throw new ObjectNotUniqueException(); + } + } + } + + if (getCount() == maxCount) { + throw new CollectionOverflowException(collection.size()); + } + collection.add(obj); + return getCount(); + } + + @Override + public int insert(T obj, int position, Comparator comparator) throws PositionOutOfCollectionException, CollectionOverflowException { + if (comparator == null) { + if (collection.contains(obj)) { + throw new ObjectNotUniqueException(position); + } + } else { + for (T item : collection) { + if (comparator.compare(item, obj) != 0) { + throw new ObjectNotUniqueException(position); + } + } + } + + if (position < 0 || position >= getCount()) { + throw new PositionOutOfCollectionException(); + } + + if (getCount() == maxCount) { + throw new CollectionOverflowException(collection.size()); + } + + collection.add(position, obj); + return position; + } + @Override public int insert(T obj) throws CollectionOverflowException { if (getCount() == maxCount) { @@ -97,7 +147,7 @@ public class ListGenericObjects implements ICollectionGenericObjects { throw new PositionOutOfCollectionException(); } - if (getCount() == maxCount){ + if (getCount() == maxCount) { throw new CollectionOverflowException(); } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/MassiveGenericObjects.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/MassiveGenericObjects.java index 0f28141..5e4a88e 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/MassiveGenericObjects.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/MassiveGenericObjects.java @@ -1,10 +1,13 @@ package com.projectairfighter.collectiongenericobjects; +import com.projectairfighter.drawnings.DrawningWarPlane; import com.projectairfighter.exceptions.CollectionOverflowException; import com.projectairfighter.exceptions.ObjectNotFoundException; +import com.projectairfighter.exceptions.ObjectNotUniqueException; import com.projectairfighter.exceptions.PositionOutOfCollectionException; import java.util.Arrays; +import java.util.Comparator; import java.util.Iterator; import java.util.NoSuchElementException; @@ -23,7 +26,7 @@ public class MassiveGenericObjects implements ICollectionGenericObjects { @Override @SuppressWarnings("unchecked") - public void setMaxCount(int value){ + public void setMaxCount(int value) { if (value < 0) return; T[] newCollection = (T[]) new Object[value]; @@ -43,8 +46,7 @@ public class MassiveGenericObjects implements ICollectionGenericObjects { throw new PositionOutOfCollectionException(); } - if (collection[position] == null) - { + if (collection[position] == null) { throw new ObjectNotFoundException(position); } @@ -63,6 +65,46 @@ public class MassiveGenericObjects implements ICollectionGenericObjects { return CollectionType.Massive; } + @Override + public int insert(T obj, Comparator comparator) throws PositionOutOfCollectionException, CollectionOverflowException { + return insert(obj, 0, comparator); + } + + @Override + @SuppressWarnings("unchecked") + public int insert(T obj, int position, Comparator comparator) throws PositionOutOfCollectionException, CollectionOverflowException { + if (position < 0 || position >= getCount()) { + throw new PositionOutOfCollectionException(position); + } + if (collection[position] == null) { + collection[position] = obj; + return position; + } + + for (T item : collection) { + if (item instanceof DrawningWarPlane dwItem && obj instanceof DrawningWarPlane dwObj) { + if (comparator.compare((T) dwItem, (T) dwObj) > 0) { + throw new ObjectNotUniqueException(position); + } + } + } + + for (int i = position + 1; i < getCount(); i++) { + if (collection[i] == null) { + collection[i] = obj; + return i; + } + } + for (int i = position - 1; i >= 0; i--) { + if (collection[i] == null) { + collection[i] = obj; + return i; + } + } + + throw new CollectionOverflowException(collection.length); + } + @Override public int insert(T obj) throws PositionOutOfCollectionException, CollectionOverflowException { return insert(obj, 0); @@ -100,8 +142,7 @@ public class MassiveGenericObjects implements ICollectionGenericObjects { throw new PositionOutOfCollectionException(position); } - if (collection[position] == null) - { + if (collection[position] == null) { throw new ObjectNotFoundException(position); } @@ -134,5 +175,10 @@ public class MassiveGenericObjects implements ICollectionGenericObjects { } }; } + + @Override + public void collectionSort(Comparator comparator) { + Arrays.sort(collection, comparator); + } } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/StorageCollection.java b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/StorageCollection.java index 7291eca..8486409 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/StorageCollection.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/collectiongenericobjects/StorageCollection.java @@ -20,7 +20,7 @@ public class StorageCollection { /** * Словарь (хранилище) с коллекциями. */ - private final Map> storages; + private final Map> storages; /** * Ключевое слово, с которого должен начинаться файл @@ -58,8 +58,8 @@ public class StorageCollection { * * @return Список названий коллекций. */ - public List keys() { - return new ArrayList<>(storages.keySet()); + public List keys() { + return storages.keySet().stream().toList(); } /** @@ -76,17 +76,18 @@ public class StorageCollection { * @param collectionType Тип коллекции. */ public void addCollection(String name, CollectionType collectionType) { - if (name == null || storages.containsKey(name)) { + CollectionInfo collectionInfo = new CollectionInfo(name, collectionType, ""); + if (name == null || storages.containsKey(collectionInfo)) { return; } switch (collectionType) { case None: return; case Massive: - storages.put(name, new MassiveGenericObjects<>()); + storages.put(collectionInfo, new MassiveGenericObjects<>()); return; case List: - storages.put(name, new ListGenericObjects<>()); + storages.put(collectionInfo, new ListGenericObjects<>()); } } @@ -96,10 +97,11 @@ public class StorageCollection { * @param name Название коллекции. */ public void delCollection(String name) { - if (name == null || !storages.containsKey(name)) { + CollectionInfo collectionInfo = new CollectionInfo(name, CollectionType.None, ""); + if (name == null || !storages.containsKey(collectionInfo)) { return; } - storages.remove(name); + storages.remove(collectionInfo); } /** @@ -109,10 +111,12 @@ public class StorageCollection { * @return Коллекция или null, если коллекция с данным названием отсутствует. */ public ICollectionGenericObjects get(String name) { - if (name == null || !storages.containsKey(name)) { + CollectionInfo collectionInfo = new CollectionInfo(name, CollectionType.None, ""); + + if (name == null || !storages.containsKey(collectionInfo)) { return null; } - return storages.get(name); + return storages.get(collectionInfo); } /** @@ -123,7 +127,8 @@ public class StorageCollection { * @return Элемент коллекции или null, если коллекция с данным названием отсутствует или индекс некорректен. */ public T getElement(String name, int index) throws PositionOutOfCollectionException, ObjectNotFoundException { - return storages.get(name).get(index); + CollectionInfo collectionInfo = new CollectionInfo(name, CollectionType.None, ""); + return storages.get(collectionInfo).get(index); } /** @@ -146,7 +151,7 @@ public class StorageCollection { writer.write(COLLECTION_KEY); writer.newLine(); - for (Map.Entry> entry : storages.entrySet()) { + for (Map.Entry> entry : storages.entrySet()) { if (entry.getValue().getCount() == 0) { continue; } @@ -197,7 +202,7 @@ public class StorageCollection { writer.write(COLLECTION_KEY_ONE_COL); writer.newLine(); - for (Map.Entry> entry : storages.entrySet()) { + for (Map.Entry> entry : storages.entrySet()) { if ((entry.getValue().getCount() == 0) || !entry.getKey().equals(collection)) { continue; } @@ -205,8 +210,6 @@ public class StorageCollection { StringBuilder sb = new StringBuilder(); sb.append(entry.getKey()); sb.append(SEPARATOR_FOR_KEY_VALUE_ONE_TYPE_COL); - sb.append(entry.getValue().getCollectionType()); - sb.append(SEPARATOR_FOR_KEY_VALUE_ONE_TYPE_COL); sb.append(entry.getValue().getMaxCount()); sb.append(SEPARATOR_FOR_KEY_VALUE_ONE_TYPE_COL); @@ -236,44 +239,45 @@ public class StorageCollection { * @return результат обработки */ @SuppressWarnings("unchecked") - private boolean processRecord(String recordLine, String keyValueSeparator, String itemSeparator) throws CollectionOverflowException { + private boolean processRecord(String recordLine, String keyValueSeparator, String itemSeparator) throws Exception { String[] record = recordLine.split(keyValueSeparator); - if (record.length != 4) { + if (record.length != 3) { return false; } ICollectionGenericObjects collection; - if (storages.containsKey(record[0])) { - storages.get(record[0]).clear(); - collection = storages.get(record[0]); + CollectionInfo collectionInfo = Optional.ofNullable(CollectionInfo.getCollectionInfo(record[0])) + .orElseThrow(() -> new Exception("Не удалось определить информацию коллекции: " + record[0])); + + if (storages.containsKey(collectionInfo)) { + storages.get(collectionInfo).clear(); + collection = storages.get(collectionInfo); } else { - CollectionType collectionType = CollectionType.valueOf(record[1]); - collection = StorageCollection.createCollection(collectionType); + collection = createCollection(collectionInfo.collectionType()); } + if (collection == null) { throw new IllegalStateException("Не удалось определить тип коллекции:" + record[1]); } - collection.setMaxCount(Integer.parseInt(record[2])); + collection.setMaxCount(Integer.parseInt(record[1])); - String[] items = record[3].split(itemSeparator, -1); + String[] items = record[2].split(itemSeparator, -1); for (String elem : items) { T ship = (T) createDrawingPlane(elem); - try - { + try { if (ship != null && collection.insert(ship) == -1) - throw new IllegalStateException("Объект не удалось добавить в коллекцию: " + record[3]); - } - catch (CollectionOverflowException ex){ + throw new IllegalStateException("Объект не удалось добавить в коллекцию: " + record[2]); + } catch (CollectionOverflowException ex) { throw new CollectionOverflowException("Коллекция переполнена", ex); } catch (PositionOutOfCollectionException ex) { throw new CollectionOverflowException("Выход за пределы коллекции", ex); } } - storages.put(record[0], collection); + storages.put(collectionInfo, collection); return true; } @@ -281,7 +285,7 @@ public class StorageCollection { /** * Загрузка информации из файла */ - public void loadData(String filename) throws IOException, CollectionOverflowException { + public void loadData(String filename) throws Exception { File file = new File(filename); if (!file.exists()) { throw new FileNotFoundException("Файл не существует"); @@ -316,10 +320,11 @@ public class StorageCollection { /** * Создание коллекции по типу */ + @SuppressWarnings("unchecked") private static ICollectionGenericObjects createCollection(CollectionType collectionType) { return switch (collectionType) { - case Massive -> new MassiveGenericObjects<>(); - case List -> new ListGenericObjects<>(); + case Massive -> (ICollectionGenericObjects) new MassiveGenericObjects<>(); + case List -> (ICollectionGenericObjects) new ListGenericObjects<>(); default -> null; }; } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java index 7251a64..3483faa 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java @@ -5,7 +5,12 @@ import com.projectairfighter.entities.EntityWarPlane; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; -public class DrawningAirFighter extends DrawningWarPlane { +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class DrawningAirFighter extends DrawningWarPlane implements Iterator, Iterable { + private int currentIndex = 0; + public DrawningAirFighter(int speed, double weight, Color bodyColor, IDrawableExtras engineDrawing, Color additionalColor, boolean bodyRockets, boolean additionalWings) { super(speed, weight, bodyColor, engineDrawing); @@ -57,4 +62,60 @@ public class DrawningAirFighter extends DrawningWarPlane { } super.drawTransport(gc); } + + // Реализация методов Iterator + @Override + public boolean hasNext() { + return currentIndex < 6; + } + + @Override + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return switch (currentIndex++) { + case 0 -> entityWarPlane; + case 1 -> pictureWidth; + case 2 -> pictureHeight; + case 3 -> startPosX; + case 4 -> startPosY; + case 5 -> new int[]{drawningAirFighterWidth, drawningAirFighterHeight}; + default -> throw new NoSuchElementException(); + }; + } + + // Метод для сброса итератора + public void reset() { + currentIndex = 0; + } + + // Реализация методов Iterable + @Override + public Iterator iterator() { + return new Iterator<>() { + private int index = 0; + + @Override + public boolean hasNext() { + return index < 6; + } + + @Override + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return switch (index++) { + case 0 -> entityWarPlane; + case 1 -> pictureWidth; + case 2 -> pictureHeight; + case 3 -> startPosX; + case 4 -> startPosY; + case 5 -> new int[]{drawningAirFighterWidth, drawningAirFighterHeight}; + default -> throw new NoSuchElementException(); + }; + } + }; + } } \ No newline at end of file diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByColor.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByColor.java new file mode 100644 index 0000000..266c696 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByColor.java @@ -0,0 +1,36 @@ +package com.projectairfighter.drawnings; + +import java.util.Comparator; + +/** + * Comparison by color, speed, weight. + */ +public class DrawningPlaneCompareByColor implements Comparator { + + @Override + public int compare(DrawningWarPlane x, DrawningWarPlane y) { + if (x == null || x.entityWarPlane == null) { + return 1; + } + + if (y == null || y.entityWarPlane == null) { + return -1; + } + + // Compare by body color name + int bodyColorCompare = y.entityWarPlane.getBodyColor().toString().compareTo(x.entityWarPlane.getBodyColor().toString()); + + if (bodyColorCompare != 0) { + return bodyColorCompare; + } + + // Compare by speed + int speedCompare = Integer.compare(y.entityWarPlane.getSpeed(), x.entityWarPlane.getSpeed()); + if (speedCompare != 0) { + return speedCompare; + } + + // Compare by weight + return Integer.compare((int) y.entityWarPlane.getWeight(), (int) x.entityWarPlane.getWeight()); + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByType.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByType.java new file mode 100644 index 0000000..f4564b2 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneCompareByType.java @@ -0,0 +1,34 @@ +package com.projectairfighter.drawnings; + +import java.util.Comparator; + +/** + * Comparison by type, speed, weight. + */ +public class DrawningPlaneCompareByType implements Comparator { + + @Override + public int compare(DrawningWarPlane x, DrawningWarPlane y) { + if (x == null || x.entityWarPlane == null) { + return 1; + } + + if (y == null || y.entityWarPlane == null) { + return -1; + } + + // Compare by type name + if (!x.getClass().getName().equals(y.getClass().getName())) { + return y.getClass().getName().compareTo(x.getClass().getName()); + } + + // Compare by speed + int speedCompare = Integer.compare(y.entityWarPlane.getSpeed(), x.entityWarPlane.getSpeed()); + if (speedCompare != 0) { + return speedCompare; + } + + // Compare by weight + return Integer.compare((int) y.entityWarPlane.getWeight(), (int) x.entityWarPlane.getWeight()); + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneEquatables.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneEquatables.java new file mode 100644 index 0000000..c502086 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningPlaneEquatables.java @@ -0,0 +1,40 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityAirFighter; + +import java.util.Comparator; + +/** + * Implementation of the comparison of two drawing class objects. + */ +public class DrawningPlaneEquatables implements Comparator { + @Override + public int compare(DrawningWarPlane x, DrawningWarPlane y) { + if (x.entityWarPlane == null || y.entityWarPlane == null) return 0; + + if (!x.getClass().getName().equals(y.getClass().getName())) return 0; + + if (x.entityWarPlane.getSpeed() != y.entityWarPlane.getSpeed()) return 0; + + if (x.entityWarPlane.getWeight() != y.entityWarPlane.getWeight()) return 0; + + if (x.entityWarPlane.getBodyColor() != y.entityWarPlane.getBodyColor()) return 0; + + if ((x.entityWarPlane.getEngineDrawing().getCountEngines() != y.entityWarPlane.getEngineDrawing().getCountEngines() + && !x.entityWarPlane.getEngineDrawing().getClass().getSimpleName().equals(y.entityWarPlane.getEngineDrawing().getClass().getSimpleName()))) + return 0; + + + if (x instanceof DrawningAirFighter && y instanceof DrawningAirFighter) { + EntityAirFighter dx = (EntityAirFighter) x.entityWarPlane; + EntityAirFighter dy = (EntityAirFighter) y.entityWarPlane; + if (dx.getAdditionalColor() != dy.getAdditionalColor()) return 0; + + if (dx.hasBodyRockets() != dy.hasBodyRockets()) return 0; + + if (dx.hasAdditionalWings() != dy.hasAdditionalWings()) return 0; + } + + return 1; + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java index 61da9d6..d579749 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java @@ -4,20 +4,24 @@ import com.projectairfighter.entities.EntityWarPlane; import javafx.scene.canvas.GraphicsContext; import javafx.scene.paint.Color; -public class DrawningWarPlane { +import java.util.Iterator; +import java.util.NoSuchElementException; + +public class DrawningWarPlane implements Iterator, Iterable { // Сущность public EntityWarPlane entityWarPlane; // Ширина и высота окна - private Integer pictureWidth = 0; - private Integer pictureHeight = 0; + protected Integer pictureWidth = 0; + protected Integer pictureHeight = 0; // Начальные координаты прорисовки истребителя - private Integer startPosX = null; - private Integer startPosY = null; + protected Integer startPosX = null; + protected Integer startPosY = null; + private int currentIndex = 0; - private final int drawningAirFighterWidth = 157; - private final int drawningAirFighterHeight = 140; + protected final int drawningAirFighterWidth = 157; + protected final int drawningAirFighterHeight = 140; public Integer getPosX(){ return startPosX; } @@ -145,4 +149,36 @@ public class DrawningWarPlane { new double[]{startPosY + 79, startPosY + 133, startPosY + 133, startPosY + 79}, 4); } + + // Реализация методов Iterator + @Override + public boolean hasNext() { + return currentIndex < 6; + } + + @Override + public Object next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + return switch (currentIndex++) { + case 0 -> entityWarPlane; + case 1 -> pictureWidth; + case 2 -> pictureHeight; + case 3 -> startPosX; + case 4 -> startPosY; + case 5 -> new int[]{drawningAirFighterWidth, drawningAirFighterHeight}; + default -> throw new NoSuchElementException(); + }; + } + + // Метод для сброса итератора + public void reset() { + currentIndex = 0; + } + + @Override + public Iterator iterator() { + return this; + } } diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java index f909a1a..9d7c467 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java @@ -37,6 +37,7 @@ public class EntityAirFighter extends EntityWarPlane { return additionalWings; } + // Конструктор public EntityAirFighter(int speed, double weight, Color bodyColor, IDrawableExtras engineDrawing, Color additionalColor, boolean bodyRockets, boolean additionalWings){ diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/exceptions/ObjectNotUniqueException.java b/ProjectAirFighter/src/main/java/com/projectairfighter/exceptions/ObjectNotUniqueException.java new file mode 100644 index 0000000..9d8712a --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/exceptions/ObjectNotUniqueException.java @@ -0,0 +1,19 @@ +package com.projectairfighter.exceptions; + +public class ObjectNotUniqueException extends RuntimeException { + public ObjectNotUniqueException() { + super("В коллекции уже есть такой элемент"); + } + + public ObjectNotUniqueException(String message) { + super(message); + } + + public ObjectNotUniqueException(String message, Throwable cause) { + super(message, cause); + } + + public ObjectNotUniqueException(int count) { + super("В коллекции содержится равный элемент: " + count); + } +} diff --git a/ProjectAirFighter/src/main/resources/com/projectairfighter/FormWarPlaneCollection.fxml b/ProjectAirFighter/src/main/resources/com/projectairfighter/FormWarPlaneCollection.fxml index f66e171..8d10ce9 100644 --- a/ProjectAirFighter/src/main/resources/com/projectairfighter/FormWarPlaneCollection.fxml +++ b/ProjectAirFighter/src/main/resources/com/projectairfighter/FormWarPlaneCollection.fxml @@ -34,13 +34,15 @@