diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 000000000..26d33521a
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/Robots.iml b/.idea/Robots.iml
new file mode 100644
index 000000000..8df936b5d
--- /dev/null
+++ b/.idea/Robots.iml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 000000000..650a13293
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..35eb1ddfb
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/robots/src/gui/CoordinatesDrawer.java b/robots/src/gui/CoordinatesDrawer.java
new file mode 100644
index 000000000..b4ff55b1f
--- /dev/null
+++ b/robots/src/gui/CoordinatesDrawer.java
@@ -0,0 +1,48 @@
+package gui;
+
+import log.Logger;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class CoordinatesDrawer extends JPanel {
+
+ private final java.util.Timer m_timer = initTimer();
+ public Parameters parameters;
+
+ private static java.util.Timer initTimer() {
+ java.util.Timer timer = new Timer("events generator", true);
+ return timer;
+ }
+
+ public CoordinatesDrawer(Parameters parameters) {
+ this.parameters = parameters;
+ m_timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ onRedrawEvent();
+ }
+ }, 0, 50);
+ }
+
+
+ protected void onRedrawEvent() {
+ EventQueue.invokeLater(this::repaint);
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.drawString("X: " + String.valueOf(parameters.m_robotPositionX), 25, 25);
+ g2d.drawString("Y: " + String.valueOf(parameters.m_robotPositionY), 25, 45);
+ g2d.drawString("DIRECTION: " + String.valueOf(parameters.m_robotDirection), 25, 65);
+ g2d.drawString("Target X: " + String.valueOf(parameters.m_targetPositionX), 25, 85);
+ g2d.drawString("Target Y: " + String.valueOf(parameters.m_targetPositionY), 25, 105);
+ setDoubleBuffered(true);
+ }
+
+
+}
diff --git a/robots/src/gui/CoordinatesWindow.java b/robots/src/gui/CoordinatesWindow.java
new file mode 100644
index 000000000..4002e9767
--- /dev/null
+++ b/robots/src/gui/CoordinatesWindow.java
@@ -0,0 +1,32 @@
+package gui;
+
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Observable;
+import java.util.Observer;
+
+public class CoordinatesWindow extends JInternalFrame implements Observer {
+
+ private CoordinatesDrawer drawer;
+
+ public CoordinatesWindow(Parameters parameters) {
+ super("Текущие координаты робота", true, true, true, true);
+
+
+ drawer = new CoordinatesDrawer(parameters);
+
+ JPanel panel = new JPanel(new BorderLayout());
+ panel.add(drawer, BorderLayout.CENTER);
+ getContentPane().add(panel);
+ pack();
+
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ var t = (Parameters) o;
+ drawer.parameters = t;
+
+ }
+}
\ No newline at end of file
diff --git a/robots/src/gui/GameDrawer.java b/robots/src/gui/GameDrawer.java
new file mode 100644
index 000000000..39dbea2c5
--- /dev/null
+++ b/robots/src/gui/GameDrawer.java
@@ -0,0 +1,97 @@
+package gui;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Timer;
+import java.util.TimerTask;
+
+
+public class GameDrawer extends JPanel implements Observer {
+ private final Timer m_timer = initTimer();
+ private Parameters parameters;
+
+ private static Timer initTimer() {
+ Timer timer = new Timer("events generator", true);
+ return timer;
+ }
+
+ public GameDrawer(Parameters parameters) {
+ this.parameters = parameters;
+ m_timer.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ onRedrawEvent();
+ }
+ }, 0, 50);
+
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ parameters.updateTarget(e.getPoint());
+ repaint();
+ }
+ });
+ setDoubleBuffered(true);
+
+ }
+
+ protected void onRedrawEvent() {
+ EventQueue.invokeLater(this::repaint);
+ }
+
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ Graphics2D g2d = (Graphics2D) g;
+ drawRobot(g2d, round(parameters.m_robotPositionX), round(parameters.m_robotPositionY), parameters.m_robotDirection);
+ drawTarget(g2d, parameters.m_targetPositionX, parameters.m_targetPositionY);
+ setDoubleBuffered(true);
+ }
+
+ private 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) {
+ g.drawOval(centerX - diam1 / 2, centerY - diam2 / 2, diam1, diam2);
+ }
+
+ private void drawRobot(Graphics2D g, int x, int y, double direction) {
+ int robotCenterX = round(parameters.m_robotPositionX);
+ int robotCenterY = round(parameters.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);
+ g.setTransform(t);
+ g.setColor(Color.GREEN);
+ fillOval(g, x, y, 5, 5);
+ g.setColor(Color.BLACK);
+ drawOval(g, x, y, 5, 5);
+ }
+
+ private static int round(double value) {
+ return (int) (value + 0.5);
+ }
+
+ @Override
+ public void update(Observable o, Object arg) {
+ parameters = (Parameters) o;
+ repaint();
+ }
+}
diff --git a/robots/src/gui/GameVisualizer.java b/robots/src/gui/GameVisualizer.java
deleted file mode 100644
index f82cfd8f8..000000000
--- a/robots/src/gui/GameVisualizer.java
+++ /dev/null
@@ -1,210 +0,0 @@
-package gui;
-
-import java.awt.Color;
-import java.awt.EventQueue;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-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()
- {
- 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()
- {
- m_timer.schedule(new TimerTask()
- {
- @Override
- public void run()
- {
- onRedrawEvent();
- }
- }, 0, 50);
- m_timer.schedule(new TimerTask()
- {
- @Override
- public void run()
- {
- onModelUpdateEvent();
- }
- }, 0, 10);
- addMouseListener(new MouseAdapter()
- {
- @Override
- public void mouseClicked(MouseEvent e)
- {
- setTargetPosition(e.getPoint());
- repaint();
- }
- });
- setDoubleBuffered(true);
- }
-
- protected void setTargetPosition(Point p)
- {
- m_targetPositionX = p.x;
- m_targetPositionY = p.y;
- }
-
- protected void onRedrawEvent()
- {
- EventQueue.invokeLater(this::repaint);
- }
-
- private static double distance(double x1, double y1, double x2, double y2)
- {
- double diffX = x1 - x2;
- double diffY = y1 - y2;
- return Math.sqrt(diffX * diffX + diffY * diffY);
- }
-
- private static double angleTo(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)
- {
- return;
- }
- double velocity = maxVelocity;
- double angleToTarget = angleTo(m_robotPositionX, m_robotPositionY, m_targetPositionX, m_targetPositionY);
- double angularVelocity = 0;
- if (angleToTarget > m_robotDirection)
- {
- angularVelocity = maxAngularVelocity;
- }
- if (angleToTarget < m_robotDirection)
- {
- angularVelocity = -maxAngularVelocity;
- }
-
- moveRobot(velocity, angularVelocity, 10);
- }
-
- private static double applyLimits(double value, double min, double max)
- {
- if (value < min)
- return min;
- if (value > 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)
- {
- while (angle < 0)
- {
- angle += 2*Math.PI;
- }
- while (angle >= 2*Math.PI)
- {
- angle -= 2*Math.PI;
- }
- return angle;
- }
-
- private 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);
- drawTarget(g2d, m_targetPositionX, m_targetPositionY);
- }
-
- private 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)
- {
- 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);
- g.setTransform(t);
- g.setColor(Color.GREEN);
- fillOval(g, x, y, 5, 5);
- g.setColor(Color.BLACK);
- drawOval(g, x, y, 5, 5);
- }
-}
diff --git a/robots/src/gui/GameWindow.java b/robots/src/gui/GameWindow.java
index ecb63c00f..0c16319e6 100644
--- a/robots/src/gui/GameWindow.java
+++ b/robots/src/gui/GameWindow.java
@@ -1,20 +1,27 @@
package gui;
+import log.Logger;
+
import java.awt.BorderLayout;
+import java.util.Observable;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
-public class GameWindow extends JInternalFrame
-{
- private final GameVisualizer m_visualizer;
- public GameWindow()
- {
+public class GameWindow extends JInternalFrame {
+ private final GameDrawer m_drawer;
+ private final RobotModel m_robot;
+
+ public GameWindow(Parameters parameters) {
super("Игровое поле", true, true, true, true);
- m_visualizer = new GameVisualizer();
+ Logger.debug("Создано игровое поле");
+ m_robot = new RobotModel(parameters);
+ m_drawer = new GameDrawer(parameters);
+ parameters.addObserver(m_drawer);
+
JPanel panel = new JPanel(new BorderLayout());
- panel.add(m_visualizer, BorderLayout.CENTER);
+ panel.add(m_drawer, BorderLayout.CENTER);
getContentPane().add(panel);
pack();
}
-}
+}
\ No newline at end of file
diff --git a/robots/src/gui/LogWindow.java b/robots/src/gui/LogWindow.java
index 723d3e2fc..58a1958da 100644
--- a/robots/src/gui/LogWindow.java
+++ b/robots/src/gui/LogWindow.java
@@ -11,19 +11,17 @@
import log.LogEntry;
import log.LogWindowSource;
-public class LogWindow extends JInternalFrame implements LogChangeListener
-{
+public class LogWindow extends JInternalFrame implements LogChangeListener {
private LogWindowSource m_logSource;
private TextArea m_logContent;
- public LogWindow(LogWindowSource logSource)
- {
+ public LogWindow(LogWindowSource logSource) {
super("Протокол работы", true, true, true, true);
m_logSource = logSource;
m_logSource.registerListener(this);
m_logContent = new TextArea("");
m_logContent.setSize(200, 500);
-
+
JPanel panel = new JPanel(new BorderLayout());
panel.add(m_logContent, BorderLayout.CENTER);
getContentPane().add(panel);
@@ -31,20 +29,17 @@ public LogWindow(LogWindowSource logSource)
updateLogContent();
}
- private void updateLogContent()
- {
+ private void updateLogContent() {
StringBuilder content = new StringBuilder();
- for (LogEntry entry : m_logSource.all())
- {
+ for (LogEntry entry : m_logSource.all()) {
content.append(entry.getMessage()).append("\n");
}
m_logContent.setText(content.toString());
- m_logContent.invalidate();
+ // m_logContent.invalidate();
}
-
+
@Override
- public void onLogChanged()
- {
+ public void onLogChanged() {
EventQueue.invokeLater(this::updateLogContent);
}
}
diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java
index 62e943ee1..da9cd59d6 100644
--- a/robots/src/gui/MainApplicationFrame.java
+++ b/robots/src/gui/MainApplicationFrame.java
@@ -3,107 +3,104 @@
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
+import java.beans.PropertyVetoException;
+import java.io.*;
-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.*;
import log.Logger;
+import static java.lang.Integer.parseInt;
+
/**
* Что требуется сделать:
- * 1. Метод создания меню перегружен функционалом и трудно читается.
+ * 1. Метод создания меню перегружен функционалом и трудно читается.
* Следует разделить его на серию более простых методов (или вообще выделить отдельный класс).
- *
*/
-public class MainApplicationFrame extends JFrame
-{
+public class MainApplicationFrame extends JFrame {
private final JDesktopPane desktopPane = new JDesktopPane();
-
+
public MainApplicationFrame() {
//Make the big window be indented 50 pixels from each edge
//of the screen.
- int inset = 50;
+ 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);
-
-
+
+ CreateInternalWindows();
+ setJMenuBar(generateMenuBar());
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ ReadPreviousSettings();
+
+ }
+
+ private void ReadPreviousSettings() {
+ try (FileReader fr = new FileReader("text.txt");) {
+ var t = "";
+ var c = 0;
+ while ((c = fr.read()) != -1) {
+
+ t += (char) c;
+ }
+ SetPreviousParameters(t);
+ } catch (IOException ex) {
+
+ System.out.println("не считали");
+ }
+ }
+
+ private void CreateInternalWindows() {
LogWindow logWindow = createLogWindow();
addWindow(logWindow);
+ var parameters = new Parameters();
+
+ CoordinatesWindow coordinatesWindow = createCoordinatesWindow(parameters);
+ coordinatesWindow.setSize(300, 150);
+ coordinatesWindow.setMinimumSize(coordinatesWindow.getSize());
+ addWindow(coordinatesWindow);
+
+ parameters.addObserver(coordinatesWindow);
- GameWindow gameWindow = new GameWindow();
- gameWindow.setSize(400, 400);
+ GameWindow gameWindow = new GameWindow(parameters);
+ gameWindow.setSize(400, 400);
addWindow(gameWindow);
+ }
- setJMenuBar(generateMenuBar());
- setDefaultCloseOperation(EXIT_ON_CLOSE);
+ private CoordinatesWindow createCoordinatesWindow(Parameters parameters) {
+ var coordinatesWindow = new CoordinatesWindow(parameters);
+ coordinatesWindow.setLocation(400, 400);
+ coordinatesWindow.pack();
+ return coordinatesWindow;
}
-
- 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) {
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()
- {
+
+ private JMenuBar generateMenuBar() {
JMenuBar menuBar = new JMenuBar();
-
+
+
JMenu lookAndFeelMenu = new JMenu("Режим отображения");
lookAndFeelMenu.setMnemonic(KeyEvent.VK_V);
lookAndFeelMenu.getAccessibleContext().setAccessibleDescription(
"Управление режимом отображения приложения");
-
+
{
JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S);
systemLookAndFeel.addActionListener((event) -> {
@@ -122,11 +119,29 @@ private JMenuBar generateMenuBar()
lookAndFeelMenu.add(crossplatformLookAndFeel);
}
+
+ JMenu file = new JMenu("Файл");
+ file.setMnemonic(KeyEvent.VK_V);
+ file.getAccessibleContext().setAccessibleDescription(
+ "Управление приложением");
+ {
+ JMenuItem closeMenu = new JMenuItem("Закрыть приложение", KeyEvent.VK_S);
+ closeMenu.addActionListener((event) -> {
+ int res = JOptionPane.showOptionDialog(null, "Закрыть приложение?", null, JOptionPane.YES_NO_OPTION,
+ JOptionPane.PLAIN_MESSAGE, null, new Object[]{"Да", "Нет"}, null);
+ if (res == 0) {
+ SaveParameters();
+ System.exit(0);
+ }
+ });
+ file.add(closeMenu);
+ }
+
JMenu testMenu = new JMenu("Тесты");
testMenu.setMnemonic(KeyEvent.VK_T);
testMenu.getAccessibleContext().setAccessibleDescription(
"Тестовые команды");
-
+
{
JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S);
addLogMessageItem.addActionListener((event) -> {
@@ -135,21 +150,95 @@ private JMenuBar generateMenuBar()
testMenu.add(addLogMessageItem);
}
+ menuBar.add(file);
menuBar.add(lookAndFeelMenu);
menuBar.add(testMenu);
return menuBar;
}
-
- private void setLookAndFeel(String className)
- {
- try
- {
+
+ private void SaveParameters() {
+ //var temp ="";
+ try (FileWriter writer = new FileWriter("text.txt", false)) {
+
+ var t = this.desktopPane.getAllFrames();
+
+ for (int i = 0; i < t.length; i++) {
+ var location = t[i].getLocation();
+ var size = t[i].getSize();
+ var isShowing = t[i].isShowing();
+
+ t[i].setResizable(true);
+ var temp = t[i].getTitle() + "\n" + location.x + " " + location.y + "\n" + size.width + " " + size.height + "\n" + (isShowing ? "T" : "F") + "\n";
+// writer.write(location.x+" "+ location.y + "\n");
+// writer.write(size.width+" "+ size.height + "\n");
+// writer.write(isShowing?"T":"F");
+// writer.write("\n");
+ writer.write(temp);
+ }
+ writer.flush();
+ } catch (IOException ex) {
+
+ System.out.println("не сохранили");
+ }
+
+ //System.out.println(temp);
+ }
+
+ private void SetPreviousParameters(String text) {
+ if (text.length() == 0)
+ return;
+ var t = this.desktopPane.getAllFrames();
+ var arr = text.split("\n");
+ var p = 0;
+ var counter = 0;
+ while (counter < t.length) {
+ for (int i = 0; i < t.length; i++) {
+ var name = arr[0 + p + counter];
+ if (t[i].getTitle().equals(name)) {
+ var current = t[i];
+ var location = arr[counter + p + 1].split(" ");
+ current.setLocation(parseInt(location[0]), parseInt(location[1]));
+ var size = arr[counter + 2 + p].split(" ");
+ current.setSize(parseInt(size[0]), parseInt(size[1]));
+ var showing = arr[counter + 3 + p];
+ current.setBounds(parseInt(location[0]), parseInt(location[1]), parseInt(size[0]), parseInt(size[1]));
+ if (showing.equals("F")) {
+ try {
+ current.setIcon(true);
+ } catch (PropertyVetoException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ p += 3;
+ counter += 1;
+ break;
+ }
+ }
+ }
+// for (int i = 0; i parameters.m_targetPositionX)
+ newX -= koef;
+ if (parameters.m_robotPositionY > parameters.m_targetPositionY)
+ newY -= koef;
+ var dir = angleTo(newX, newY, parameters.m_targetPositionX, parameters.m_targetPositionY);
+ parameters.updateRobot(newX, newY, dir);
+ }
+
+ private static double angleTo(double fromX, double fromY, double toX, double toY) {
+ double diffX = toX - fromX;
+ double diffY = toY - fromY;
+ return asNormalizedRadians(Math.atan2(diffY, diffX));
+ }
+
+ private static double asNormalizedRadians(double angle) {
+ while (angle < 0) {
+ angle += 2 * Math.PI;
+ }
+ while (angle >= 2 * Math.PI) {
+ angle -= 2 * Math.PI;
+ }
+ return angle;
+ }
+
+
+}
diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/gui/RobotsProgram.java
index ae0930a8b..3051d62f4 100644
--- a/robots/src/gui/RobotsProgram.java
+++ b/robots/src/gui/RobotsProgram.java
@@ -5,21 +5,18 @@
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
-public class RobotsProgram
-{
- public static void main(String[] args) {
- try {
- UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
-// UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
-// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
- } catch (Exception e) {
- e.printStackTrace();
- }
- SwingUtilities.invokeLater(() -> {
- MainApplicationFrame frame = new MainApplicationFrame();
- frame.pack();
- frame.setVisible(true);
- frame.setExtendedState(Frame.MAXIMIZED_BOTH);
- });
- }}
+public class RobotsProgram {
+ public static void main(String[] args) {
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ SwingUtilities.invokeLater(() -> {
+ MainApplicationFrame frame = new MainApplicationFrame();
+ frame.pack();
+ frame.setVisible(true);
+ frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+ });
+ }
+}
diff --git a/robots/src/log/List.java b/robots/src/log/List.java
new file mode 100644
index 000000000..4eb3c4c34
--- /dev/null
+++ b/robots/src/log/List.java
@@ -0,0 +1,123 @@
+package log;
+
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static java.lang.System.*;
+
+/**
+ * Что починить:
+ * 1. Этот класс порождает утечку ресурсов (связанные слушатели оказываются
+ * удерживаемыми в памяти)
+ * 2. Этот класс хранит активные сообщения лога, но в такой реализации он
+ * их лишь накапливает. Надо же, чтобы количество сообщений в логе было ограничено
+ * величиной m_iQueueLength (т.е. реально нужна очередь сообщений
+ * ограниченного размера)
+ */
+public class List {
+ private final int size;
+ public int curSize;
+
+ public List(int size) {
+ this.size = size;
+ curSize = 0;
+ }
+
+ private static class Node {
+ final LogEntry item;
+ final AtomicReference next;
+
+ Node(LogEntry item, Node next) {
+ this.item = item;
+ this.next = new AtomicReference(next);
+ }
+ }
+
+ private AtomicReference tail = new AtomicReference<>();
+ private AtomicReference head
+ = new AtomicReference(new Node(null, null));
+
+ public void put(LogEntry item) {
+ Node newNode = new Node(item, null);
+ var curHead = head.get();
+ if (curHead.item == null || size == 1) {
+ if (!head.compareAndSet(curHead, newNode)) {
+ put(item);
+ return;
+ }
+ curSize++;
+ return;
+ }
+ if (tail.get() == null) {
+ if (!tail.compareAndSet(null, newNode)) {
+ put(item);
+ return;
+ }
+ if (!head.get().next.compareAndSet(null, tail.get())) {
+ put(item);
+ return;
+ }
+ curSize++;
+ return;
+ }
+ if (!tail.get().next.compareAndSet(null, newNode)) {
+ put(item);
+ return;
+ }
+ var previous = tail.get();
+ if (!tail.compareAndSet(previous, previous.next.get())) {
+ put(item);
+ return;
+ }
+ curSize++;
+ if (size < curSize) {
+ var cur = head.get();
+ if (!head.compareAndSet(cur, cur.next.get())) {
+ put(item);
+ return;
+ }
+ curSize--;
+ }
+
+ }
+
+ public int size() {
+ return curSize;
+ }
+
+ public Node[] getCurNodes() {
+ var result = new Node[size];
+ var curIndex = 0;
+ var start = this.head;
+ while (start.get() != null && start.get().item != null) {
+ synchronized (start.get()) {
+ var prev = start.get();
+ result[curIndex] = prev;
+ start = prev.next;
+ curIndex++;
+ }
+ }
+
+ return result;
+ }
+
+ public Iterable range(int startFrom, int count) {
+ var nodeList = Arrays.copyOfRange(getCurNodes(), startFrom, count);
+ var result = new LogEntry[nodeList.length];
+ var cur = 0;
+ for (Node node : nodeList) {
+ result[cur] = node.item;
+ cur++;
+ }
+ return java.util.List.of(result);
+ }
+
+ public void print(Node[] arr) {
+ for (Node node : arr) {
+ if (node != null)
+ out.println(node.item.getMessage());
+ }
+ System.out.println("*****");
+ }
+
+}
diff --git a/robots/src/log/LogWindowSource.java b/robots/src/log/LogWindowSource.java
index ca0ce4426..56c39f142 100644
--- a/robots/src/log/LogWindowSource.java
+++ b/robots/src/log/LogWindowSource.java
@@ -3,87 +3,63 @@
import java.util.ArrayList;
import java.util.Collections;
-/**
- * Что починить:
- * 1. Этот класс порождает утечку ресурсов (связанные слушатели оказываются
- * удерживаемыми в памяти)
- * 2. Этот класс хранит активные сообщения лога, но в такой реализации он
- * их лишь накапливает. Надо же, чтобы количество сообщений в логе было ограничено
- * величиной m_iQueueLength (т.е. реально нужна очередь сообщений
- * ограниченного размера)
- */
-public class LogWindowSource
-{
+public class LogWindowSource {
+ /**
+ * Что починить:
+ * 1. Этот класс порождает утечку ресурсов (связанные слушатели оказываются
+ * удерживаемыми в памяти)
+ * 2. Этот класс хранит активные сообщения лога, но в такой реализации он
+ * их лишь накапливает. Надо же, чтобы количество сообщений в логе было ограничено
+ * величиной m_iQueueLength (т.е. реально нужна очередь сообщений
+ * ограниченного размера)
+ */
private int m_iQueueLength;
-
- private ArrayList m_messages;
+
+ private List m_msgs;
private final ArrayList m_listeners;
- private volatile LogChangeListener[] m_activeListeners;
-
- public LogWindowSource(int iQueueLength)
- {
+
+ public LogWindowSource(int iQueueLength) {
m_iQueueLength = iQueueLength;
- m_messages = new ArrayList(iQueueLength);
- m_listeners = new ArrayList();
+ m_msgs = new List(30);
+ m_listeners = new ArrayList<>();
}
-
- public void registerListener(LogChangeListener listener)
- {
- synchronized(m_listeners)
- {
+
+ public void registerListener(LogChangeListener listener) {
+ synchronized (m_listeners) {
m_listeners.add(listener);
- m_activeListeners = null;
}
}
-
- public void unregisterListener(LogChangeListener listener)
- {
- synchronized(m_listeners)
- {
+
+ public void unregisterListener(LogChangeListener listener) {
+ synchronized (m_listeners) {
m_listeners.remove(listener);
- m_activeListeners = null;
}
}
-
- public void append(LogLevel logLevel, String strMessage)
- {
+
+ public void append(LogLevel logLevel, String strMessage) {
LogEntry entry = new LogEntry(logLevel, strMessage);
- m_messages.add(entry);
- LogChangeListener [] activeListeners = m_activeListeners;
- if (activeListeners == null)
- {
- synchronized (m_listeners)
- {
- if (m_activeListeners == null)
- {
- activeListeners = m_listeners.toArray(new LogChangeListener [0]);
- m_activeListeners = activeListeners;
- }
+ m_msgs.put(entry);
+
+ synchronized (m_listeners) {
+ for (LogChangeListener listener : m_listeners) {
+ listener.onLogChanged();
}
}
- for (LogChangeListener listener : activeListeners)
- {
- listener.onLogChanged();
- }
}
-
- public int size()
- {
- return m_messages.size();
+
+ public int size() {
+ return m_msgs.size();
}
- public Iterable range(int startFrom, int count)
- {
- if (startFrom < 0 || startFrom >= m_messages.size())
- {
+ public Iterable range(int startFrom, int count) {
+ if (startFrom < 0 || startFrom >= m_msgs.size()) {
return Collections.emptyList();
}
- int indexTo = Math.min(startFrom + count, m_messages.size());
- return m_messages.subList(startFrom, indexTo);
+ int indexTo = Math.min(startFrom + count, m_msgs.size());
+ return m_msgs.range(startFrom, indexTo);
}
- public Iterable all()
- {
- return m_messages;
+ public Iterable all() {
+ return m_msgs.range(0, size());
}
}
diff --git a/text.txt b/text.txt
new file mode 100644
index 000000000..e2469fecb
--- /dev/null
+++ b/text.txt
@@ -0,0 +1,12 @@
+Текущие координаты робота
+1076 525
+300 150
+T
+Игровое поле
+913 58
+400 400
+T
+Протокол работы
+10 10
+212 524
+T