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
+
+
+
+
+ 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