diff --git a/Hydroplane/src/main/java/org/example/DrawingHydroplane.java b/Hydroplane/src/main/java/org/example/DrawingHydroplane.java index cba9d02..90fa49f 100644 --- a/Hydroplane/src/main/java/org/example/DrawingHydroplane.java +++ b/Hydroplane/src/main/java/org/example/DrawingHydroplane.java @@ -4,8 +4,7 @@ import java.awt.*; public class DrawingHydroplane extends DrawingPlane{ - public DrawingHydroplane(int speed, double weight, Color bodyColor, Color - additionalColor, boolean boat, boolean bobber, int _numWindow, int width, int height) + public DrawingHydroplane(int speed, float weight, Color bodyColor, int _numWindow, Color additionalColor, boolean boat, boolean bobber, int width, int height) { super(speed, weight, bodyColor, _numWindow, width, height); _EntityPlane = new EntityHydroplane(speed, weight, bodyColor, additionalColor, boat, bobber, _numWindow); @@ -51,6 +50,8 @@ public class DrawingHydroplane extends DrawingPlane{ g.drawLine(_startPosX + 125, _startPosY + 55, _startPosX + 125, _startPosY + 70); g.drawLine(_startPosX + 130, _startPosY + 55, _startPosX + 130, _startPosY + 70); +// windowDrawing.Draw(_startPosX, _startPosY, ((EntityHydroplane)_EntityPlane).AdditionalColor, g); + if (((EntityHydroplane)_EntityPlane).Bobber) { g.fillPolygon( new int[]{ _startPosX + 55, _startPosX + 55, _startPosX + 155, _startPosX + 175 }, diff --git a/Hydroplane/src/main/java/org/example/ExtentionDrawingPlane.java b/Hydroplane/src/main/java/org/example/ExtentionDrawingPlane.java new file mode 100644 index 0000000..dc78d52 --- /dev/null +++ b/Hydroplane/src/main/java/org/example/ExtentionDrawingPlane.java @@ -0,0 +1,78 @@ +package org.example; + +import java.awt.Color; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.Vector; + +public class ExtentionDrawingPlane { + // Создание объекта из строки + public static DrawingPlane CreateDrawingPlane(String info, String separatorForObject, int width, int height) { + String[] strs = info.split(separatorForObject); + if (strs.length == 5) + { + String[] colorValues = strs[2].split(","); + + DrawingPlane drawingPlane = new DrawingPlane(Integer.parseInt(strs[0]), (double)Integer.parseInt(strs[1]), + new Color(Integer.parseInt(colorValues[0].replaceAll("\\D", "")), + Integer.parseInt(colorValues[1].replaceAll("\\D", "")), + Integer.parseInt(colorValues[2].replaceAll("\\D", ""))), + Integer.parseInt(strs[3]), + width, height + ); + + try{ + drawingPlane.windowDrawing = (IWindowDrawing) Class.forName(strs[4]).getDeclaredConstructor().newInstance(); + drawingPlane.windowDrawing.setNumWindow(drawingPlane._EntityPlane.numWindow); + } catch (Exception e) { + return null; + } + return drawingPlane; + } + + if(strs.length == 8) { + String[] colorValues = strs[2].split(","); + String[] colorValues2 = strs[5].split(","); + DrawingHydroplane drawingHydroplane = new DrawingHydroplane( + Integer.parseInt(strs[0]), + (float) Integer.parseInt(strs[1]), + new Color( + Integer.parseInt(colorValues[0].replaceAll("\\D", "")), + Integer.parseInt(colorValues[1].replaceAll("\\D", "")), + Integer.parseInt(colorValues[2].replaceAll("\\D", "")) + ), + Integer.parseInt(strs[3]), + new Color( + Integer.parseInt(colorValues2[0].replaceAll("\\D", "")), + Integer.parseInt(colorValues2[1].replaceAll("\\D", "")), + Integer.parseInt(colorValues2[2].replaceAll("\\D", "")) + ), + strs[6].equals("true"), + strs[7].equals("true"), + width, height + ); + try { + drawingHydroplane.windowDrawing = (IWindowDrawing) Class.forName(strs[4]).getDeclaredConstructor().newInstance(); + drawingHydroplane.windowDrawing.setNumWindow(drawingHydroplane._EntityPlane.numWindow); + } catch (Exception e) { + return null; + } + return drawingHydroplane; + } + return null; + } + + // Получение данных для сохранения в файл + public static String GetDataForSave(DrawingPlane drawingPlane, String separatorForObject) { + EntityPlane plane = drawingPlane._EntityPlane; + if (plane == null) { + return null; + } + + String str = "" + plane.Speed + separatorForObject + (int)plane.Weight + separatorForObject + plane.BodyColor + separatorForObject + plane.numWindow + separatorForObject + drawingPlane.windowDrawing.getClass().getName(); + if (!(plane instanceof EntityHydroplane)) { + return str; + } + return str+separatorForObject+((EntityHydroplane)plane).AdditionalColor.toString()+separatorForObject+((EntityHydroplane)plane).Boat+separatorForObject+((EntityHydroplane)plane).Bobber; + } +} diff --git a/Hydroplane/src/main/java/org/example/FormHydroplane.java b/Hydroplane/src/main/java/org/example/FormHydroplane.java index 980bd66..81e6ffd 100644 --- a/Hydroplane/src/main/java/org/example/FormHydroplane.java +++ b/Hydroplane/src/main/java/org/example/FormHydroplane.java @@ -89,10 +89,10 @@ public class FormHydroplane{ random.nextInt(100, 300), random.nextInt(1000, 3000), new Color(random.nextInt(0, 256), random.nextInt(0, 256), random.nextInt(0, 256)), + random.nextInt(1, 4) * 10, new Color(random.nextInt(0, 256), random.nextInt(0, 256), random.nextInt(0, 256)), random.nextInt(0, 2) == 1, random.nextInt(0, 2) == 1, - random.nextInt(1, 4) * 10, pictureBoxWidth, pictureBoxHeight); _drawingPlane.SetPosition(random.nextInt(10, 100), random.nextInt(10, 100)); diff --git a/Hydroplane/src/main/java/org/example/FormPlaneCollecltion.java b/Hydroplane/src/main/java/org/example/FormPlaneCollecltion.java index 6ced848..86206a9 100644 --- a/Hydroplane/src/main/java/org/example/FormPlaneCollecltion.java +++ b/Hydroplane/src/main/java/org/example/FormPlaneCollecltion.java @@ -1,5 +1,12 @@ package org.example; +import java.io.File; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JFileChooser; +import javax.swing.filechooser.FileNameExtensionFilter; + import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; @@ -247,6 +254,120 @@ public class FormPlaneCollecltion { } ); + // Создаём панель меню + JMenuBar menuBar = new JMenuBar(); + + // Создаём пункты меню + JMenu fileMenu = new JMenu("File"); + + // Создаём пункты меню + JMenuItem openItem = new JMenuItem("Открыть"); + openItem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + + fileChooser.setDialogTitle("Выберите файл для загрузки данных"); + + // Установка фильтра для файлов с определённым расширеним (например, txt) + fileChooser.setFileFilter(new FileNameExtensionFilter("Текстовые файлы (*.txt)", "txt")); + + fileChooser.setDialogTitle("Выберите файл для загрузки данных"); + if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File selectedFile = fileChooser.getSelectedFile(); + if (_storage.LoadData(selectedFile.getAbsolutePath())) { + JOptionPane.showMessageDialog(null, "Загрузка прошла успешно", "Результат", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(null, "Не загрузилось", "Результат", JOptionPane.ERROR_MESSAGE); + } + } + ReloadObjects(); + } + }); + + JMenuItem saveItem = new JMenuItem("Сохранить"); + saveItem.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("Выберите файл для сохранения данных"); + + // Установка фильтра для файлов с определённым расширением (например, txt) + fileChooser.setFileFilter(new FileNameExtensionFilter("Текстовые файлы (*.txt)", "txt")); + + if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { + File selectedFile = fileChooser.getSelectedFile(); + if(_storage.SaveData(selectedFile.getAbsolutePath())) + JOptionPane.showMessageDialog(null, "Сохранение прошло успешно", "Результат", JOptionPane.INFORMATION_MESSAGE); + else + JOptionPane.showMessageDialog(null, "Не сохранилось", "Результат", JOptionPane.ERROR_MESSAGE); + } + } + } + ); + + JMenuItem openItemSingle = new JMenuItem("Открыть одиночный"); + openItemSingle.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fileChooser = new JFileChooser(); + + fileChooser.setDialogTitle("Выберите файл для загрузки данных"); + + //Установка фильтра для файлов с определённым расширением (например, txt) + fileChooser.setFileFilter(new FileNameExtensionFilter("Текстовые файлы (*.txt)", "txt")); + + fileChooser.setDialogTitle("Выберите файл для загрузки данных"); + if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + File selectedFile = fileChooser.getSelectedFile(); + + if (_storage.LoadDataSingle(selectedFile.getAbsolutePath())) { + JOptionPane.showMessageDialog(null, "Загрузка прошла успешно", "Результат", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(null, "Не загрузилось", "Результат", JOptionPane.ERROR_MESSAGE); + } + } + ReloadObjects(); + } + }); + + JMenuItem saveItemSingle = new JMenuItem("Сохранение одиночного"); + saveItemSingle.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e){ + if (jListStorage.getSelectedValue() == null){ + JOptionPane.showMessageDialog(null, "Не выбран гараж", "Ошибка", JOptionPane.ERROR_MESSAGE); + return; + } + + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("Выберите файл для сохранения данных"); + + // Установка фильтра для файлов с определенным расширением (например, .txt) + fileChooser.setFileFilter(new FileNameExtensionFilter("Текстовые файлы (*.txt)", "txt")); + + if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) { + File selectedFile = fileChooser.getSelectedFile(); + if (_storage.SaveDataSingle(selectedFile.getAbsolutePath(), jListStorage.getSelectedValue())) + JOptionPane.showMessageDialog(null, "Сохранение прошло успешно", "Результат", JOptionPane.INFORMATION_MESSAGE); + else + JOptionPane.showMessageDialog(null, "Не сохранилось", "Результат", JOptionPane.ERROR_MESSAGE); + } + } + } + ); + + // Добавляем пункты в меню + fileMenu.add(openItem); + fileMenu.add(saveItem); + fileMenu.add(openItemSingle); + fileMenu.add(saveItemSingle); + + // Добавляем меню в панель меню + menuBar.add(fileMenu); + w.setSize (1000, 600); w.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); w.setLayout(null); @@ -264,6 +385,8 @@ public class FormPlaneCollecltion { buttonGetRemoved.setBounds(pictureBoxWidth, 330, 160, 20); + menuBar.setBounds(pictureBoxWidth - 10, 420, 170, 20); + w.add(canv); w.add(ButtonAddPlane); w.add(ButtonRemovePlane); @@ -278,6 +401,8 @@ public class FormPlaneCollecltion { w.add(buttonGetRemoved); + w.add(menuBar); + w.setVisible(true); } } diff --git a/Hydroplane/src/main/java/org/example/FormPlaneConfig.java b/Hydroplane/src/main/java/org/example/FormPlaneConfig.java index d52c4c9..0e5e87f 100644 --- a/Hydroplane/src/main/java/org/example/FormPlaneConfig.java +++ b/Hydroplane/src/main/java/org/example/FormPlaneConfig.java @@ -320,7 +320,7 @@ public class FormPlaneConfig { _plane = new DrawingPlane((int)numericSpeed.getValue(), (int)numericWeight.getValue(), Color.WHITE, (int)numericWindowNum.getValue(), CanvasWidth,CanvasHeight); break; case "Hydroplane": - _plane = new DrawingHydroplane((int)numericSpeed.getValue(), (int)numericWeight.getValue(), Color.WHITE, Color.BLACK, checkBoxBoat.isSelected(), checkBoxBobber.isSelected(), (int)numericWindowNum.getValue(), CanvasWidth,CanvasHeight); + _plane = new DrawingHydroplane((int)numericSpeed.getValue(), (int)numericWeight.getValue(), Color.WHITE, (int)numericWindowNum.getValue(), Color.BLACK, checkBoxBoat.isSelected(), checkBoxBobber.isSelected(), CanvasWidth,CanvasHeight); break; } canvas.repaint(); diff --git a/Hydroplane/src/main/java/org/example/PlanesGenericCollection.java b/Hydroplane/src/main/java/org/example/PlanesGenericCollection.java index 2399050..a4ebb51 100644 --- a/Hydroplane/src/main/java/org/example/PlanesGenericCollection.java +++ b/Hydroplane/src/main/java/org/example/PlanesGenericCollection.java @@ -16,6 +16,11 @@ public class PlanesGenericCollection _collection; + // Получение объектов коллекции + public Iterable getPlanes(final Integer maxPlanes) { return _collection.GetPlanes(maxPlanes); } + + public void clear() { _collection.clear(); } + public PlanesGenericCollection(int picWidth, int picHeight) { int width = picWidth / _placeSizeWidth; diff --git a/Hydroplane/src/main/java/org/example/PlanesGenericStorage.java b/Hydroplane/src/main/java/org/example/PlanesGenericStorage.java index 1fe72df..bf45fc2 100644 --- a/Hydroplane/src/main/java/org/example/PlanesGenericStorage.java +++ b/Hydroplane/src/main/java/org/example/PlanesGenericStorage.java @@ -1,10 +1,174 @@ package org.example; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.stream.Collectors; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + public class PlanesGenericStorage { + // Разделитель для записи ключа и значения элемента словаря + private static String _separatorForKeyValueWR = "|"; + private static String _separatorForKeyValue = "\\|"; + + // Разделитель для записей коллекции данных в файл + private String _separatorRecordsWR = ";"; + private String _separatorRecords = "\\;"; + + // Разделитель для записи информации по объекту в файл + private static String _separatorForObjectWR = ":"; + private static String _separatorForObject = "\\:"; + + public boolean SaveDataSingle(String filename, String key) { + if(new File(filename).exists()) { + new File(filename).delete(); + } + + StringBuilder data = new StringBuilder(); + data.append(key).append("\n"); + for (DrawingPlane elem: _planeStorages.get(key).getPlanes(100)) { + if(_planeStorages.get(key) == null) + return false; + + if(_planeStorages.get(key) != null) + data.append(elem != null ? ExtentionDrawingPlane.GetDataForSave(elem, _separatorForObjectWR) + "\n" : ""); + } + + if(data.length() == 0) + return false; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { + writer.write("PlaneStorageSingle" + System.lineSeparator() + data.toString()); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + return true; + } + + public boolean LoadDataSingle(String filename) { + if(!new File(filename).exists()) { + return false; + } + + try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { + String s = reader.readLine(); + if(s == null || s.length() == 0) + return false; + + if(!s.startsWith("PlaneStorageSingle")) + return false; + + String key = reader.readLine(); + if(key == null || key.length() == 0) + return false; + + PlanesGenericCollection collections = new PlanesGenericCollection<>(_pictureWidth, _pictureHeight); + if (_planeStorages.containsKey(key)){ + collections = _planeStorages.get(key); + collections.clear(); + } + else + collections = new PlanesGenericCollection<>(_pictureWidth, _pictureHeight); + + List planesStrings = new ArrayList(); + + s = reader.readLine(); + while (s != null && s.length() != 0) { + planesStrings.add(s); + s = reader.readLine(); + } + + Collections.reverse(planesStrings); + for (String elem : planesStrings) { + DrawingPlane plane = ExtentionDrawingPlane.CreateDrawingPlane(elem, _separatorForObject, _pictureWidth, _pictureHeight); + if(plane == null || collections.Add(plane) == -1) + return false; + } + + if(_planeStorages.containsKey(key)) + _planeStorages.remove(key); + _planeStorages.put(key, collections); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + + // Сохранение информации по технике в хранилище в файл + public boolean SaveData(String filename) { + if(new File(filename).exists()) { + new File(filename).delete(); + } + + StringBuilder data = new StringBuilder(); + + for (Map.Entry> record : _planeStorages.entrySet()) { + StringBuilder records = new StringBuilder(); + for (DrawingPlane elem : record.getValue().getPlanes(100)) { + records.append(elem != null ? ExtentionDrawingPlane.GetDataForSave(elem, _separatorForObjectWR) + _separatorRecordsWR : ""); + } + data.append(record.getKey()).append(_separatorForKeyValueWR).append(records).append("\n"); + } + + if (data.length() == 0) + return false; + + try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) { + writer.write("PlaneStorage" + System.lineSeparator() + data.toString()); + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + + // Загрузка информации по технике в хранилище из файла + public boolean LoadData(String filename) { + if (!new File(filename).exists()) { + return false; + } + + try (BufferedReader reader = new BufferedReader(new FileReader(filename))) { + String s = reader.readLine(); + if (s == null || s.length() == 0) + return false; + + if (!s.startsWith("PlaneStorage")) + return false; + + _planeStorages.clear(); + + s = reader.readLine(); + while (s != null && s.length() != 0) { + String[] record = s.split(_separatorForKeyValue); + s = reader.readLine(); + if (record.length != 2) { + continue; + } + PlanesGenericCollection collection = new PlanesGenericCollection<>(_pictureWidth, _pictureHeight); + String[] set = record[1].split(_separatorRecords); + List reversedSet = Arrays.asList(set); + Collections.reverse(reversedSet); + for (String elem : reversedSet) { + DrawingPlane plane = ExtentionDrawingPlane.CreateDrawingPlane(elem, _separatorForObject, _pictureWidth, _pictureHeight); + if (plane == null || collection.Add(plane) == -1) + return false; + } + _planeStorages.put(record[0], collection); + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + return true; + } + HashMap> _planeStorages; diff --git a/Hydroplane/src/main/java/org/example/SetGeneric.java b/Hydroplane/src/main/java/org/example/SetGeneric.java index 99763fe..8ddee28 100644 --- a/Hydroplane/src/main/java/org/example/SetGeneric.java +++ b/Hydroplane/src/main/java/org/example/SetGeneric.java @@ -49,6 +49,8 @@ public class SetGeneric { return true; } + public void clear() { _places.clear(); } + public T Get(int position) { if (position < 0 || position >= _places.size()) diff --git a/Hydroplane/src/main/java/org/example/WindowDrawing.java b/Hydroplane/src/main/java/org/example/WindowDrawing.java index 5a9a3e4..d385155 100644 --- a/Hydroplane/src/main/java/org/example/WindowDrawing.java +++ b/Hydroplane/src/main/java/org/example/WindowDrawing.java @@ -30,7 +30,6 @@ public class WindowDrawing implements IWindowDrawing{ public void Draw(int _startPosX, int _startPosY, Color color, Graphics2D g){ g.setColor(color); - // обработка исключения при запуске, это не дублирующийся код! if (numWindow == null) numWindow = NumWindow.tenWindows; switch (numWindow) { diff --git a/Hydroplane/src/main/java/org/example/WindowDrawingRect.java b/Hydroplane/src/main/java/org/example/WindowDrawingRect.java index 54df155..5bfe50f 100644 --- a/Hydroplane/src/main/java/org/example/WindowDrawingRect.java +++ b/Hydroplane/src/main/java/org/example/WindowDrawingRect.java @@ -30,7 +30,6 @@ public class WindowDrawingRect implements IWindowDrawing{ public void Draw(int _startPosX, int _startPosY, Color color, Graphics2D g){ g.setColor(color); - // обработка исключения при запуске, это не дублирующийся код! if (numWindow == null) numWindow = NumWindow.tenWindows; switch (numWindow) { diff --git a/Hydroplane/src/main/java/org/example/WindowDrawingTringle.java b/Hydroplane/src/main/java/org/example/WindowDrawingTringle.java index 5ee3deb..450f6b0 100644 --- a/Hydroplane/src/main/java/org/example/WindowDrawingTringle.java +++ b/Hydroplane/src/main/java/org/example/WindowDrawingTringle.java @@ -30,7 +30,6 @@ public class WindowDrawingTringle implements IWindowDrawing{ public void Draw(int _startPosX, int _startPosY, Color color, Graphics2D g){ g.setColor(color); - // обработка исключения при запуске, это не дублирующийся код! if (numWindow == null) numWindow = NumWindow.tenWindows; switch (numWindow) {