From e5eb0df21a2d7443747898a4549345aaaa9e8a20 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 20:36:31 +0600 Subject: [PATCH 01/12] Update MainApplicationFrame.java --- robots/src/gui/MainApplicationFrame.java | 53 ++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 62e943ee1..760eba16a 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -3,7 +3,10 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.KeyEvent; +import java.awt.*; +import java.awt.event.WindowEvent; +import javax.swing.*; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; @@ -13,6 +16,9 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.event.MenuEvent; +import javax.swing.JInternalFrame; +import javax.swing.event.MenuListener; import log.Logger; @@ -132,13 +138,52 @@ private JMenuBar generateMenuBar() addLogMessageItem.addActionListener((event) -> { Logger.debug("Новая строка"); }); - testMenu.add(addLogMessageItem); + testMenu.add(addLogMessageItem); } + return testMenu; + } + + + private JMenu createExitMenu() { + JMenu exitMenu = new JMenu("Выход"); + exitMenu.setMnemonic(KeyEvent.VK_E); + exitMenu.getAccessibleContext().setAccessibleDescription( + "Выход из приложения"); + + + exitMenu.addMenuListener(new MenuListener() { + @Override + public void menuSelected(MenuEvent e) { + exitProgram(); + } + + @Override + public void menuDeselected(MenuEvent e) { + } + + @Override + public void menuCanceled(MenuEvent e) { + } + }); - menuBar.add(lookAndFeelMenu); - menuBar.add(testMenu); - return menuBar; + return exitMenu; + } + + + public void exitProgram() { + int reply = JOptionPane.showConfirmDialog(null, + "Вы уверены что хотите выйти?", "Robots ", JOptionPane.YES_NO_OPTION); + int yesNoOption = JOptionPane.YES_NO_OPTION; + + if (reply == JOptionPane.YES_OPTION) { + + System.exit(0); + + } } + //локализация переменных + {UIManager.put("OptionPane.yesButtonText","Да"); + UIManager.put("OptionPane.noButtonText","Нет");} private void setLookAndFeel(String className) { From 878db4d0d0622a106270691be46ae4fff1eb1a28 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:04:40 +0600 Subject: [PATCH 02/12] Update MainApplicationFrame.java --- robots/src/gui/MainApplicationFrame.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 760eba16a..02482ffea 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -53,8 +53,17 @@ public MainApplicationFrame() { setJMenuBar(generateMenuBar()); setDefaultCloseOperation(EXIT_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + exitProgram(); + } + }); + } + protected LogWindow createLogWindow() { LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); @@ -105,6 +114,13 @@ private JMenuBar generateMenuBar() { JMenuBar menuBar = new JMenuBar(); + menuBar.add(createLookAndFeelMenu()); + menuBar.add(createTestMenu()); + menuBar.add(createExitMenu()); + menuBar.add(exitMenu); + return menuBar; + } + JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( From b68e6afece2aa07bd4fc9a6de7ea74940cc0d552 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:15:57 +0600 Subject: [PATCH 03/12] Update MainApplicationFrame.java --- robots/src/gui/MainApplicationFrame.java | 71 +++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 02482ffea..08fca29e6 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -6,6 +6,10 @@ import java.awt.*; import java.awt.event.WindowEvent; +import org.json.simple.parser.JSONParser; +import org.json.simple.JSONObject; +import org.json.simple.parser.ParseException; + import javax.swing.*; import javax.swing.JDesktopPane; import javax.swing.JFrame; @@ -20,6 +24,11 @@ import javax.swing.JInternalFrame; import javax.swing.event.MenuListener; +import java.io.File; +import java.io.FileWriter; +import java.io.FileReader; +import java.io.IOException; + import log.Logger; /** @@ -31,6 +40,8 @@ public class MainApplicationFrame extends JFrame { private final JDesktopPane desktopPane = new JDesktopPane(); + private final GameWindow gameWindow; + private final LogWindow logWindow; public MainApplicationFrame() { //Make the big window be indented 50 pixels from each edge @@ -50,6 +61,9 @@ public MainApplicationFrame() { GameWindow gameWindow = new GameWindow(); gameWindow.setSize(400, 400); addWindow(gameWindow); + + applyConfig(); + saveConfiguration(); setJMenuBar(generateMenuBar()); setDefaultCloseOperation(EXIT_ON_CLOSE); @@ -57,7 +71,8 @@ public MainApplicationFrame() { @Override public void windowClosing(WindowEvent e) { - exitProgram(); + saveConfiguration(); + exitProgram(); } }); @@ -200,6 +215,60 @@ public void exitProgram() { //локализация переменных {UIManager.put("OptionPane.yesButtonText","Да"); UIManager.put("OptionPane.noButtonText","Нет");} + + + protected void saveConfiguration() { + JSONObject json = new JSONObject(); + json.put("gameWindowX", gameWindow.getX()); + json.put("gameWindowY", gameWindow.getY()); + json.put("gameWindowWidth", gameWindow.getWidth()); + json.put("gameWindowHeight", gameWindow.getHeight()); + + json.put("logWindowX", logWindow.getX()); + json.put("logWindowY", logWindow.getY()); + json.put("logWindowWidth", logWindow.getWidth()); + json.put("logWindowHeight", logWindow.getHeight()); + + String userHomeDir = System.getProperty("user.home"); + File robotsDir = new File(userHomeDir + "/.Robots"); + if (!robotsDir.exists()) { + robotsDir.mkdir(); + } + File configFile = new File(userHomeDir + "/.Robots/config.json"); + try (FileWriter fileWriter = new FileWriter(configFile.getAbsolutePath())) { + fileWriter.write(json.toString()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void applyConfig() { + JSONObject config = readFromConfig(); + if (config == null) { + return; + } + gameWindow.setSize(((Long) config.get("gameWindowWidth")).intValue(), ((Long) config.get("gameWindowHeight")).intValue()); + logWindow.setSize(((Long) config.get("logWindowWidth")).intValue(), ((Long) config.get("logWindowHeight")).intValue()); + gameWindow.setLocation(((Long) config.get("gameWindowX")).intValue(), ((Long) config.get("gameWindowY")).intValue()); + logWindow.setLocation(((Long) config.get("logWindowX")).intValue(), ((Long) config.get("logWindowY")).intValue()); + } + + protected JSONObject readFromConfig() { + + File configFile = new File(System.getProperty("user.home") + "/.Robots/config.json"); + JSONParser parser = new JSONParser(); + if (configFile.exists()) { + try { + return (JSONObject) parser.parse(new FileReader(configFile)); + } catch (IOException e) { + e.printStackTrace(); + } catch (ParseException e) { + throw new RuntimeException(e); + } + } + return null; + } + private void setLookAndFeel(String className) { From c4539f03cbed7e0d3f6904bbfe255e6da429ed46 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:23:16 +0600 Subject: [PATCH 04/12] Create pom.xml --- robots/pom.xml | 128 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 robots/pom.xml diff --git a/robots/pom.xml b/robots/pom.xml new file mode 100644 index 000000000..60d00a281 --- /dev/null +++ b/robots/pom.xml @@ -0,0 +1,128 @@ + + + 4.0.0 + + groupId + robots + 1.0-SNAPSHOT + + + + + com.googlecode.json-simple + json-simple + 1.1 + + + commons-lang + commons-lang + 2.5 + + + org.apache.activemq + activemq-core + 5.3.0 + + + com.intellij + forms_rt + 5.0 + + + + junit + junit + 4.7 + test + + + + + 17 + 17 + UTF-8 + + + + + + + maven-clean-plugin + 3.1.0 + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + 14 + 14 + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + + ${project.build.directory}/libs + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + true + libs/ + + RobotsProgram + + + + + + + + maven-surefire-plugin + 2.22.1 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + + + + From 3fc5dc4701139ca29d4cddb7a8f828dfe0ce2203 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:30:43 +0600 Subject: [PATCH 05/12] Add files via upload --- robots/src/gui/RobotCoordinates.java | 38 ++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 robots/src/gui/RobotCoordinates.java diff --git a/robots/src/gui/RobotCoordinates.java b/robots/src/gui/RobotCoordinates.java new file mode 100644 index 000000000..f4a862084 --- /dev/null +++ b/robots/src/gui/RobotCoordinates.java @@ -0,0 +1,38 @@ +package gui; + +import javafx.util.Pair; + +import javax.swing.*; +import java.awt.*; +import java.util.Observable; +import java.util.Observer; + +public class RobotCoordinates extends JInternalFrame implements Observer +{ + private final TextArea coordinatesArea; + + public RobotCoordinates() + { + super("Координаты робота", true, true, true, true); + + coordinatesArea = new TextArea(); + coordinatesArea.setSize(100, 50); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(coordinatesArea, BorderLayout.CENTER); + getContentPane().add(panel); + pack(); + } + + private void updateDisplayedRobotCoordinates(Pair newCoordinates) + { + coordinatesArea.setText("X: " + newCoordinates.getKey() + "\nY: " + newCoordinates.getValue()); + coordinatesArea.invalidate(); + } + + @Override + public void update(Observable observable, Object o) + { + updateDisplayedRobotCoordinates((Pair) o); + } +} \ No newline at end of file From a930ff0c6977000cc501d14ad693bd2dbe0852fa Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:31:24 +0600 Subject: [PATCH 06/12] Update GameVisualizer.java --- robots/src/gui/GameVisualizer.java | 149 ++++++++++------------------- 1 file changed, 52 insertions(+), 97 deletions(-) diff --git a/robots/src/gui/GameVisualizer.java b/robots/src/gui/GameVisualizer.java index f82cfd8f8..cd67c2548 100644 --- a/robots/src/gui/GameVisualizer.java +++ b/robots/src/gui/GameVisualizer.java @@ -1,40 +1,35 @@ package gui; -import java.awt.Color; -import java.awt.EventQueue; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Point; +import javax.swing.*; +import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.util.Timer; import java.util.TimerTask; -import javax.swing.JPanel; - public class GameVisualizer extends JPanel { - private final Timer m_timer = initTimer(); - - private static Timer initTimer() + + private static Timer initTimer() { Timer timer = new Timer("events generator", true); return timer; } - - private volatile double m_robotPositionX = 100; - private volatile double m_robotPositionY = 100; - private volatile double m_robotDirection = 0; private volatile int m_targetPositionX = 150; private volatile int m_targetPositionY = 100; - - private static final double maxVelocity = 0.1; - private static final double maxAngularVelocity = 0.001; - - public GameVisualizer() + + + public static final double maxVelocity = 0.1; + public static final double maxAngularVelocity = 0.001; + + private final RobotController controller; + + public GameVisualizer(RobotController controller) { + this.controller = controller; + Timer m_timer = initTimer(); m_timer.schedule(new TimerTask() { @Override @@ -68,7 +63,7 @@ protected void setTargetPosition(Point p) m_targetPositionX = p.x; m_targetPositionY = p.y; } - + protected void onRedrawEvent() { EventQueue.invokeLater(this::repaint); @@ -80,39 +75,37 @@ private static double distance(double x1, double y1, double x2, double y2) double diffY = y1 - y2; return Math.sqrt(diffX * diffX + diffY * diffY); } - - private static double angleTo(double fromX, double fromY, double toX, double toY) + + private static double cornerTo(double fromX, double fromY, double toX, double toY) { double diffX = toX - fromX; double diffY = toY - fromY; - + return asNormalizedRadians(Math.atan2(diffY, diffX)); } - - protected void onModelUpdateEvent() - { - double distance = distance(m_targetPositionX, m_targetPositionY, - m_robotPositionX, m_robotPositionY); - if (distance < 0.5) - { + + protected void onModelUpdateEvent() { + double distance = distance(m_targetPositionX, m_targetPositionY, + controller.getPositionX(), controller.getPositionY()); + if (distance < 0.5) { return; } - double velocity = maxVelocity; - double angleToTarget = angleTo(m_robotPositionX, m_robotPositionY, m_targetPositionX, m_targetPositionY); + + double cornerToTarget = cornerTo(controller.getPositionX(), controller.getPositionY(), m_targetPositionX, m_targetPositionY); double angularVelocity = 0; - if (angleToTarget > m_robotDirection) - { + if (cornerToTarget > controller.getDirection() + 0.01) { angularVelocity = maxAngularVelocity; } - if (angleToTarget < m_robotDirection) - { + if (cornerToTarget < controller.getDirection() - 0.01) { angularVelocity = -maxAngularVelocity; } - - moveRobot(velocity, angularVelocity, 10); + + + controller.move(maxVelocity, angularVelocity, 10); + } - - private static double applyLimits(double value, double min, double max) + + static double applyLimits(double value, double min, double max) { if (value < min) return min; @@ -120,87 +113,49 @@ private static double applyLimits(double value, double min, double max) return max; return value; } - - private void moveRobot(double velocity, double angularVelocity, double duration) - { - velocity = applyLimits(velocity, 0, maxVelocity); - angularVelocity = applyLimits(angularVelocity, -maxAngularVelocity, maxAngularVelocity); - double newX = m_robotPositionX + velocity / angularVelocity * - (Math.sin(m_robotDirection + angularVelocity * duration) - - Math.sin(m_robotDirection)); - if (!Double.isFinite(newX)) - { - newX = m_robotPositionX + velocity * duration * Math.cos(m_robotDirection); - } - double newY = m_robotPositionY - velocity / angularVelocity * - (Math.cos(m_robotDirection + angularVelocity * duration) - - Math.cos(m_robotDirection)); - if (!Double.isFinite(newY)) - { - newY = m_robotPositionY + velocity * duration * Math.sin(m_robotDirection); - } - m_robotPositionX = newX; - m_robotPositionY = newY; - double newDirection = asNormalizedRadians(m_robotDirection + angularVelocity * duration); - m_robotDirection = newDirection; - } - private static double asNormalizedRadians(double angle) + + static double asNormalizedRadians(double corner) { - while (angle < 0) + while (corner < 0) { - angle += 2*Math.PI; + corner += 2*Math.PI; } - while (angle >= 2*Math.PI) + while (corner >= 2*Math.PI) { - angle -= 2*Math.PI; + corner -= 2*Math.PI; } - return angle; + return corner; } - - private static int round(double value) + + public static int round(double value) { return (int)(value + 0.5); } - + @Override public void paint(Graphics g) { super.paint(g); - Graphics2D g2d = (Graphics2D)g; - drawRobot(g2d, round(m_robotPositionX), round(m_robotPositionY), m_robotDirection); + Graphics2D g2d = (Graphics2D)g; + controller.draw(g2d); drawTarget(g2d, m_targetPositionX, m_targetPositionY); } - - private static void fillOval(Graphics g, int centerX, int centerY, int diam1, int diam2) + + static void fillOval(Graphics g, int centerX, int centerY, int diam1, int diam2) { g.fillOval(centerX - diam1 / 2, centerY - diam2 / 2, diam1, diam2); } - - private static void drawOval(Graphics g, int centerX, int centerY, int diam1, int diam2) + + static void drawOval(Graphics g, int centerX, int centerY, int diam1, int diam2) { g.drawOval(centerX - diam1 / 2, centerY - diam2 / 2, diam1, diam2); } - - private void drawRobot(Graphics2D g, int x, int y, double direction) - { - int robotCenterX = round(m_robotPositionX); - int robotCenterY = round(m_robotPositionY); - AffineTransform t = AffineTransform.getRotateInstance(direction, robotCenterX, robotCenterY); - g.setTransform(t); - g.setColor(Color.MAGENTA); - fillOval(g, robotCenterX, robotCenterY, 30, 10); - g.setColor(Color.BLACK); - drawOval(g, robotCenterX, robotCenterY, 30, 10); - g.setColor(Color.WHITE); - fillOval(g, robotCenterX + 10, robotCenterY, 5, 5); - g.setColor(Color.BLACK); - drawOval(g, robotCenterX + 10, robotCenterY, 5, 5); - } - + + private void drawTarget(Graphics2D g, int x, int y) { - AffineTransform t = AffineTransform.getRotateInstance(0, 0, 0); + AffineTransform t = AffineTransform.getRotateInstance(0, 0, 0); g.setTransform(t); g.setColor(Color.GREEN); fillOval(g, x, y, 5, 5); From 69444626badbd629524f2bed413beb5fda7195f4 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:33:24 +0600 Subject: [PATCH 07/12] Update GameWindow.java --- robots/src/gui/GameWindow.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/robots/src/gui/GameWindow.java b/robots/src/gui/GameWindow.java index ecb63c00f..8b0056181 100644 --- a/robots/src/gui/GameWindow.java +++ b/robots/src/gui/GameWindow.java @@ -1,17 +1,15 @@ package gui; -import java.awt.BorderLayout; - -import javax.swing.JInternalFrame; -import javax.swing.JPanel; +import javax.swing.*; +import java.awt.*; public class GameWindow extends JInternalFrame { - private final GameVisualizer m_visualizer; - public GameWindow() + + public GameWindow(RobotController controller) { super("Игровое поле", true, true, true, true); - m_visualizer = new GameVisualizer(); + GameVisualizer m_visualizer = new GameVisualizer(controller); JPanel panel = new JPanel(new BorderLayout()); panel.add(m_visualizer, BorderLayout.CENTER); getContentPane().add(panel); From fa261a33e2c38c8a9c0f7402e4bf15ee9943b317 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:34:46 +0600 Subject: [PATCH 08/12] Update MainApplicationFrame.java --- robots/src/gui/MainApplicationFrame.java | 249 +++++++++++------------ 1 file changed, 122 insertions(+), 127 deletions(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 08fca29e6..45195a445 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -1,175 +1,169 @@ package gui; -import java.awt.Dimension; -import java.awt.Toolkit; -import java.awt.event.KeyEvent; -import java.awt.*; -import java.awt.event.WindowEvent; - -import org.json.simple.parser.JSONParser; -import org.json.simple.JSONObject; -import org.json.simple.parser.ParseException; import javax.swing.*; -import javax.swing.JDesktopPane; -import javax.swing.JFrame; -import javax.swing.JInternalFrame; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.MenuEvent; -import javax.swing.JInternalFrame; import javax.swing.event.MenuListener; - +import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.WindowEvent; import java.io.File; -import java.io.FileWriter; import java.io.FileReader; +import java.io.FileWriter; import java.io.IOException; import log.Logger; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + /** * Что требуется сделать: - * 1. Метод создания меню перегружен функционалом и трудно читается. + * 1. Метод создания меню перегружен функционалом и трудно читается. * Следует разделить его на серию более простых методов (или вообще выделить отдельный класс). - * */ -public class MainApplicationFrame extends JFrame -{ +public class MainApplicationFrame extends JFrame { + private final JDesktopPane desktopPane = new JDesktopPane(); - private final GameWindow gameWindow; - private final LogWindow logWindow; - + RobotModel robotModel = new RobotModel(); + RobotView robotView = new RobotView(); + RobotController controller = new RobotController(robotModel, robotView); + private final GameWindow gameWindow = new GameWindow(controller); + private final LogWindow logWindow = createLogWindow(); + + RobotCoordinates coordinatesWindow = new RobotCoordinates(); public MainApplicationFrame() { - //Make the big window be indented 50 pixels from each edge - //of the screen. - int inset = 50; +//Make the big window be indented 50 pixels from each edge +//of the screen. + int inset = 50; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setBounds(inset, inset, - screenSize.width - inset*2, - screenSize.height - inset*2); + screenSize.width - inset * 2, + screenSize.height - inset * 2); setContentPane(desktopPane); - - - LogWindow logWindow = createLogWindow(); - addWindow(logWindow); - - GameWindow gameWindow = new GameWindow(); - gameWindow.setSize(400, 400); - addWindow(gameWindow); - + + addWindow(logWindow, 200, 200); + addWindow(gameWindow, 400, 400); + addWindow(coordinatesWindow, 300, 300); + robotModel.addObserver(coordinatesWindow); applyConfig(); - saveConfiguration(); + saveConfiguration(); setJMenuBar(generateMenuBar()); - setDefaultCloseOperation(EXIT_ON_CLOSE); - addWindowListener(new java.awt.event.WindowAdapter() { + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new java.awt.event.WindowAdapter() { @Override public void windowClosing(WindowEvent e) { - saveConfiguration(); - exitProgram(); + saveConfiguration(); + exitProgram(); } }); - + } - - - protected LogWindow createLogWindow() - { + + protected LogWindow createLogWindow() { LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); - logWindow.setLocation(10,10); + logWindow.setLocation(10, 10); logWindow.setSize(300, 800); setMinimumSize(logWindow.getSize()); logWindow.pack(); Logger.debug("Протокол работает"); return logWindow; } - - protected void addWindow(JInternalFrame frame) - { + + protected void addWindow(JInternalFrame frame, int height, int width) { + frame.setSize(width, height); desktopPane.add(frame); frame.setVisible(true); } - -// protected JMenuBar createMenuBar() { -// JMenuBar menuBar = new JMenuBar(); -// -// //Set up the lone menu. -// JMenu menu = new JMenu("Document"); -// menu.setMnemonic(KeyEvent.VK_D); -// menuBar.add(menu); -// -// //Set up the first menu item. -// JMenuItem menuItem = new JMenuItem("New"); -// menuItem.setMnemonic(KeyEvent.VK_N); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_N, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("new"); -//// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// //Set up the second menu item. -// menuItem = new JMenuItem("Quit"); -// menuItem.setMnemonic(KeyEvent.VK_Q); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_Q, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("quit"); -//// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// return menuBar; -// } - - private JMenuBar generateMenuBar() - { + +// protected JMenuBar createMenuBar() { +// JMenuBar menuBar = new JMenuBar(); +// +// //Set up the lone menu. +// JMenu menu = new JMenu("Document"); +// menu.setMnemonic(KeyEvent.VK_D); +// menuBar.add(menu); +// +// //Set up the first menu item. +// JMenuItem menuItem = new JMenuItem("New"); +// menuItem.setMnemonic(KeyEvent.VK_N); +// menuItem.setAccelerator(KeyStroke.getKeyStroke( +// KeyEvent.VK_N, ActionEvent.ALT_MASK)); +// menuItem.setActionCommand("new"); +//// menuItem.addActionListener(this); +// menu.add(menuItem); +// +// //Set up the second menu item. +// menuItem = new JMenuItem("Quit"); +// menuItem.setMnemonic(KeyEvent.VK_Q); +// menuItem.setAccelerator(KeyStroke.getKeyStroke( +// KeyEvent.VK_Q, ActionEvent.ALT_MASK)); +// menuItem.setActionCommand("quit"); +//// menuItem.addActionListener(this); +// menu.add(menuItem); +// +// return menuBar; +// } + + private JMenuBar generateMenuBar() { JMenuBar menuBar = new JMenuBar(); - + menuBar.add(createLookAndFeelMenu()); menuBar.add(createTestMenu()); menuBar.add(createExitMenu()); - menuBar.add(exitMenu); - return menuBar; - } - + + return menuBar; + } + + + private JMenu createLookAndFeelMenu() { JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); - lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( - "Управление режимом отображения приложения"); - - { - JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(systemLookAndFeel); - } + lookAndFeelMenu.getAccessibleContext(). - { - JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossplatformLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(crossplatformLookAndFeel); - } + setAccessibleDescription( + "Управление режимом отображения приложения"); + + + lookAndFeelMenu.add( + createJMenuItem("Системная схема", + KeyEvent.VK_S, + UIManager.getSystemLookAndFeelClassName())); + + lookAndFeelMenu.add(createJMenuItem("Универсальная схема", + KeyEvent.VK_S, + UIManager.getCrossPlatformLookAndFeelClassName())); + + return lookAndFeelMenu; + + } + + private JMenuItem createJMenuItem(String name, int key, String action) { + JMenuItem item = new JMenuItem(name, key); + item.addActionListener((event) -> { + setLookAndFeel(action); + this.invalidate(); + }); + return item; + } + + private JMenu createTestMenu() { JMenu testMenu = new JMenu("Тесты"); testMenu.setMnemonic(KeyEvent.VK_T); testMenu.getAccessibleContext().setAccessibleDescription( "Тестовые команды"); - + { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); addLogMessageItem.addActionListener((event) -> { Logger.debug("Новая строка"); }); - testMenu.add(addLogMessageItem); + testMenu.add(addLogMessageItem); } return testMenu; } @@ -216,7 +210,6 @@ public void exitProgram() { {UIManager.put("OptionPane.yesButtonText","Да"); UIManager.put("OptionPane.noButtonText","Нет");} - protected void saveConfiguration() { JSONObject json = new JSONObject(); json.put("gameWindowX", gameWindow.getX()); @@ -228,8 +221,13 @@ protected void saveConfiguration() { json.put("logWindowY", logWindow.getY()); json.put("logWindowWidth", logWindow.getWidth()); json.put("logWindowHeight", logWindow.getHeight()); - - String userHomeDir = System.getProperty("user.home"); + + json.put("RobotCoordinatesX", coordinatesWindow.getX()); + json.put("RobotCoordinatesY", coordinatesWindow.getY()); + json.put("RobotCoordinatesWidth", coordinatesWindow.getWidth()); + json.put("RobotCoordinatesHeight", coordinatesWindow.getHeight()); +// Save JSON to user home directory + String userHomeDir = System.getProperty("user.home"); File robotsDir = new File(userHomeDir + "/.Robots"); if (!robotsDir.exists()) { robotsDir.mkdir(); @@ -249,8 +247,10 @@ protected void applyConfig() { } gameWindow.setSize(((Long) config.get("gameWindowWidth")).intValue(), ((Long) config.get("gameWindowHeight")).intValue()); logWindow.setSize(((Long) config.get("logWindowWidth")).intValue(), ((Long) config.get("logWindowHeight")).intValue()); + coordinatesWindow.setSize(((Long) config.get("RobotCoordinatesWidth")).intValue(), ((Long) config.get("RobotCoordinatesHeight")).intValue()); gameWindow.setLocation(((Long) config.get("gameWindowX")).intValue(), ((Long) config.get("gameWindowY")).intValue()); logWindow.setLocation(((Long) config.get("logWindowX")).intValue(), ((Long) config.get("logWindowY")).intValue()); + coordinatesWindow.setLocation(((Long) config.get("RobotCoordinatesX")).intValue(), ((Long) config.get("RobotCoordinatesY")).intValue()); } protected JSONObject readFromConfig() { @@ -269,18 +269,13 @@ protected JSONObject readFromConfig() { return null; } - - private void setLookAndFeel(String className) - { - try - { + private void setLookAndFeel(String className) { + try { UIManager.setLookAndFeel(className); SwingUtilities.updateComponentTreeUI(this); - } - catch (ClassNotFoundException | InstantiationException - | IllegalAccessException | UnsupportedLookAndFeelException e) - { - // just ignore + } catch (ClassNotFoundException | InstantiationException + | IllegalAccessException | UnsupportedLookAndFeelException e) { +// just ignore } } } From f6f5c5b2e7b0f5ed8a9672713677053d7eddd508 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:35:12 +0600 Subject: [PATCH 09/12] Add files via upload --- robots/src/gui/RobotController.java | 41 +++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 robots/src/gui/RobotController.java diff --git a/robots/src/gui/RobotController.java b/robots/src/gui/RobotController.java new file mode 100644 index 000000000..cf57c0ebb --- /dev/null +++ b/robots/src/gui/RobotController.java @@ -0,0 +1,41 @@ +package gui; + +import java.awt.*; + +public class RobotController +{ + public RobotController (RobotModel robotModel, RobotView robotView ) + { + this.robotModel = robotModel; + this.robotView = robotView; + } + private final RobotView robotView; + private final RobotModel robotModel; + + + public double getPositionX() + { + return robotModel.getPositionX(); + } + + public double getPositionY() + { + return robotModel.getPositionY(); + } + + public double getDirection() + { + return robotModel.getDirection(); + } + + public void move(double velocity, double angularVelocity, double duration) + { + robotModel.move(velocity, angularVelocity, duration); + } + + public void draw(Graphics2D g) + { + robotView.draw(g, robotModel); + } + +} \ No newline at end of file From 2d0476b3736ecf60e933fff54df39eba835f1466 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:35:48 +0600 Subject: [PATCH 10/12] Add files via upload --- robots/src/gui/RobotModel.java | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 robots/src/gui/RobotModel.java diff --git a/robots/src/gui/RobotModel.java b/robots/src/gui/RobotModel.java new file mode 100644 index 000000000..63b2cd852 --- /dev/null +++ b/robots/src/gui/RobotModel.java @@ -0,0 +1,67 @@ +package gui; + +import javafx.util.Pair; + +import java.util.Observable; + +import static gui.GameVisualizer.*; + +public class RobotModel extends Observable +{ + private volatile double _positionX = 100; + public double getPositionX() + { + return _positionX; + } + public void setPositionX(double positionX) + { + _positionX = positionX; + } + + private volatile double _positionY = 100; + public double getPositionY() + { + return _positionY; + } + public void setPositionY(double positionY) + { + _positionY = positionY; + } + + private volatile double _direction = 0; + public double getDirection() + { + return _direction; + } + public void setDirection(double direction) + { + _direction = direction; + } + + public void move(double velocity, double angularVelocity, double duration) + { + velocity = applyLimits(velocity, 0, maxVelocity); + angularVelocity = applyLimits(angularVelocity, -maxAngularVelocity, maxAngularVelocity); + + var newX = _positionX; + var newY = _positionY; + var newDirection = _direction; + + if (angularVelocity == 0) + { + newX = _positionX + velocity * duration * Math.cos(_direction); + newY = _positionY + velocity * duration * Math.sin(_direction); + } + else + { + newDirection = asNormalizedRadians(_direction + angularVelocity * duration); + } + + setPositionX(newX); + setPositionY(newY); + setDirection(newDirection); + + setChanged(); + notifyObservers(new Pair<>(newX, newY)); + } +} \ No newline at end of file From eedf0920b23860d100345d7ccce5203632d007bc Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:36:09 +0600 Subject: [PATCH 11/12] Add files via upload --- robots/src/gui/RobotView.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 robots/src/gui/RobotView.java diff --git a/robots/src/gui/RobotView.java b/robots/src/gui/RobotView.java new file mode 100644 index 000000000..5d124cc21 --- /dev/null +++ b/robots/src/gui/RobotView.java @@ -0,0 +1,26 @@ +package gui; + +import java.awt.*; +import java.awt.geom.AffineTransform; + + +import static gui.GameVisualizer.*; + +public class RobotView +{ + public void draw(Graphics2D g, RobotModel robotModel) + { + int robotCenterX = round(robotModel.getPositionX()); + int robotCenterY = round(robotModel.getPositionY()); + AffineTransform t = AffineTransform.getRotateInstance(robotModel.getDirection(), robotCenterX, robotCenterY); + g.setTransform(t); + g.setColor(Color.MAGENTA); + fillOval(g, robotCenterX, robotCenterY, 30, 10); + g.setColor(Color.BLACK); + drawOval(g, robotCenterX, robotCenterY, 30, 10); + g.setColor(Color.WHITE); + fillOval(g, robotCenterX + 10, robotCenterY, 5, 5); + g.setColor(Color.BLACK); + drawOval(g, robotCenterX + 10, robotCenterY, 5, 5); + } +} \ No newline at end of file From 8d1b32c9ba88d6c1b61cdd4f14e074b6f9f2f857 Mon Sep 17 00:00:00 2001 From: GuldenaKuantaeva <91087385+GuldenaKuantaeva@users.noreply.github.com> Date: Sat, 29 Apr 2023 21:37:11 +0600 Subject: [PATCH 12/12] Update pom.xml --- robots/pom.xml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/robots/pom.xml b/robots/pom.xml index 60d00a281..6a1818672 100644 --- a/robots/pom.xml +++ b/robots/pom.xml @@ -20,6 +20,12 @@ commons-lang 2.5 + + org.openjfx + javafx-base + 11 + pom + org.apache.activemq activemq-core @@ -37,6 +43,11 @@ 4.7 test + + org.jetbrains.kotlin + kotlin-stdlib + 1.7.10 + @@ -64,7 +75,14 @@ 14 - + + org.openjfx + javafx-maven-plugin + 0.0.3 + + src.main.java.RobotsProgram + + org.apache.maven.plugins maven-dependency-plugin