diff --git a/src/main/java/robots/controller/GameController.java b/src/main/java/robots/game/GameController.java similarity index 92% rename from src/main/java/robots/controller/GameController.java rename to src/main/java/robots/game/GameController.java index c1cbd8a..0057039 100644 --- a/src/main/java/robots/controller/GameController.java +++ b/src/main/java/robots/game/GameController.java @@ -1,7 +1,4 @@ -package robots.controller; - -import robots.gui.GameVisualizer; -import robots.models.RobotModel; +package robots.game; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; diff --git a/src/main/java/robots/gui/GameVisualizer.java b/src/main/java/robots/game/GameVisualizer.java similarity index 86% rename from src/main/java/robots/gui/GameVisualizer.java rename to src/main/java/robots/game/GameVisualizer.java index 19a7355..c1cf067 100644 --- a/src/main/java/robots/gui/GameVisualizer.java +++ b/src/main/java/robots/game/GameVisualizer.java @@ -1,28 +1,24 @@ -package robots.gui; - -import robots.models.RobotModel; +package robots.game; import javax.swing.*; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; /** * Класс GameVisualizer представляет собой панель для визуализации состояния робота и его цели. */ -public class GameVisualizer extends JPanel implements PropertyChangeListener { - private RobotModel robotModel; +public class GameVisualizer extends JComponent implements PropertyChangeListener { + private final RobotModel robotModel; /** * Создает новый объект GameVisualizer. * Устанавливает параметры двойной буферизации для улучшения производительности отрисовки и * подписывается на события изменения состояния робота через объект PropertyChangeSupport. - * - * @param propertyChangeSupport объект PropertyChangeSupport для подписки на события изменения состояния робота */ - public GameVisualizer(PropertyChangeSupport propertyChangeSupport) { - propertyChangeSupport.addPropertyChangeListener(this); + public GameVisualizer(RobotModel robotModel) { + this.robotModel = robotModel; + robotModel.addListener(this); setDoubleBuffered(true); } @@ -108,8 +104,7 @@ private void onRedrawEvent() { @Override public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals("robot_update")) { - this.robotModel = (RobotModel) evt.getNewValue(); + if (evt.getPropertyName().equals("model_update")) { onRedrawEvent(); } } diff --git a/src/main/java/robots/game/MVCController.java b/src/main/java/robots/game/MVCController.java new file mode 100644 index 0000000..fb5720c --- /dev/null +++ b/src/main/java/robots/game/MVCController.java @@ -0,0 +1,16 @@ +package robots.game; + +import javax.swing.*; + +/** + * Интерфейс MVCController определяет методы, которые должен реализовать контроллер + * для управления графическим интерфейсом пользователя в рамках архитектуры MVC. + */ +public interface MVCController { + /** + * Возвращает компонент, ответственный за рисование или отображение данных. + * + * @return компонент, реализующий интерфейс {@link JComponent}, который используется для рисования или отображения данных. + */ + JComponent getPainter(); +} diff --git a/src/main/java/robots/game/MVCControllerWithWindows.java b/src/main/java/robots/game/MVCControllerWithWindows.java new file mode 100644 index 0000000..7f522d4 --- /dev/null +++ b/src/main/java/robots/game/MVCControllerWithWindows.java @@ -0,0 +1,15 @@ +package robots.game; + +import javax.swing.*; + +/** + * Интерфейс для модулей с дополнительными окнами + */ +public interface MVCControllerWithWindows extends MVCController { + /** + * Возвращает массив внутренних окон, которые управляются контроллером. + * + * @return массив объектов {@link JInternalFrame}, представляющих внутренние окна, управляемые контроллером. + */ + JInternalFrame[] getWindows(); +} diff --git a/src/main/java/robots/game/ModuleController.java b/src/main/java/robots/game/ModuleController.java new file mode 100644 index 0000000..1ecb079 --- /dev/null +++ b/src/main/java/robots/game/ModuleController.java @@ -0,0 +1,44 @@ +package robots.game; + +import javax.swing.*; + +/** + * Класс для инкапсулирования логики работы модуля с игрой. + */ +public class ModuleController implements MVCControllerWithWindows { + private final GameVisualizer gameVisualizer; + private final JInternalFrame[] jInternalFrames; + + /** + * Конструктор модуля с какой-либо базовой логикой робота + */ + public ModuleController() { + RobotModel robotModel = new RobotModel(); + gameVisualizer = new GameVisualizer(robotModel); + GameController gameController = new GameController(robotModel, gameVisualizer); + + WindowWithCoordinates wwc = new WindowWithCoordinates(); + robotModel.addListener(wwc); + jInternalFrames = new JInternalFrame[]{wwc}; + + gameController.start(); + } + + /** + * Предоставление отрисовщика робота + * @return графический элемент, который будет отрисовывать работу робота + */ + @Override + public JComponent getPainter() { + return gameVisualizer; + } + + /** + * Возвращает список зависимых окон + * @return массив с зависимыми окнами + */ + @Override + public JInternalFrame[] getWindows() { + return jInternalFrames; + } +} diff --git a/src/main/java/robots/models/RobotModel.java b/src/main/java/robots/game/RobotModel.java similarity index 91% rename from src/main/java/robots/models/RobotModel.java rename to src/main/java/robots/game/RobotModel.java index 7de5070..bfcb0a5 100644 --- a/src/main/java/robots/models/RobotModel.java +++ b/src/main/java/robots/game/RobotModel.java @@ -1,14 +1,13 @@ -package robots.models; +package robots.game; import java.awt.*; +import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; /** * Класс RobotModel представляет модель робота в игре. */ public class RobotModel { - private final PropertyChangeSupport propertyChangeSupport; - // Позиция робота private double posX = 100; private double posY = 100; @@ -24,13 +23,13 @@ public class RobotModel { private int targetX = 150; private int targetY = 100; + private final PropertyChangeSupport pcs; + /** * Конструктор класса Robot. - * - * @param propertyChangeSupport объект PropertyChangeSupport для поддержки событий изменения свойств */ - public RobotModel(PropertyChangeSupport propertyChangeSupport) { - this.propertyChangeSupport = propertyChangeSupport; + public RobotModel() { + pcs = new PropertyChangeSupport(this); } /** @@ -128,11 +127,19 @@ private double normalizeRadians(double angle) { return angle; } + /** + * Добавляет слушателя + * @param pcl слушатель + */ + public void addListener(PropertyChangeListener pcl) { + pcs.addPropertyChangeListener(pcl); + } + /** * Уведомляет слушателей об изменении состояния модели робота. */ private void notifyListeners() { - propertyChangeSupport.firePropertyChange("robot_update", null, this); + pcs.firePropertyChange("model_update", null, this); } public double getPosX() { diff --git a/src/main/java/robots/gui/WindowWithCoordinates.java b/src/main/java/robots/game/WindowWithCoordinates.java similarity index 75% rename from src/main/java/robots/gui/WindowWithCoordinates.java rename to src/main/java/robots/game/WindowWithCoordinates.java index 57f0b59..f6b0285 100644 --- a/src/main/java/robots/gui/WindowWithCoordinates.java +++ b/src/main/java/robots/game/WindowWithCoordinates.java @@ -1,15 +1,12 @@ -package robots.gui; +package robots.game; import robots.locale.LanguageManager; -import robots.log.Logger; -import robots.models.RobotModel; import robots.serialize.Stateful; import javax.swing.*; import java.awt.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; import java.text.DecimalFormat; /** @@ -23,13 +20,12 @@ public class WindowWithCoordinates extends JInternalFrame implements Stateful, P /** * Конструктор класса WindowWithCoordinates. */ - public WindowWithCoordinates(PropertyChangeSupport propertyChangeSupport) { + public WindowWithCoordinates() { super(LanguageManager.getStr("WindowWithCoordinates.title"), true, true, true, true); - propertyChangeSupport.addPropertyChangeListener(this); xCord = new JLabel("x"); yCord = new JLabel("y"); @@ -43,14 +39,10 @@ public WindowWithCoordinates(PropertyChangeSupport propertyChangeSupport) { pack(); setLocation(770, 10); - - Logger.debug("WindowWithCoordinates.title"); } /** * Обновляет отображаемые координаты на основе состояния робота. - * - * @param robotModel модель робота */ private void updateCoords(RobotModel robotModel) { xCord.setText("x: " + df.format(robotModel.getPosX())); @@ -59,9 +51,8 @@ private void updateCoords(RobotModel robotModel) { @Override public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName().equals("robot_update")) { - RobotModel robotModel = (RobotModel) evt.getNewValue(); - updateCoords(robotModel); + if (evt.getPropertyName().equals("model_update")) { + updateCoords((RobotModel) evt.getNewValue()); } } diff --git a/src/main/java/robots/gui/GameWindow.java b/src/main/java/robots/gui/GameWindow.java index bb313b4..facf8a0 100644 --- a/src/main/java/robots/gui/GameWindow.java +++ b/src/main/java/robots/gui/GameWindow.java @@ -1,14 +1,11 @@ package robots.gui; -import robots.controller.GameController; import robots.locale.LanguageManager; import robots.log.Logger; -import robots.models.RobotModel; import robots.serialize.Stateful; import javax.swing.*; import java.awt.*; -import java.beans.PropertyChangeSupport; /** * Класс GameWindow представляет собой внутреннее окно Swing, содержащее игровое поле. @@ -16,26 +13,18 @@ public class GameWindow extends JInternalFrame implements Stateful { /** * Создает новое игровое окно с заданным объектом PropertyChangeSupport. - * - * @param propertyChangeSupport объект PropertyChangeSupport для обмена данными с контроллером игры */ - public GameWindow(PropertyChangeSupport propertyChangeSupport) { + public GameWindow(JComponent jComponent) { super(LanguageManager.getStr("GameWindow.title"), true, true, true, true); - RobotModel robotModel = new RobotModel(propertyChangeSupport); - GameVisualizer gameVisualizer = new GameVisualizer(propertyChangeSupport); - GameController gameController = new GameController(robotModel, gameVisualizer); - JPanel panel = new JPanel(new BorderLayout()); - panel.add(gameVisualizer, BorderLayout.CENTER); + panel.add(jComponent, BorderLayout.CENTER); getContentPane().add(panel); - gameController.start(); - setBounds(230, 10, 530, 530); diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index d958828..98886a2 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -1,5 +1,8 @@ package robots.gui; +import robots.game.MVCControllerWithWindows; +import robots.game.MVCController; +import robots.game.ModuleController; import robots.locale.LanguageManager; import robots.log.Logger; import robots.serialize.Stateful; @@ -9,7 +12,7 @@ import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.beans.PropertyChangeSupport; +import java.beans.PropertyVetoException; import java.util.ArrayList; import java.util.List; @@ -19,6 +22,8 @@ public class MainApplicationFrame extends JFrame implements Stateful { private final JDesktopPane desktopPane = new JDesktopPane(); private final WindowStateManager windowStateManager = new WindowStateManager(); + private GameWindow gameWindow; + private MVCController mvcController; /** * Конструктор для создания главного окна @@ -37,15 +42,21 @@ public void windowClosing(WindowEvent e) { } }); - PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); - addWindow(new GameWindow(propertyChangeSupport)); - addWindow(new WindowWithCoordinates(propertyChangeSupport)); addWindow(new LogWindow()); + + mvcController = new ModuleController(); + + gameWindow = new GameWindow(mvcController.getPainter()); + addWindow(gameWindow); + + if (mvcController instanceof MVCControllerWithWindows mvcController) + addDependedWindows(mvcController); + restoreStatesWindows(); } /** - * Устанавливает визуальные отношения окна (размер, название и станадартную тему) + * Устанавливает визуальные отношения окна (размер, название и стандартную тему) */ private void setVisualMainFrame() { int inset = 50; @@ -133,6 +144,64 @@ private List getListStateful() { return statefuls; } + /** + * Метод для перезапуска игры на основе загруженного класса, реализующего интерфейс {@link MVCController} + * @param newMvcController класс, реализующий интерфейс {@link MVCController} + */ + public void restartGame(MVCController newMvcController) { + saveStatesWindows(); + disposeGameWindowAndDependentInternal(); + + mvcController = newMvcController; + + gameWindow = new GameWindow(mvcController.getPainter()); + addWindow(gameWindow); + + if (newMvcController instanceof MVCControllerWithWindows mvcControllerWithWindows) + addDependedWindows(mvcControllerWithWindows); + + restoreStatesWindows(); + } + + /** + * Метод для закрытия окон {@link GameWindow} и зависимых окон от текущего {@link MVCController}, + * если он реализует интерфейс {@link MVCControllerWithWindows} + */ + private void disposeGameWindowAndDependentInternal() { + if (gameWindow == null) return; + + if (mvcController instanceof MVCControllerWithWindows mvcControllerWithWindows) { + for (JInternalFrame frame : mvcControllerWithWindows.getWindows()) { + try { + frame.setClosed(true); + } catch (PropertyVetoException e) { + System.err.println("Ошибка при закрытии зависимого внутреннего окна: " + e.getMessage()); + e.printStackTrace(); + } + desktopPane.remove(frame); + } + } + + try { + gameWindow.setClosed(true); + } catch (PropertyVetoException e) { + System.err.println("Ошибка при закрытии окна GameWindow: " + e.getMessage()); + e.printStackTrace(); + } + desktopPane.remove(gameWindow); + desktopPane.repaint(); + } + + /** + * Добавление зависимых окон от {@link MVCController}, если он реализует интерфейс {@link MVCControllerWithWindows} + * @param mvcController класс реализующий интерфейс {@link MVCControllerWithWindows} + */ + private void addDependedWindows(MVCControllerWithWindows mvcController) { + JInternalFrame[] jInternalFrames = mvcController.getWindows(); + for (JInternalFrame jInternalFrame : jInternalFrames) + addWindow(jInternalFrame); + } + @Override public void dispose() { saveStatesWindows(); diff --git a/src/main/java/robots/gui/ModuleLoaderDialog.java b/src/main/java/robots/gui/ModuleLoaderDialog.java new file mode 100644 index 0000000..6495c5e --- /dev/null +++ b/src/main/java/robots/gui/ModuleLoaderDialog.java @@ -0,0 +1,124 @@ +package robots.gui; + +import robots.locale.LanguageManager; + +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.*; +import java.io.File; + +/** + * Диалог для загрузки модуля из JAR файла. + * Предоставляет возможность выбрать JAR файл и указать путь к классу модуля внутри JAR. + */ +public class ModuleLoaderDialog extends JDialog { + private final JTextField jarFilePathField; + private final JTextField moduleClassPathField; + private final JTextArea statusTextArea; + private File selectedJarFile; + + /** + * Конструктор для создания диалога загрузчика модуля. + * + * @param parent родительский фрейм для модального диалога. + */ + public ModuleLoaderDialog(Frame parent) { + super(parent, LanguageManager.getStr("PaneMenuBar.optionMenu.dialogLoader"), true); + setSize(500, 300); + setLocationRelativeTo(parent); + setLayout(new BorderLayout()); + + JPanel inputPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + + jarFilePathField = new JTextField(30); + jarFilePathField.setEditable(false); + moduleClassPathField = new JTextField(30); + JButton browseButton = new JButton(LanguageManager.getStr("PaneMenuBar.optionMenu.browse")); + JButton loadButton = new JButton(LanguageManager.getStr("PaneMenuBar.optionMenu.load")); + statusTextArea = new JTextArea(); + statusTextArea.setEditable(false); + + gbc.insets = new Insets(10, 10, 10, 10); + + gbc.gridx = 0; + gbc.gridy = 0; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + inputPanel.add(new JLabel(LanguageManager.getStr("moduleLoaderDialog.fileChooser.title")), gbc); + + gbc.gridx = 1; + gbc.gridy = 0; + gbc.gridwidth = 2; + gbc.fill = GridBagConstraints.HORIZONTAL; + inputPanel.add(jarFilePathField, gbc); + + gbc.gridx = 3; + gbc.gridy = 0; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + inputPanel.add(browseButton, gbc); + + gbc.gridx = 0; + gbc.gridy = 1; + gbc.gridwidth = 1; + gbc.fill = GridBagConstraints.NONE; + inputPanel.add(new JLabel(LanguageManager.getStr("moduleLoaderDialog.modulePath.title")), gbc); + + gbc.gridx = 1; + gbc.gridy = 1; + gbc.gridwidth = 3; + gbc.fill = GridBagConstraints.HORIZONTAL; + inputPanel.add(moduleClassPathField, gbc); + + add(inputPanel, BorderLayout.NORTH); + + JScrollPane scrollPane = new JScrollPane(statusTextArea); + add(scrollPane, BorderLayout.CENTER); + + add(loadButton, BorderLayout.SOUTH); + + browseButton.addActionListener(e -> { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + fileChooser.setFileFilter(new FileNameExtensionFilter("Jar", "jar")); + int result = fileChooser.showOpenDialog(ModuleLoaderDialog.this); + if (result == JFileChooser.APPROVE_OPTION) { + selectedJarFile = fileChooser.getSelectedFile(); + jarFilePathField.setText(selectedJarFile.getAbsolutePath()); + } + }); + + loadButton.addActionListener(e -> { + String jarPath = jarFilePathField.getText(); + String modulePath = moduleClassPathField.getText(); + if (jarPath.isEmpty() || modulePath.isEmpty()) { + statusTextArea.append(LanguageManager.getStr("moduleLoaderDialog.notEmptyField")); + return; + } + + dispose(); + }); + + pack(); + setVisible(true); + } + + /** + * Возвращает выбранный JAR файл. + * + * @return выбранный JAR файл. + */ + public File getSelectedJarFile() { + return selectedJarFile; + } + + /** + * Возвращает путь к классу модуля внутри JAR. + * + * @return путь к классу модуля. + */ + public String getModuleClassPath() { + return moduleClassPathField.getText(); + } +} diff --git a/src/main/java/robots/gui/PaneMenuBar.java b/src/main/java/robots/gui/PaneMenuBar.java index a0dc1a5..532c6cf 100644 --- a/src/main/java/robots/gui/PaneMenuBar.java +++ b/src/main/java/robots/gui/PaneMenuBar.java @@ -1,13 +1,16 @@ package robots.gui; +import robots.game.MVCController; import robots.locale.LanguageManager; import robots.log.Logger; +import robots.utils.ModuleLoader; import javax.swing.*; import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.WindowEvent; +import java.io.File; import java.util.Locale; /** @@ -146,6 +149,7 @@ private JMenu createOptionBar() { LanguageManager.getStr("PaneMenuBar.optionMenu.menuDesc"), KeyEvent.VK_O); quitMenu.add(getExitMentItem()); + quitMenu.add(getCreateChangeGameMenuItem()); quitMenu.add(getInfoAboutProgram()); return quitMenu; } @@ -163,6 +167,38 @@ private JMenuItem getExitMentItem() { return addQuitItem; } + /** + * Создает и возвращает JMenuItem для изменения игры. + * При выборе этого элемента меню открывается диалог для выбора JAR файла и класса модуля, + * затем загружает и инициализирует выбранный модуль и перезапускает игру с новым модулем. + * + * @return JMenuItem для изменения игры. + */ + private JMenuItem getCreateChangeGameMenuItem() { + JMenuItem changeGameMenuItem = new JMenuItem(LanguageManager.getStr("PaneMenuBar.optionMenu.changeGame"), KeyEvent.VK_I); + changeGameMenuItem.addActionListener(e -> { + ModuleLoaderDialog moduleLoaderDialog = new ModuleLoaderDialog(frame); + File jarFile = moduleLoaderDialog.getSelectedJarFile(); + String className = moduleLoaderDialog.getModuleClassPath(); + + if (jarFile == null || className == null || className.isEmpty()) { + return; + } + + try { + ModuleLoader moduleLoader = new ModuleLoader(jarFile); + MVCController mvcController = moduleLoader.loadController(className); + frame.restartGame(mvcController); + } catch (RuntimeException e1) { + System.err.println(e1.getMessage()); + e1.printStackTrace(); + } + }); + return changeGameMenuItem; + } + + + /** * Опция, предоставляющая информацию о программе * @return объект {@link JMenuItem}, выводящий информацию о приложении в отдельном окне diff --git a/src/main/java/robots/utils/ModuleLoader.java b/src/main/java/robots/utils/ModuleLoader.java new file mode 100644 index 0000000..62eb26c --- /dev/null +++ b/src/main/java/robots/utils/ModuleLoader.java @@ -0,0 +1,112 @@ +package robots.utils; + +import robots.game.MVCController; +import robots.game.MVCControllerWithWindows; +import robots.log.Logger; + +import javax.swing.*; +import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +/** + * Класс ModuleLoader предоставляет функциональность для загрузки и инициализации модулей + * (классов, реализующих интерфейс {@link MVCController}) из JAR файлов. + */ +public class ModuleLoader { + private final URLClassLoader urlClassLoader; + + /** + * Конструктор инициализирует URLClassLoader для загрузки классов из указанного JAR файла. + * + * @param jarFile JAR файл, содержащий классы для загрузки. + */ + public ModuleLoader(File jarFile) throws RuntimeException { + try { + URL[] urls = new URL[]{jarFile.toURI().toURL()}; + urlClassLoader = new URLClassLoader(urls); + } catch (Exception e) { + System.err.println("Указан неправильный адрес JAR файла: " + e.getMessage()); + e.printStackTrace(); + throw new RuntimeException(); + } + } + + /** + * Загружает и инициализирует класс, реализующий интерфейс {@link MVCController}, по его полному имени. + * + * @param className полное имя класса, включая пакет, для загрузки. + * @return экземпляр загруженного класса, реализующего интерфейс {@link MVCController}, если произошла ошибка она передаётся выше. + */ + public MVCController loadController(String className) throws RuntimeException { + try { + Class clazz = urlClassLoader.loadClass(className); + Object object = clazz.getConstructor().newInstance(); + Method getPainter = clazz.getMethod("getPainter"); + try { + Method getWindows = clazz.getMethod("getWindows"); + return new MVCControllerWithWindows() { + @Override + public JInternalFrame[] getWindows() { + try { + return (JInternalFrame[]) getWindows.invoke(object); + } catch (IllegalAccessException e) { + Logger.error("moduleLoader.illegalAccess"); + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + Logger.error("moduleLoader.invocationTarget"); + throw new RuntimeException(e); + } + } + + @Override + public JComponent getPainter() { + try { + return (JComponent) getPainter.invoke(object); + }catch (IllegalAccessException e) { + Logger.error("moduleLoader.illegalAccess"); + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + Logger.error("moduleLoader.invocationTarget"); + throw new RuntimeException(e); + } + } + }; + } catch (NoSuchMethodException e) { + return new MVCController() { + @Override + public JComponent getPainter() { + try { + return (JComponent) getPainter.invoke(object); + }catch (IllegalAccessException e) { + Logger.error("moduleLoader.illegalAccess"); + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + Logger.error("moduleLoader.invocationTarget"); + throw new RuntimeException(e); + } + } + }; + } catch (SecurityException e) { + throw new RuntimeException(e); + } + } catch (ClassNotFoundException e) { + Logger.error("moduleLoader.classNotFound"); + throw new RuntimeException(e); + } catch (NoSuchMethodException e) { + Logger.error("moduleLoader.noSuchMethod"); + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + Logger.error("moduleLoader.invocationTarget"); + throw new RuntimeException(e); + } catch (InstantiationException e) { + Logger.error("moduleLoader.instantiation"); + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + Logger.error("moduleLoader.illegalAccess"); + throw new RuntimeException(e); + } + } +} diff --git a/src/main/resources/locale_en.properties b/src/main/resources/locale_en.properties index 1f218fd..c34afc6 100644 --- a/src/main/resources/locale_en.properties +++ b/src/main/resources/locale_en.properties @@ -30,6 +30,18 @@ Utils.exit=Exit Utils.optionNo=No Utils.optionYes=Yes Utils.sure=Are you sure? -Logger.error=Window {0}: error! +Logger.error={0}! Logger.info={0} -Logger.pass=pass \ No newline at end of file +Logger.pass=pass +PaneMenuBar.optionMenu.changeGame=Change Game +PaneMenuBar.optionMenu.dialogLoader=Choise jar file with MVC module +PaneMenuBar.optionMenu.browse=Browse... +PaneMenuBar.optionMenu.load=Load Jar +moduleLoaderDialog.fileChooser.title=Path to the jar file: +moduleLoaderDialog.notEmptyField=Don't leave the fields empty!\n +moduleLoaderDialog.modulePath.title=Path to module controller: +moduleLoader.classNotFound=Class not found +moduleLoader.noSuchMethod=The default constructor was not found in the class +moduleLoader.invocationTarget=Error when calling the class constructor +moduleLoader.instantiation=Error creating an instance of the class +moduleLoader.illegalAccess=Insufficient permissions to access the class constructor \ No newline at end of file diff --git a/src/main/resources/locale_ru.properties b/src/main/resources/locale_ru.properties index c049a15..cc3951b 100644 --- a/src/main/resources/locale_ru.properties +++ b/src/main/resources/locale_ru.properties @@ -30,6 +30,18 @@ Utils.exit=Выйти Utils.optionNo=Нет Utils.optionYes=Да Utils.sure=Вы уверены? -Logger.error=Окно {0}: ошибка! +Logger.error={0}! Logger.info={0} -Logger.pass=pass \ No newline at end of file +Logger.pass=pass +PaneMenuBar.optionMenu.changeGame=Загрузуть свою игру +PaneMenuBar.optionMenu.dialogLoader=Выберите jar с MVC модуля +PaneMenuBar.optionMenu.browse=Выберите файл... +PaneMenuBar.optionMenu.load=Загрузить Jar файл +moduleLoaderDialog.fileChooser.title=Путь к jar-файлу: +moduleLoaderDialog.notEmptyField=Не оставляйте поля пустыми!\n +moduleLoaderDialog.modulePath.title=Путь к контроллеру модуля: +moduleLoader.classNotFound=Класс не найден +moduleLoader.noSuchMethod=Конструктор по умолчанию не найден в классе +moduleLoader.invocationTarget=Ошибка при вызове конструктора класса +moduleLoader.instantiation=Ошибка при создании экземпляра класса +moduleLoader.illegalAccess=Недостаточно прав для доступа к конструктору класса diff --git a/src/main/resources/model.jar b/src/main/resources/model.jar new file mode 100644 index 0000000..b99bfc8 Binary files /dev/null and b/src/main/resources/model.jar differ diff --git a/src/main/resources/robots.jar b/src/main/resources/robots.jar new file mode 100644 index 0000000..0e94e35 Binary files /dev/null and b/src/main/resources/robots.jar differ