diff --git a/ArtillerySerde.java b/ArtillerySerde.java new file mode 100644 index 0000000..d633e3f --- /dev/null +++ b/ArtillerySerde.java @@ -0,0 +1,69 @@ +import java.awt.*; + +public class ArtillerySerde { // Artillery Serialization/Deserialization + private static final char _separatorForObject = ':'; + + public static DrawingArtillery deserialize(String info) { + String[] strings = info.split(Character.toString(_separatorForObject)); + + int speed = Integer.parseInt(strings[0]); + float weight = Float.parseFloat(strings[1]); + Color bodyColor = new Color(Integer.parseInt(strings[2])); + IDrawingRollers rollers = switch (strings[3]) { + case "DrawingRollers" -> new DrawingRollers(Integer.parseInt(strings[4]), bodyColor); + case "DrawingCrossRollers" -> new DrawingCrossRollers(Integer.parseInt(strings[4]), bodyColor); + case "DrawingSquaredRollers" -> new DrawingSquaredRollers(Integer.parseInt(strings[4]), bodyColor); + default -> null; + }; + + if (strings.length == 5) { + EntityArtillery entity = new EntityArtillery(speed, weight, bodyColor); + + return new DrawingArtillery(entity, rollers); + } + + if (strings.length == 8) { + Color dopColor = new Color(Integer.parseInt(strings[5])); + boolean weapon = Boolean.parseBoolean(strings[6]); + boolean salvoBattery = Boolean.parseBoolean(strings[7]); + + EntityAdvancedArtillery entity = new EntityAdvancedArtillery(speed, weight, bodyColor, dopColor, weapon, salvoBattery); + + return new DrawingAdvancedArtillery(entity, rollers); + } + + return null; + } + + public static String serialize(DrawingArtillery drawingArtillery) { + EntityArtillery artillery = drawingArtillery.getArtillery(); + + String result = String.format( + "%d%c%s%c%d%c%s%c%d", + artillery.getSpeed(), + _separatorForObject, + artillery.getWeight(), + _separatorForObject, + artillery.getBodyColor().getRGB(), + _separatorForObject, + drawingArtillery.getRollers().getClass().getSimpleName(), + _separatorForObject, + drawingArtillery.getRollers().getRollersCount() + ); + + if (!(artillery instanceof EntityAdvancedArtillery advanced)) { + return result; + } + + return String.format( + "%s%c%d%c%b%c%b", + result, + _separatorForObject, + advanced.getDopColor().getRGB(), + _separatorForObject, + advanced.getWeapon(), + _separatorForObject, + advanced.getSalvoBattery() + ); + } +} diff --git a/DrawingCrossRollers.java b/DrawingCrossRollers.java index 70e6e8c..ae392ee 100644 --- a/DrawingCrossRollers.java +++ b/DrawingCrossRollers.java @@ -19,6 +19,10 @@ public class DrawingCrossRollers implements IDrawingRollers { } } + public int getRollersCount() { + return rollersCount.getValue(); + } + public void draw(Graphics2D g, int x, int y, int artilleryWidth, int artilleryHeight) { g.setColor(color != null ? color : Color.BLACK); g.fillOval(x + artilleryWidth / 20, y + artilleryHeight * 7 / 15, artilleryWidth * 4 / 20, artilleryHeight * 10 / 32); diff --git a/DrawingObjectArtillery.java b/DrawingObjectArtillery.java index 5292c9c..9036048 100644 --- a/DrawingObjectArtillery.java +++ b/DrawingObjectArtillery.java @@ -38,4 +38,16 @@ public class DrawingObjectArtillery implements IDrawingObject { public void drawingObject(Graphics2D g) { _artillery.drawTransport(g); } + + public String getInfo() { + if (_artillery == null) { + return null; + } + + return ArtillerySerde.serialize(_artillery); + } + + public static IDrawingObject create(String data) { + return new DrawingObjectArtillery(ArtillerySerde.deserialize(data)); + } } diff --git a/DrawingRollers.java b/DrawingRollers.java index 7c55044..e23b53f 100644 --- a/DrawingRollers.java +++ b/DrawingRollers.java @@ -19,6 +19,10 @@ public class DrawingRollers implements IDrawingRollers { } } + public int getRollersCount() { + return rollersCount.getValue(); + } + public void draw(Graphics2D g, int x, int y, int artilleryWidth, int artilleryHeight) { g.setColor(color != null ? color : Color.BLACK); g.fillOval(x + artilleryWidth / 20, y + artilleryHeight * 7 / 15, artilleryWidth * 4 / 20, artilleryHeight * 10 / 32); diff --git a/DrawingSquaredRollers.java b/DrawingSquaredRollers.java index c15aebc..8e197cc 100644 --- a/DrawingSquaredRollers.java +++ b/DrawingSquaredRollers.java @@ -19,6 +19,10 @@ public class DrawingSquaredRollers implements IDrawingRollers { } } + public int getRollersCount() { + return rollersCount.getValue(); + } + public void draw(Graphics2D g, int x, int y, int artilleryWidth, int artilleryHeight) { g.setColor(color != null ? color : Color.BLACK); g.fillOval(x + artilleryWidth / 20, y + artilleryHeight * 7 / 15, artilleryWidth * 4 / 20, artilleryHeight * 10 / 32); diff --git a/FormMapWithSetArtilleries.java b/FormMapWithSetArtilleries.java index 4c8e966..16f6b4c 100644 --- a/FormMapWithSetArtilleries.java +++ b/FormMapWithSetArtilleries.java @@ -1,13 +1,16 @@ import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.text.DefaultFormatterFactory; import javax.swing.text.MaskFormatter; import java.awt.*; +import java.io.IOException; import java.text.ParseException; import java.util.HashMap; import java.util.Optional; import java.util.Stack; public class FormMapWithSetArtilleries extends JFrame { + private JMenuBar menuBar; private JPanel pictureBox; private JPanel toolsGroup; private JLabel toolsLabel; @@ -52,6 +55,87 @@ public class FormMapWithSetArtilleries extends JFrame { _mapsCollection = new MapsCollection(pictureBox.getWidth(), pictureBox.getHeight()); + menuBar = new JMenuBar(); + + JMenu fileMenu = new JMenu("Файл"); + menuBar.add(fileMenu); + + JMenuItem saveMenuItem = new JMenuItem("Сохранить"); + saveMenuItem.addActionListener(e -> { + JFileChooser dialog = new JFileChooser(); + dialog.setFileFilter(new FileNameExtensionFilter("TXT file", "txt")); + dialog.showSaveDialog(this); + + try { + if (_mapsCollection.saveData(dialog.getSelectedFile().getAbsolutePath())) { + JOptionPane.showMessageDialog(this, "Сохранение прошло успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(this, "Не сохранилось", "Провал", JOptionPane.INFORMATION_MESSAGE); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + }); + fileMenu.add(saveMenuItem); + + JMenuItem loadMenuItem = new JMenuItem("Загрузить"); + loadMenuItem.addActionListener(e -> { + JFileChooser dialog = new JFileChooser(); + dialog.setFileFilter(new FileNameExtensionFilter("TXT file", "txt")); + dialog.showOpenDialog(this); + + try { + if (_mapsCollection.loadData(dialog.getSelectedFile().getAbsolutePath())) { + reloadMaps(); + JOptionPane.showMessageDialog(this, "Загрузка прошла успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(this, "Не загрузилось", "Провал", JOptionPane.INFORMATION_MESSAGE); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + }); + fileMenu.add(loadMenuItem); + + JMenuItem saveMapMenuItem = new JMenuItem("Сохранить карту"); + saveMapMenuItem.addActionListener(e -> { + JFileChooser dialog = new JFileChooser(); + dialog.setFileFilter(new FileNameExtensionFilter("TXT file", "txt")); + dialog.showSaveDialog(this); + + try { + if (_mapsCollection.saveMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse(""), dialog.getSelectedFile().getAbsolutePath())) { + JOptionPane.showMessageDialog(this, "Сохранение прошло успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(this, "Не сохранилось", "Провал", JOptionPane.INFORMATION_MESSAGE); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + }); + fileMenu.add(saveMapMenuItem); + + JMenuItem loadMapMenuItem = new JMenuItem("Загрузить карту"); + loadMapMenuItem.addActionListener(e -> { + JFileChooser dialog = new JFileChooser(); + dialog.setFileFilter(new FileNameExtensionFilter("TXT file", "txt")); + dialog.showOpenDialog(this); + + try { + if (_mapsCollection.loadMap(dialog.getSelectedFile().getAbsolutePath())) { + reloadMaps(); + JOptionPane.showMessageDialog(this, "Загрузка прошла успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(this, "Не загрузилось", "Провал", JOptionPane.INFORMATION_MESSAGE); + } + } catch (IOException ex) { + ex.printStackTrace(); + } + }); + fileMenu.add(loadMapMenuItem); + + setJMenuBar(menuBar); + comboBoxMapSelector.removeAllItems(); for (var key : _mapsDict.keySet()) { comboBoxMapSelector.addItem(key); diff --git a/IDrawingObject.java b/IDrawingObject.java index f1effa3..67ea616 100644 --- a/IDrawingObject.java +++ b/IDrawingObject.java @@ -6,4 +6,5 @@ public interface IDrawingObject { void moveObject(Direction direction); void drawingObject(Graphics2D g); float[] getCurrentPosition(); + String getInfo(); } diff --git a/IDrawingRollers.java b/IDrawingRollers.java index 166e40c..f63eb13 100644 --- a/IDrawingRollers.java +++ b/IDrawingRollers.java @@ -4,4 +4,5 @@ public interface IDrawingRollers { void setRollersCount(int num); void setColor(Color color); void draw(Graphics2D g, int x, int y, int artilleryWidth, int artilleryHeight); + int getRollersCount(); } diff --git a/MapWithSetArtilleriesGeneric.java b/MapWithSetArtilleriesGeneric.java index 3c2774f..85c4474 100644 --- a/MapWithSetArtilleriesGeneric.java +++ b/MapWithSetArtilleriesGeneric.java @@ -19,6 +19,10 @@ public class MapWithSetArtilleriesGeneric= 0; i--) { + _setArtilleries.insert((T) DrawingObjectArtillery.create(records[i])); + } + } } diff --git a/MapsCollection.java b/MapsCollection.java index 5b9f24c..016f466 100644 --- a/MapsCollection.java +++ b/MapsCollection.java @@ -1,3 +1,4 @@ +import java.io.*; import java.util.HashMap; import java.util.Set; @@ -7,6 +8,9 @@ public class MapsCollection { private final int _pictureWidth; private final int _pictureHeight; + private final char separatorDict = '|'; + private final char separatorData = ';'; + public Set getKeys() { return _mapsStorage.keySet(); } @@ -38,4 +42,127 @@ public class MapsCollection { } return null; } + + @SuppressWarnings("ResultOfMethodCallIgnored") + public boolean saveData(String filename) throws IOException { + File file = new File(filename); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + + try (PrintWriter writer = new PrintWriter(file)) { + writer.println("MapsCollection"); + + for (var storage : _mapsStorage.entrySet()) { + writer.println(String.format("%s%c%s", storage.getKey(), separatorDict, storage.getValue().getData(separatorDict, separatorData))); + } + } + + return true; + } + + public boolean loadData(String filename) throws IOException { + File file = new File(filename); + + if (!file.exists()) { + return false; + } + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String currentLine = reader.readLine(); + + if (currentLine == null || !currentLine.contains("MapsCollection")) { + return false; + } + + _mapsStorage.clear(); + while ((currentLine = reader.readLine()) != null) { + var elements = currentLine.split(String.format("\\%c", separatorDict)); + + AbstractMap map = switch (elements[1]) { + case "SimpleMap" -> new SimpleMap(); + case "ForestMap" -> new ForestMap(); + default -> null; + }; + + _mapsStorage.put(elements[0], new MapWithSetArtilleriesGeneric<>(_pictureWidth, _pictureHeight, map)); + _mapsStorage.get(elements[0]).loadData(elements[2].split(separatorData + "\n?")); + } + } + + return true; + } + + @SuppressWarnings("ResultOfMethodCallIgnored") + public boolean saveMap(String mapName, String filename) throws IOException { + File file = new File(filename); + + if (file.exists()) { + file.delete(); + } + + file.createNewFile(); + + MapWithSetArtilleriesGeneric map = _mapsStorage.getOrDefault(mapName, null); + + if (map == null) { + return false; + } + + try (PrintWriter writer = new PrintWriter(file)) { + writer.println("Map"); + writer.println(mapName); + writer.println(map.getMap().getClass().getSimpleName()); + + for (var artillery : map._setArtilleries.getArtilleries()) { + writer.println(artillery.getInfo()); + } + } + + return true; + } + + public boolean loadMap(String filename) throws IOException { + File file = new File(filename); + + if (!file.exists()) { + return false; + } + + try (BufferedReader reader = new BufferedReader(new FileReader(file))) { + String currentLine = reader.readLine(); + + if (currentLine == null || !currentLine.contains("Map")) { + return false; + } + + String mapName = reader.readLine(); + + MapWithSetArtilleriesGeneric map; + if (_mapsStorage.containsKey(mapName)) { + map = _mapsStorage.get(mapName); + if (!map.getMap().getClass().getSimpleName().equals(reader.readLine())) { + return false; + } + map._setArtilleries.clear(); + } else { + map = switch (reader.readLine()) { + case "SimpleMap" -> new MapWithSetArtilleriesGeneric<>(_pictureWidth, _pictureHeight, new SimpleMap()); + case "ForestMap" -> new MapWithSetArtilleriesGeneric<>(_pictureWidth, _pictureHeight, new ForestMap()); + default -> null; + }; + } + + while ((currentLine = reader.readLine()) != null) { + map._setArtilleries.insert(DrawingObjectArtillery.create(currentLine)); + } + + _mapsStorage.put(mapName, map); + } + + return true; + } } diff --git a/RollersCount.java b/RollersCount.java index 7b9cdbe..38dbc92 100644 --- a/RollersCount.java +++ b/RollersCount.java @@ -1,5 +1,18 @@ public enum RollersCount { Four, Five, - Six + Six; + + public int getValue() { + return switch (this) { + case Four -> 4; + case Five -> 5; + case Six -> 6; + }; + } + + @Override + public String toString() { + return Integer.toString(getValue()); + } } diff --git a/SetArtilleriesGeneric.java b/SetArtilleriesGeneric.java index 7b8c6d0..0293a7b 100644 --- a/SetArtilleriesGeneric.java +++ b/SetArtilleriesGeneric.java @@ -53,4 +53,8 @@ public class SetArtilleriesGeneric { public Iterable getArtilleries() { return () -> _places.stream().filter(Objects::nonNull).iterator(); } + + public void clear() { + _places.clear(); + } }