import org.apache.logging.log4j.Logger; 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; private JComboBox comboBoxMapSelector; private JButton buttonAddArtillery; private JPanel paneArtilleries; private JFormattedTextField textBoxPosition; private JButton buttonRemoveArtillery; private JButton buttonShowStorage; private JButton buttonUp; private JButton buttonDown; private JButton buttonLeft; private JButton buttonRight; private JButton buttonShowOnMap; private JLabel mapsLabel; private JTextField textFieldMapName; private JButton buttonAddMap; private JList listBoxMaps; private JPanel mapsGroup; private JButton buttonDeleteMap; private JButton buttonShowDeleted; private Image bufferedImage; private final HashMap _mapsDict = new HashMap<>() {{ put("Простая карта", new SimpleMap()); put("Лесная карта", new ForestMap()); }}; private final MapsCollection _mapsCollection; private final Stack deletedObjects = new Stack<>(); private Logger logger; public FormMapWithSetArtilleries(Logger logger) { this(); this.logger = logger; } public FormMapWithSetArtilleries() { this.setTitle("Artillery"); this.setContentPane(paneArtilleries); this.setSize(640, 530); this.setVisible(true); try { textBoxPosition.setFormatterFactory(new DefaultFormatterFactory(new MaskFormatter("##"))); } catch (ParseException e) { e.printStackTrace(); } _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 { _mapsCollection.saveData(dialog.getSelectedFile().getAbsolutePath()); logger.info("Сохранение в файл \"" + dialog.getSelectedFile().getAbsolutePath() + "\""); JOptionPane.showMessageDialog(this, "Сохранение прошло успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.error("Ошибка сохранения в файл: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Не сохранилось: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } }); 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 { _mapsCollection.loadData(dialog.getSelectedFile().getAbsolutePath()); reloadMaps(); logger.info("Загрузка из файла \"" + dialog.getSelectedFile().getAbsolutePath() + "\""); JOptionPane.showMessageDialog(this, "Загрузка прошла успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.error("Ошибка загрузки из файла: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Не загрузилось: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } }); 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 { _mapsCollection.saveMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse(""), dialog.getSelectedFile().getAbsolutePath()); logger.info("Сохранение карты в файл \"" + dialog.getSelectedFile().getAbsolutePath() + "\""); JOptionPane.showMessageDialog(this, "Сохранение прошло успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.error("Ошибка сохранения карты в файл: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Не сохранилось: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } }); 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 { _mapsCollection.loadMap(dialog.getSelectedFile().getAbsolutePath()); reloadMaps(); logger.info("Загрузка карты из файла \"" + dialog.getSelectedFile().getAbsolutePath() + "\""); JOptionPane.showMessageDialog(this, "Загрузка прошла успешно", "Успех", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.error("Ошибка загрузки карты из файла: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Не загрузилось: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } }); fileMenu.add(loadMapMenuItem); setJMenuBar(menuBar); comboBoxMapSelector.removeAllItems(); for (var key : _mapsDict.keySet()) { comboBoxMapSelector.addItem(key); } buttonAddMap.addActionListener(e -> { if (comboBoxMapSelector.getSelectedIndex() == -1 || textFieldMapName.getText() == null || textFieldMapName.getText().isEmpty()) { logger.warn("Не удалось добавить карту: Не все данные заполнены"); JOptionPane.showMessageDialog(this, "Не все данные заполнены", "Ошибка", JOptionPane.ERROR_MESSAGE); return; } if (!_mapsDict.containsKey((String)comboBoxMapSelector.getSelectedItem())) { logger.warn("Не удалось добавить карту: Нет такой карты"); JOptionPane.showMessageDialog(this, "Нет такой карты", "Ошибка", JOptionPane.ERROR_MESSAGE); return; } _mapsCollection.addMap(textFieldMapName.getText(), _mapsDict.get((String)comboBoxMapSelector.getSelectedItem())); reloadMaps(); logger.info("Добавлена карта \"" + textFieldMapName.getText() + "\" типа " + _mapsDict.get((String)comboBoxMapSelector.getSelectedItem())); }); buttonDeleteMap.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() == -1) { return; } if (JOptionPane.showConfirmDialog(this, "Удалить карту " + listBoxMaps.getSelectedValue() + "?", "Удаление", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { _mapsCollection.deleteMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")); logger.info("Удалена карта \"" + listBoxMaps.getSelectedValue() + "\""); reloadMaps(); } }); listBoxMaps.addListSelectionListener(e -> { if (listBoxMaps.getSelectedValue() != null) { bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).showSet(); repaint(); logger.info("Переход на карту \"" + listBoxMaps.getSelectedValue() + "\""); } }); buttonAddArtillery.addActionListener(e -> { FormArtilleryConfig form = new FormArtilleryConfig(); form.addListener(artillery -> { if (listBoxMaps.getSelectedIndex() == -1) { return; } if (artillery != null) { try { DrawingObjectArtillery objectArtillery = new DrawingObjectArtillery(artillery); if (_mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).addArtillery(objectArtillery) != -1) { JOptionPane.showMessageDialog(this, "Объект добавлен", "Успех", JOptionPane.INFORMATION_MESSAGE); bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).showSet(); repaint(); logger.info("Добавлен новый объект"); } else { logger.warn("Не удалось добавить объект"); JOptionPane.showMessageDialog(this, "Не удалось добавить объект", "Провал", JOptionPane.INFORMATION_MESSAGE); } } catch (StorageOverflowException ex) { logger.warn("Ошибка переполнения хранилища: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Ошибка переполнения хранилища: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.fatal("Неизвестная ошибка: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Неизвестная ошибка: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } } }); form.setVisible(true); }); buttonRemoveArtillery.addActionListener(e -> { String text = textBoxPosition.getText(); if (text == null || text.isEmpty()) { return; } if (JOptionPane.showConfirmDialog(this, "Удалить объект?", "Удаление", JOptionPane.YES_NO_OPTION) == JOptionPane.NO_OPTION) { return; } int position = Integer.parseInt(text); try { IDrawingObject deleted = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).removeArtilleryAt(position); if (deleted != null) { deletedObjects.push(deleted); JOptionPane.showMessageDialog(this, "Объект удалён", "Успех", JOptionPane.INFORMATION_MESSAGE); bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).showSet(); repaint(); logger.info("Удалён объект"); } else { logger.warn("Не удалось удалить объект по позиции " + position + ". Объект равен null"); JOptionPane.showMessageDialog(this, "Не удалось удалить объект", "Провал", JOptionPane.INFORMATION_MESSAGE); } } catch (ArtilleryNotFoundException ex) { logger.warn("Ошибка удаления: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Не удалось найти артиллерию по позиции: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } catch (Exception ex) { logger.error("Неизвестная ошибка: " + ex.getMessage()); JOptionPane.showMessageDialog(this, "Неизвестная ошибка: " + ex.getMessage(), "Провал", JOptionPane.INFORMATION_MESSAGE); } }); buttonShowStorage.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() == -1) { return; } bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).showSet(); repaint(); }); buttonShowOnMap.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() == -1) { return; } bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).showOnMap(); repaint(); }); buttonShowDeleted.addActionListener(e -> { if (!deletedObjects.empty()) { DrawingObjectArtillery deleted = (DrawingObjectArtillery) deletedObjects.pop(); FormArtillery dialog = new FormArtillery(deleted.getArtillery()); dialog.setSize(800, 500); dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); } else { JOptionPane.showMessageDialog(this, "Стек удалённых объектов пуст", "Провал", JOptionPane.INFORMATION_MESSAGE); } }); buttonLeft.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() != -1) { bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).moveObject(Direction.Left); repaint(); } }); buttonRight.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() != -1) { bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).moveObject(Direction.Right); repaint(); } }); buttonUp.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() != -1) { bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).moveObject(Direction.Up); repaint(); } }); buttonDown.addActionListener(e -> { if (listBoxMaps.getSelectedIndex() != -1) { bufferedImage = _mapsCollection.getMap(Optional.ofNullable(listBoxMaps.getSelectedValue()).orElse("")).moveObject(Direction.Down); repaint(); } }); } private void reloadMaps() { int index = listBoxMaps.getSelectedIndex(); listBoxMaps.setListData(_mapsCollection.getKeys().toArray(new String[0])); int size = listBoxMaps.getModel().getSize(); if (size > 0 && (index == -1 || index >= size)) { listBoxMaps.setSelectedIndex(0); } else if (index > -1 && index < size) { listBoxMaps.setSelectedIndex(index); } } @Override public void paint(Graphics g) { super.paint(g); if (bufferedImage != null) { pictureBox.paintComponents(bufferedImage.getGraphics()); pictureBox.getGraphics().drawImage(bufferedImage, 0, 0, null); } } }