From c96d02b79eb4df1dc5297c5c328214879c33b6ca Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Tue, 25 Mar 2025 00:26:36 +0500 Subject: [PATCH 01/18] initial commit --- robots/.gitignore | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 robots/.gitignore diff --git a/robots/.gitignore b/robots/.gitignore deleted file mode 100644 index 2757ffa76..000000000 --- a/robots/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/bin/ -/.settings/ From 8193112bd621ab2efdb511bc3201f2abd6682484 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Tue, 25 Mar 2025 00:29:04 +0500 Subject: [PATCH 02/18] initial commit --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2c6eb3893..5a04d7653 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /.metadata /robots/.settings /robots/bin -eclipse.bat \ No newline at end of file +eclipse.bat +.idea +/robots/src/.classpath +/robots/src/.project \ No newline at end of file From 4a456151eda5169648a0cecad1f5821c4c1ca2ce Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Tue, 25 Mar 2025 00:42:52 +0500 Subject: [PATCH 03/18] initial commit --- robots/src/gui/RobotsProgram.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/gui/RobotsProgram.java index ae0930a8b..7cb901c7f 100644 --- a/robots/src/gui/RobotsProgram.java +++ b/robots/src/gui/RobotsProgram.java @@ -10,9 +10,6 @@ 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(); } From 600a877f192ac886c4a6916bfc1f9d25bad4f985 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 9 Apr 2025 10:15:00 +0500 Subject: [PATCH 04/18] initial commit --- .gitignore | 4 +- robots/src/gui/LogWindow.java | 4 +- robots/src/gui/MainApplicationFrame.java | 147 +++++++++++------------ robots/src/gui/RobotsProgram.java | 12 +- robots/src/log/LogChangeListener.java | 2 +- robots/src/log/LogWindowSource.java | 8 +- robots/src/log/Logger.java | 8 +- 7 files changed, 89 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index 5a04d7653..b328e8790 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ eclipse.bat .idea /robots/src/.classpath -/robots/src/.project \ No newline at end of file +/robots/src/.project +./simple.txt +.my \ No newline at end of file diff --git a/robots/src/gui/LogWindow.java b/robots/src/gui/LogWindow.java index 723d3e2fc..4e446b042 100644 --- a/robots/src/gui/LogWindow.java +++ b/robots/src/gui/LogWindow.java @@ -13,8 +13,8 @@ public class LogWindow extends JInternalFrame implements LogChangeListener { - private LogWindowSource m_logSource; - private TextArea m_logContent; + private final LogWindowSource m_logSource; + private final TextArea m_logContent; public LogWindow(LogWindowSource logSource) { diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 62e943ee1..76e29b9b1 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -3,119 +3,88 @@ import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; -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; -/** - * Что требуется сделать: - * 1. Метод создания меню перегружен функционалом и трудно читается. - * Следует разделить его на серию более простых методов (или вообще выделить отдельный класс). - * - */ public class MainApplicationFrame extends JFrame { + private final LogWindow logWindow; + private final GameWindow gameWindow; + 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; + public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow) { + this.logWindow = logWindow; + this.gameWindow = gameWindow; + initialize(); + } + + private void initialize() { + setLogWindow(logWindow); + 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(logWindow); addWindow(gameWindow); setJMenuBar(generateMenuBar()); - setDefaultCloseOperation(EXIT_ON_CLOSE); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + handleExit(); + } + }); } - - protected LogWindow createLogWindow() + + + protected void setLogWindow(LogWindow logWindow ) { - LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); logWindow.setLocation(10,10); logWindow.setSize(300, 800); setMinimumSize(logWindow.getSize()); logWindow.pack(); Logger.debug("Протокол работает"); - return logWindow; } - + + // окна внутри этого стола 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() { JMenuBar menuBar = new JMenuBar(); - + JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); - lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( - "Управление режимом отображения приложения"); - + lookAndFeelMenu.getAccessibleContext().setAccessibleDescription("Управление режимом отображения приложения"); + { JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemLookAndFeel.addActionListener((event) -> { + systemLookAndFeel.addActionListener((_) -> { setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - this.invalidate(); + invalidate(); }); lookAndFeelMenu.add(systemLookAndFeel); } { JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossplatformLookAndFeel.addActionListener((event) -> { + crossplatformLookAndFeel.addActionListener((_) -> { setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); this.invalidate(); }); @@ -124,22 +93,48 @@ private JMenuBar generateMenuBar() JMenu testMenu = new JMenu("Тесты"); testMenu.setMnemonic(KeyEvent.VK_T); - testMenu.getAccessibleContext().setAccessibleDescription( - "Тестовые команды"); - + testMenu.getAccessibleContext().setAccessibleDescription("Тестовые команды"); + { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); - addLogMessageItem.addActionListener((event) -> { - Logger.debug("Новая строка"); - }); + addLogMessageItem.addActionListener((_) -> Logger.debug("Новая строка")); testMenu.add(addLogMessageItem); } + JMenu fileMenu = new JMenu("Файл"); + JMenuItem exitItem = new JMenuItem("Выход"); + + exitItem.addActionListener(e -> handleExit()); + + + + fileMenu.add(exitItem); + menuBar.add(fileMenu); + + + menuBar.add(lookAndFeelMenu); menuBar.add(testMenu); return menuBar; } - + + private void handleExit() { + UIManager.put("OptionPane.yesButtonText", "Да"); + UIManager.put("OptionPane.noButtonText", "Нет"); + + int choice = JOptionPane.showConfirmDialog( + this, + "Вы действительно хотите выйти?", + "Подтверждение выхода", + JOptionPane.YES_NO_OPTION + ); + + if (choice == JOptionPane.YES_OPTION) { + System.exit(0); + } + } + + private void setLookAndFeel(String className) { try diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/gui/RobotsProgram.java index 7cb901c7f..29c5353e7 100644 --- a/robots/src/gui/RobotsProgram.java +++ b/robots/src/gui/RobotsProgram.java @@ -8,15 +8,17 @@ 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); + MainController mainController = new MainController(); + MainApplicationFrame _ = mainController.createFrame(); }); - }} + + } +} diff --git a/robots/src/log/LogChangeListener.java b/robots/src/log/LogChangeListener.java index 0b0fb85dd..2ba48db75 100644 --- a/robots/src/log/LogChangeListener.java +++ b/robots/src/log/LogChangeListener.java @@ -2,5 +2,5 @@ public interface LogChangeListener { - public void onLogChanged(); + void onLogChanged(); } diff --git a/robots/src/log/LogWindowSource.java b/robots/src/log/LogWindowSource.java index ca0ce4426..9aa27edf6 100644 --- a/robots/src/log/LogWindowSource.java +++ b/robots/src/log/LogWindowSource.java @@ -14,15 +14,13 @@ */ public class LogWindowSource { - private int m_iQueueLength; - - private ArrayList m_messages; + + private final ArrayList m_messages; private final ArrayList m_listeners; private volatile LogChangeListener[] m_activeListeners; public LogWindowSource(int iQueueLength) { - m_iQueueLength = iQueueLength; m_messages = new ArrayList(iQueueLength); m_listeners = new ArrayList(); } @@ -49,7 +47,7 @@ public void append(LogLevel logLevel, String strMessage) { LogEntry entry = new LogEntry(logLevel, strMessage); m_messages.add(entry); - LogChangeListener [] activeListeners = m_activeListeners; + LogChangeListener[] activeListeners = m_activeListeners; if (activeListeners == null) { synchronized (m_listeners) diff --git a/robots/src/log/Logger.java b/robots/src/log/Logger.java index b008a5d01..5ff4fa964 100644 --- a/robots/src/log/Logger.java +++ b/robots/src/log/Logger.java @@ -2,13 +2,9 @@ public final class Logger { - private static final LogWindowSource defaultLogSource; - static { - defaultLogSource = new LogWindowSource(100); - } + private static final LogWindowSource defaultLogSource = new LogWindowSource(100); - private Logger() - { + private Logger() { } public static void debug(String strMessage) From b6ea9c410e5853746c51cd31931459efcddaa8be Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 16 Apr 2025 09:22:02 +0500 Subject: [PATCH 05/18] do task1 --- .gitignore | 2 +- my.txt | 56 ++++++++++++++++++ net | 1 + .../java-project/gui/GameVisualizer$1.class | Bin 0 -> 605 bytes .../java-project/gui/GameVisualizer$2.class | Bin 0 -> 610 bytes .../java-project/gui/GameVisualizer$3.class | Bin 0 -> 833 bytes .../java-project/gui/GameVisualizer.class | Bin 0 -> 5627 bytes .../java-project/gui/GameWindow.class | Bin 0 -> 856 bytes .../java-project/gui/LogWindow.class | Bin 0 -> 2580 bytes .../gui/MainApplicationFrame$1.class | Bin 0 -> 754 bytes .../gui/MainApplicationFrame.class | Bin 0 -> 6141 bytes .../java-project/gui/MainController.class | Bin 0 -> 1012 bytes .../java-project/gui/RobotsProgram.class | Bin 0 -> 1473 bytes .../java-project/log/LogChangeListener.class | Bin 0 -> 148 bytes .../java-project/log/LogEntry.class | Bin 0 -> 651 bytes .../java-project/log/LogLevel.class | Bin 0 -> 1390 bytes .../java-project/log/LogWindowSource.class | Bin 0 -> 2463 bytes out/production/java-project/log/Logger.class | Bin 0 -> 854 bytes robots/src/gui/MainController.java | 29 +++++++++ 19 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 my.txt create mode 160000 net create mode 100644 out/production/java-project/gui/GameVisualizer$1.class create mode 100644 out/production/java-project/gui/GameVisualizer$2.class create mode 100644 out/production/java-project/gui/GameVisualizer$3.class create mode 100644 out/production/java-project/gui/GameVisualizer.class create mode 100644 out/production/java-project/gui/GameWindow.class create mode 100644 out/production/java-project/gui/LogWindow.class create mode 100644 out/production/java-project/gui/MainApplicationFrame$1.class create mode 100644 out/production/java-project/gui/MainApplicationFrame.class create mode 100644 out/production/java-project/gui/MainController.class create mode 100644 out/production/java-project/gui/RobotsProgram.class create mode 100644 out/production/java-project/log/LogChangeListener.class create mode 100644 out/production/java-project/log/LogEntry.class create mode 100644 out/production/java-project/log/LogLevel.class create mode 100644 out/production/java-project/log/LogWindowSource.class create mode 100644 out/production/java-project/log/Logger.class create mode 100644 robots/src/gui/MainController.java diff --git a/.gitignore b/.gitignore index b328e8790..56ad388cd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,4 @@ eclipse.bat /robots/src/.classpath /robots/src/.project ./simple.txt -.my \ No newline at end of file +./my.txt \ No newline at end of file diff --git a/my.txt b/my.txt new file mode 100644 index 000000000..6e5615f98 --- /dev/null +++ b/my.txt @@ -0,0 +1,56 @@ + +=============================================================================================================== +🧠 Что такое MVC (Model–View–Controller)? +MVC — это архитектурный шаблон для разделения логики в программе: + +Компонент Что делает Пример в GUI +🧩 Model Хранит данные и бизнес-логику список логов, состояние игры +🖼️ View Отображает данные (GUI) окно, кнопки, таблицы +🕹️ Controller Обрабатывает действия пользователя и обновляет Model/View обработка кликов, вызов логики +=============================================================================================================== +1. Model +LogEntry — это элемент данных лога (чистая модель). + +Logger — это контроллер модели (может менять состояние модели). + +GameState (если есть) — состояние игры. + +2. View +MainApplicationFrame — главное окно. + +GameWindow, LogWindow — визуальные представления (View). + +GameVisualizer — возможно, рисует объекты (чистый View). + +3. Controller +LogChangeListener — похоже на контроллер (слушатель изменений, вызывает обновление View). + +Внутри GameWindow может быть код, который слушает кнопки и вызывает действия → это тоже контроллерская часть. +=============================================================================================================== + +Задавай себе 3 вопроса: + +Этот класс хранит данные? → значит, это Model. + +Он отображает что-то на экране, но сам по себе ничего не делает? → View. + +Он реагирует на действия и вызывает методы моделей или обновляет представление? → Controller. +=============================================================================================================== + +// JFrame — основное окно +// JDesktopPane — рабочий стол (панель для окон). +// JInternalFrame — подокна (внутренние окна). + +=============================================================================================================== + +JFrame + └── JPanel + ├── JLabel + ├── JTextField + └── JButton + +=============================================================================================================== + + + +=============================================================================================================== \ No newline at end of file diff --git a/net b/net new file mode 160000 index 000000000..10760b596 --- /dev/null +++ b/net @@ -0,0 +1 @@ +Subproject commit 10760b596803fd8219c89cf784d948f066bf4767 diff --git a/out/production/java-project/gui/GameVisualizer$1.class b/out/production/java-project/gui/GameVisualizer$1.class new file mode 100644 index 0000000000000000000000000000000000000000..910bba8dac62474f55492f35d1d57a7fd9e380c4 GIT binary patch literal 605 zcmZuuO-~y!5Pg#@*<{(kl0f(>&_kp`K%`uHp~?Z27NmeGK)IX50>j2D*}EY1)W3v8 zLF$1Yz>h*5FGvW1CC{4~zj^kIAD{j`0NBAw1qBp+cp=76B21rUs{K=pWMA1##Ok*+ z%`HMHJy*8*mCt+c3EKh6sQ3s%j3Xq}FT|B-XQ_(YCu$_kiLjR}@m*<^b_m7QwSIsJ zO!|mIOu35Mdr?9)(MNJ<#C7*d>Xb0M`qABMeS)`}3?*T*r?foGMyKw|)0i{0UNR7I zUl`@$m!#)mL41&Y5Og0^DYNTyEWh?ofRd4RWD% l_}IvWT?O-Aggq>9RKOxWF?#%e6)feM2`n=P%y!S^^&k0Jcqsq? literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/GameVisualizer$2.class b/out/production/java-project/gui/GameVisualizer$2.class new file mode 100644 index 0000000000000000000000000000000000000000..1f77ffbb0fa0340a7246ad7083c4d75983147096 GIT binary patch literal 610 zcmZuuO;6iE5Ph4NI57rHLiuQc_K*Vvi6Dx40dWBFQ7NEGK<-Pjf(2)dyfz0;{3WCU zQV;zB{ZSQf4H81IlIP8g-@Kif{rCURUjSS9T0;qCA6|$dR0Jl@a^2pO1J%_wm$AN4 zX>(PelAUYYT;c!Dd%}8vDr!E05W@%s8W-|fw)0HK?PEPq>9Mqzl-STlXPW}$g~e`w zQH=SBLX5kL`g>6(6LXOCReW;QmzmnRRwfgeTKK4e#jb$2O|rmPM;mpR4^G{^r!h12 zPSTTcSEkyAUaUldD8zSQ|=;DDY@k|Hv+*?lBYejtDSV??WUI9 z;A~;X^y0*7bM`DEP(4&O+fOV92!9%*((PDUt1P~8`&B-Kh$6RtdL@3ts1qCXHi<41 zw3hB6T95GW3eE&=1%kGXPqdTIEaDU+@(VSAY5GH?-9{wOAf$D&KZvfl+WHOgfRR_x opb+{FA8UoMt03=1*u!T=C49jw(c>f5Fjr(oF;5K0cJ1;!0W5%eHvj+t literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/GameVisualizer$3.class b/out/production/java-project/gui/GameVisualizer$3.class new file mode 100644 index 0000000000000000000000000000000000000000..473f833590436106ff0021c4acb4cefe92178db1 GIT binary patch literal 833 zcmZuv+iuf95IvK)apIcRjYCQav|Iw@f(TL{cu1)PQMpKIsYI3cZL&%i9J}(`MdFEH zLV_Uizz6VAh*`I41BoT?%#M%GoVon|^Ya&gmv~%44tX1vizO5Ym2s*%uf;?TlukvU zKFheiO(-NMO4pzA_x?Pf>!65|4adbYTte-GI1?T5De1^F877_mDAn@CNSr1zW~v<( zs$`dtZ!`xER;7Gnt&T(?nmv5p&zm{&;-E0QH}_kGn!{Q zob{<|1QF-1UDY**Avo`&G#<)V%E$kpv+EZMcB6FwMxZ+`pvl(aH7KE#MJi~sbr@sn;O8%1zPRH6 literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/GameVisualizer.class b/out/production/java-project/gui/GameVisualizer.class new file mode 100644 index 0000000000000000000000000000000000000000..95539a51a865b5a4f450bbd595a7f425fd1d830f GIT binary patch literal 5627 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 Zt#>}@TR6&ZnKO{y{wbA8wNitb{{ex70$~6E literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/GameWindow.class b/out/production/java-project/gui/GameWindow.class new file mode 100644 index 0000000000000000000000000000000000000000..71a6d983e4edc006dd05b71f5ccc8660138d4651 GIT binary patch literal 856 zcmZuvU2oD*7=8|86lw*Az`k^Dib{*Fe($1-7bBU`RJUY?W!{(rG}u{MQp!-Ty!0pd zH~at+N#?y*^$!`}GhmMBN!oMXbDsBop7-PD@9)O|wy+ULgke7X6n_2nAv_Mh(AQfH zf6z7zdorS!l@L=PAOaJs_@ zwHNpVHeS+FD-vXeOrvA#kIAKCw>#Xi-&?+n1Qfw>o?)h_RuV`dEn!YU1{WBT6OVn{ zt$SStrTOaU)R`e`P5^&H8WM8EH6?hLyOtwio*{Q4kaq)p%k%4&Z}N9uCy zp=Ft2d7Oy=jv&vt%Nv$&sFgS_QO;#c6hZi0Rt%yh!<|V#4h6oiV{>osg1MLryva4e-%uH zo5&IpZYsDX${%g<+8f%+UY+<;Ch{Xf>#~7$(UY^I~DHR!X95ngV%POA${71 zQKJlo*_NoeXwko&pl5l{>-aTm+ZLfyVkkzQ>jI56(iNpCB~~#ACnqMRgl^W!`iK}J zv~Ow|7Ns@7j5b8#V1RQyB!|cz43Q^mVSq)mq359 z?)x^=$G(=C;uJE&bo$ik^dbC${)s+yrptFF*|FP{sXdZ)&pr2??>n3P^Pe|w0qDh7 zA=C(LT>Sd><;7dKuPokLyvb{!i_32puSwDEt19YHub@GLf{?(v3;K+HF`l0_txWt_ zpXC~krDu;g`m`a?u+OwicfUYKBqjCYS)E#gu0!R-7(dbBMyO~~plMivl>#d=1v8$q zGb5&zwr2&Jrq5;V%%ELxCTOoM#l_OLFHWdvL92qWhE-TCuxc3{ffmQen0ca0$-8AZ zgdQoGOHLA(QQApFhZU?5X!RiLvu=FIxab~q3_XOk0tDQKb&~#iB3g!+PimuvPTVD+ zc?^;^BV)Nl=Le$FDhae#RO_2(P0%^(IeM81=a_6rGH<$U$^v(;gEC)ai%Oun1&2hB{I4(h!RRm(oBB(M~f+ZpB*YJo8L0wLtn395n8cUplmO?JAy9TQ) zK&If3K>I%nw6|bp8B-NWL}iIRs^KX5WH_?f3Laib_c3Jpc-BZX;W$zX`ZWyTM2Sb0 zia^Me+OEwKEJvf@n%TH#g>qUsh0_WKH4Ndgl9ehI7RscaA7EX2IUbWIMl?K*Q4+R1 z@#<2fJ@-L&6r5p61|4$Pa-BI9V|YTtlQ<`!GF$ydKF@*>s6HPwt&E1QVH^`I6+M?T zESAR3<(i1hI?dDxa z&-EMbq@B*UAl6)u1I-P1PsRKAK*5I^KElTWo0odfPXK4s^mtn5LH)cw!PX#$rs>Mn zFO|6o4*7nL>Q*{y`u$<&X8RSr4 zKD0iI<1m@k^LZn$;4@bBzhbf+Jq2F~blzE&9qY#en>Y>YATWm-gyoBuy%d(OEB@9} zuHYHopXKUDG*AMZjfF)WKl7-Kbzetg>^ojXG{+XuHX3f9N5^$+pm0MgergrJ716bT zt)mOrK01%cJi7aP z@z;9zI~h3;aR}QG!4AFxBYdw#aftqpqq~eZLWD2l6%TnTKpvvjt9Xq#U#E?gsQCkJ z3X%#={f;e^zES3|mn;4aff~CB8~7gir3k9z2kb^8V=`TD(bF4X)y?VDDXG TcpLBV`h*gd+MkmDm+1H#p7*Si literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/MainApplicationFrame$1.class b/out/production/java-project/gui/MainApplicationFrame$1.class new file mode 100644 index 0000000000000000000000000000000000000000..b117001b0e0841d39f604839287711a036426831 GIT binary patch literal 754 zcmaJfgc5Ph4vvFp06DW5GVEs#T+N;N$PRg@?dNNI%x3g>OSY8JWc$lf%F6MqSb z4~YXmfFFf;>r}v@;ozCs(VI8(#`E*n_a6YBqq&3{7JPUS7Eu@2JfG;~L~3(19%p(e zt_5b9?Bx!31Y${0~H-uk%SURL9!QyK&ur*>_E-u4jg`&a=rPJajt@-Fmgm^as`l zr>e9s@{&7?UK*o{ZYIl8mDu481Uv^3$LkzbixJ`R!hN8dA7x5Jv|0Lr@!al|XZ(x(w(LSShv_bnb#8<5RB@L_mK71tq5C?yV g1KdZ0)gHE3U&8}z(|f$19XzTst9VQwUUgvj8%6u4w*UYD literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/MainApplicationFrame.class b/out/production/java-project/gui/MainApplicationFrame.class new file mode 100644 index 0000000000000000000000000000000000000000..b6d35b703d6984ff53d27b6d874c7928138c1440 GIT binary patch literal 6141 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 N@=shKE)*@O{x7L#{=@(P literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/MainController.class b/out/production/java-project/gui/MainController.class new file mode 100644 index 0000000000000000000000000000000000000000..10b23995be0ad1b026cbc82fbeb93125ba618c31 GIT binary patch literal 1012 zcmaJwgo~wyhD!`_vnQ){$NV7ewsWXM$D{_sKpY7M-EvHIX$qGiZ3^#|*yTOT zqtuqub6bL8wpgkUQ2|A8QPZIzsf4 zxF;QZ)1_xR3RqTETxD1;UQoYCRca{sbptn4_ahzN`lJ#?10|HnM^|_a*_BO;+7>B( zR0Ft0_WddGL$5kgTrp6^9WqNVHjX@Dw?%u)>A{ECl&b9XxcZ8!9ZNK<5dGi~QtBVjDWxVydl;mMD6MxX+D3#r1GWVDall`jMeM6zTMm`0K$GE~SMtp&{ZLfL?9D3m1B g6FeoU5T1>Ss`wVj#<_1*FOdJkD;s&O`NFHe0U^-Y0{{R3 literal 0 HcmV?d00001 diff --git a/out/production/java-project/gui/RobotsProgram.class b/out/production/java-project/gui/RobotsProgram.class new file mode 100644 index 0000000000000000000000000000000000000000..11ee02a92a19f20dc5cc293ef63459b604d42bba GIT binary patch literal 1473 zcma)6T~iY=6g_DRTh^tmMLlO+OV*|(HdshTn`pQNg zMF(RhgM2`{bwhJ^Yc1riC{mu|4kj>38H8QMFfmt3u)pXk#had}+Bk$M3x^#X!BK{( zq}GN>^`(}c)KWwY`=om7Z;3kBM*d_{?Jl3udyJvj?#jw4m#XF~9r~UpLL1Xan_V{g^MX@>pA{lahhI(i=ZZGtgmYJQ8r`MOl% zX}8l9;hIT{1k`<(d+R)uX5BYt^oFE7#^OMGn5sn8A-SebuM>6J?E(WM*71aEw+{x( z!?q#*3zT6rZp$hU`YJ{}-f6b@tcf>!fzE;X8Ptj4z-}Q1RtjP_{BG!qB^l?pM}FC~ zjn44{pNgYH9;^zz;kTj!hV#RqCZED>2bbg3T^sjs-@<}JH=)KbGdNnk{#NR-KBC}n zxU2nen|jqru6`t2-v{*~E_2oLL^Ny8bvLLc%GIxA!m879PW@4nzolnknPK|hTj?d~)dDA|2`RdkKpM=vJ2al5 zRfT3o^U(Y!upRnIVU9-Q2C^v8==3&V9%pGaf^#@e76XoGHl!0p>oZ0^AX`8C5&OU3 z0Pqb|A^bzySb9E+hW{ literal 0 HcmV?d00001 diff --git a/out/production/java-project/log/LogEntry.class b/out/production/java-project/log/LogEntry.class new file mode 100644 index 0000000000000000000000000000000000000000..6cb702ae300dae8c457794eed6d355f45edeacc0 GIT binary patch literal 651 zcmZuu%TB^j5IwgP3Z+0r@coP%sK$N(#)U>#RTmf%SES%gEh%l%783tT6N!lnKfsSN zPA`ohm?rb;oO5R8etmy@0=U4w3JDnnvW6^j4En$x+oosxj(OJ`@P5pYJ9B+EK4-`@ znwkCGr--QR8oAnXB1hkS~KrQmR<4&u>S=9uM#Bo+q?}zU_7F&`t8RD92B3 zG^ZuTCawHz4t0J3)#35)Hnm1`c?QB#Pr8Fn9Sd8i?O+u4`L&zORI<`bohEm|A>Bfv zSCHtVgNTT(NRJD71Yfnpp_Pq=f7`*SJB1+$BT*75G^%Ah14G&o5C`yO%y@v`nYE#i$X>@ql znlglgf-|(HD@X#9{~e8YQB!c&k}MglD=bc@nnbqidopiB;|ks*fd@Y%hHwSd_TdEd zH6_mn3TIyz&UhbXAKJ&9kE)La3He0hQ`{7?%p8Xb^R@c_=wf5XPJ1hVK&Iw8Nfv)I zJlKzm-Dp3hW%V^B>nB-PsCM#RlO1I;~H68;r06)OLFA^B~RH%9Vj zX-1Q;Ee>ay0yBhH=#`hxZN4RJvyUBo$zSQdNh#esjo(oJ*#KS+x?n1d8+XPPDuLYT zBzV*G3N$M2-%wp^1S{;?BY0ug8F6`CcZ8X+>y1zeyZ#8L!&j;FaR=>5zMr^AdG7zk zY}NNI>nW~2fn~I7wrw=eXdgO`(E_7=wD6a-a-5EeLaTiejai<(&&zp`>$&pQI)Ny9XpDS<#Dxu_r_(C!9R9HTgX(YCeC zoKbe7P!N?MO#;D0Ho4e{X0#}1RdE0Zd8TL;#&cHTx?!$bcjv8&o!14TrR9=dE^7t7 zEYOkL2R9>u0}||ziVlg?R9Y@Fp>FDSS$^zN(Ty1CX{)OQNq8uAC1jE}+8D7 zfr+pR*Q!*ln#;2;$FuC%v)+8lUhInMTbYXLascX%dMdD&Z_HT8mXpO<+ZEbnnq^-k zQMRtJ>}a+#V_PL6=dFrKUnsmV^m_}IoPwG|UOTvt0|HvHD9~B;>1*N4GqmrAeQ=`Q zMKxncGaTY9)oVQ_`@zv~<`oJA&?av>2)xf#11@pR`>M8{q2YP|@SDOt-jn?OfUD0C zbkFyub|6wupe)6A(6|NFecwUb7TO=Wh#&H|jnP0Cf4iA2hB$hVLeI$a`-seqJRg1bka4_Li46Yrxz7M( z_D=E!4)be2vk$Poqd0=WItKkU2L1RLSDE<}p6EuyE5h*qOtXR^h4@0j{9j}vaP8mt z9saNUj+0-K{8HpMOnxK(i{B!SdHoX^@@-@_n@=#XG(56{!8x{29d%py2tDawEcgNw zZgxY(DSNkP=}EVeToeToGAbO~OrF$EPe_?k(X4vqxd!CM_FahFkcY z<_Nk1_apQY(+UO@j8NW7uDZ%gG;uA&pVVH+e>`3z`6i7CL}dH6apFh5H@F51yZc^+ zsu$z45%>bjjFKbs4f9JQ568blOWX(f9?E09{UF|Z%inm6^pt#!_if|C1BQF8@+Rmq zS~(x>^xgmqmu*OSkhS86S)iOCrh&${21Z7)!nc51GN-mR;Lm!VajVdMdgENlb0L{s ZCa$mTnw!k4E#xQjE{rdEsNhDg{SDlI0@(ln literal 0 HcmV?d00001 diff --git a/out/production/java-project/log/Logger.class b/out/production/java-project/log/Logger.class new file mode 100644 index 0000000000000000000000000000000000000000..79b89bfd02113ac97d2d5d0afff9052950d7a04a GIT binary patch literal 854 zcmZ`%U2oGs5S&Zmx^bK|O`8@<`78w|KqJHxO2q>dBqRe5ML|4X;={Nyc6D*e--04h z2_$|1KMFDDIMCAI2m5w>J3F(xKYxAu0pKxq9F$PDQE_2mL7;gck7O^FN!WWeJW!)d zU|}~(qU@1C+3O6dSVYx^PEO*C@qRkdBPG!Giwkd}BuGC_ z;eHhjEZJzfSVl|0E$;a0NW}uyo*GUt2{hZNg%N0 zoz3?D`r6NQl!SfbrGX6>my8DMsn)4BH7=V@ToI^v&pQKto}>YdEcsEQUQRv?m3}RU zF_D&^j$}NLIx=wqRriET z=eoS^b!G+6^jTnWcN7=XbEeII78&t1&WPG}Oex&wOiSDbfekZNo-D>(2O?J)J>XXu zw0i>anTHat@ohE-;Oa2_I#2HO5^i9NQ583_T@XA(IsaEXhJB2B_bXQZrEy7DKSfi+ zE!@s&y#LT#oJX@vn$}#J4!VV!&0Gsmp_)%DA#yjyEU-o|cm5dPrf&1pzhm`nGdRKK R7uZJm=@g66U1BBN`winKpvwRN literal 0 HcmV?d00001 diff --git a/robots/src/gui/MainController.java b/robots/src/gui/MainController.java new file mode 100644 index 000000000..91d1a99c0 --- /dev/null +++ b/robots/src/gui/MainController.java @@ -0,0 +1,29 @@ +package gui; + +import java.awt.*; + +import log.Logger; + +public class MainController { + private final LogWindow logWindow; + private final GameWindow gameWindow; + + public MainController() { + this.logWindow = new LogWindow(Logger.getDefaultLogSource()); + this.gameWindow = new GameWindow(); + } + + public MainApplicationFrame createFrame() { + MainApplicationFrame frame = new MainApplicationFrame(logWindow, gameWindow); + frame.pack(); + frame.setVisible(true); + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + return frame; + } + + + private void handleExit() { + // логика выхода + } + +} From 3929ac37c5d626dcceed555083d457213b9fbbc5 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 16 Apr 2025 10:04:51 +0500 Subject: [PATCH 06/18] do task1 --- .../gui/MainApplicationFrame$1.class | Bin 754 -> 754 bytes .../gui/MainApplicationFrame.class | Bin 6141 -> 6558 bytes .../java-project/gui/MainController.class | Bin 1012 -> 1188 bytes robots/src/gui/MainApplicationFrame.java | 80 ++++++++++-------- robots/src/gui/MainController.java | 9 +- robots/src/gui/RobotsProgram.java | 2 - 6 files changed, 49 insertions(+), 42 deletions(-) diff --git a/out/production/java-project/gui/MainApplicationFrame$1.class b/out/production/java-project/gui/MainApplicationFrame$1.class index b117001b0e0841d39f604839287711a036426831..fce8218f9aa4172327e47082504759e951519776 100644 GIT binary patch delta 23 ecmeyw`iXTz028C`H(0 zubesqpi#60QGh}XMLLQxNg%Y>*l+aLrTVNySKXFPNh59wOlq(amUD?fVRcQ1hJe7# zylETE)IP`V*$vUQ>jFY>1t-4mjO04hciCGcDvFwB=xip$vDlog{ zY+~!B$f-I)m?lsXv%7X#iKyKtP}U-aw~P*`dDC^wz&QfJE}|cuSgs~so*hv$XX%)Y zIh+}>6Hd~O#muBYg_q#0j;{3KhnHX)az)#I)N#CFWqM*97zj- zbEKD+Te3@L zjZrwdLT1Pn0(1OSc0tnYlw%~Elyp>^j&|&%W(xHp-W0P_=JppC%yTI>QL1?!xJJk8aV>e4^<0aUVvr>77x^M&?q}fYT-c*Cl!)tL zXxO78B7-$KFZWyrwb*Wg2XQ?vlYcsObV-(KlBHhCSUUD%pUaX~W>dU3?#9^9k}NGf z#c>@8nSMn*Mr2Z@eP53&m7t?|ee!~qma_S~xD zt#}(9$h0SqH(4>oWoe8HD38cw@d4Z>jd_Pa^#r{2tQfnf6u0ZRL+Y9C>S?jh$ND`blmMj(r%_4`AWmRWZ5_y0=Q2gka>zxI++;`;vPI8xw~J(LsT+udb4B3 z19+HD%G^70XyjJL_;?Tx;(-u1ufsatgGZUoMnvYz4l~(lC*vj~RsU*vkSjwj$=9pZ zS&~cfkL!2>Pr6x>|9YY<$)BO9a}VAtz5PCcl@oYdS~Zc!)p!8!m&AT7Gnh$dhBBus zJ$@fm)J}8w+04+$T^c^XnkpTpO1NvvR&!vZOkC;L59#=@tS_=?wI03RbD+DrdujeYN#?!`ZF>=4(vZp})v){PsP2&4^R)bB8zL)jQ=OZzzDTl8Zhx3EL0m>uex0 zhh;Sm;G0w|Y$k4c+JX0ytoC9i*cGF8I<>RFRd|Tk$%%k+oaSo^u zkU3J242ks7XpP7m(ePa_Ke9zF2QY~5;QKm$fFCl)Q{8qS>ECH3;~Uu2+1wEtJWt5h zELYUW`@%Qk?HkQC%|ZMaKhf}09Y2%#=QepRp$53s#u*y3-(rrwh?jKyLeg9|OTN+? z#INvc4ZqRxTl{X!?$OrA?P;eYlhQKTdrj}{iE;zTqHJdyxU+d|yOrInxVQX4pih0;Vla3knS)E-F#6R#)4gb>dZ}mko+WW{FHQJ+>*@^X0uI_4O0V9c}H~*vK75rDA zij}P?X{S;US~rcT70y>o{>M%YiBqm(3x#rrj4H?C&*-xJ0m$geuCOE>6ci3VarYP!!6p%VUaWt`1 zU|KG(vTP>om=WI-HLBbeYP3PBTEpGIS7-dqh}y*2Nboz1NL(lTwt2VVa3=}O&lB&X zqjYlB>ergEYAnFfUb1Q>z1U{=CL^l76qq&9cf|^6GP{gz%7c=aBwl%=Z96F^Y4o(3 zPPZLRm5b`KVsW0#i}Q7{Ts>VVpDxnHGWB$^e5%()t$JD~pDxkGxqO-=E(?nFqEQn~ zy4WB#vIWbz*-GrU_nCDq%EMGC_pgb<~Cx|uCX z5wDBGCm_PZ&~~3d$smH^+Ch|umkpvKynGNd!)eSt%4r2c=im7}I0B|~;WUbzfeI>` zg_#_mg+-VxCi89B6)UC)sgw#7ETQfsFbQ_CC?~W+-t(-+12iHJrTDHZ96pZnG!~Sv zZWzMiG-_JIbLK2Nj^%TTyQ93Wk=HaXkn@6RT+BZ6CHBW9VEb`2YDRY6U+VWsIVP97}RV+CAe*+uf~#nZf%bEMPD zq`#=6Z&z(m8gI-gnW7A7LsaZv{ePwwR*~+ z-gW}R3KGw82}zAUr$)CeC(w`kfi52dH%y=);exmt<+z3!b}b2c9qJGz2~5&*FC(!J zS0JuTaPzJ$YeKV_t4vse6=I$;p&m2EeBQ~t<8gpz%pEjEy7NM1%qLu9+DDD~)Tl9^ z$rE+$AV2huh9N}rhGEVyD9 z9E!vW8d)If#7bU^D5yiM;vJJkT*?To7HjzH-d&KrTbsRW;N2$9mxl!%yz)m}E}F$w G%=#aa2?`wm delta 3135 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 diff --git a/out/production/java-project/gui/MainController.class b/out/production/java-project/gui/MainController.class index 10b23995be0ad1b026cbc82fbeb93125ba618c31..1945a26d0e536badeaffd7ba9495422bbe386413 100644 GIT binary patch delta 431 zcmYjMJ5Rz;7(KUQ)q<}g7%?hwGB`9U;salRPL|2Z#aPqYl#n(l;Ob*?)1y*oe>)o=_!623yCjAG$pmNGQ<|tl6Ijf zWz9B~qpEA!X4d;;k7J{bozr#IF^fi}qM3$wFC2zLAS6VJYu<;TsOuz5Mu=jVVub2p z%wPl?G>Om^FpEuODKl(go8zcHCk}z~{2S(uQ!kL|Pp7=ozQiRbjMEwzrzazZC=!@J zk}6Ib?*O}`{ALHcM9Z+(kwrJ@b`Oa1(koUPG!ejgr8aho*c1N*id`-NIf%as7wMd< UXFW7G&F%E8u|I2h+6XB80C*ZmQ~&?~ delta 256 zcmYk0yAAzMUP#ekAc49yrWmLSFb2<>Sv@_1@$oUd(E@?0Z1Z2S_Wz4sAXh5 ortRN-nF+dv7?CP5_EYh)!P1|FOOen>9T+J5#S*_*6VEmM0L|GOWB>pF diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 76e29b9b1..134c900ba 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -14,12 +14,14 @@ public class MainApplicationFrame extends JFrame { private final LogWindow logWindow; private final GameWindow gameWindow; + private final MainController controller; private final JDesktopPane desktopPane = new JDesktopPane(); - public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow) { + public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainController mainController) { this.logWindow = logWindow; this.gameWindow = gameWindow; + this.controller = mainController; initialize(); } @@ -64,60 +66,64 @@ protected void addWindow(JInternalFrame frame) desktopPane.add(frame); frame.setVisible(true); } - - private JMenuBar generateMenuBar() - { + + private JMenuBar generateMenuBar() { JMenuBar menuBar = new JMenuBar(); + menuBar.add(createFileMenu()); + menuBar.add(createLookAndFeelMenu()); + menuBar.add(createTestMenu()); + return menuBar; + } + + private JMenu createFileMenu() { + JMenu fileMenu = new JMenu("Файл"); + JMenuItem exitItem = new JMenuItem("Выход"); + + exitItem.addActionListener(e -> handleExit()); + fileMenu.add(exitItem); + return fileMenu; + } + + private JMenu createLookAndFeelMenu() { JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); lookAndFeelMenu.getAccessibleContext().setAccessibleDescription("Управление режимом отображения приложения"); - { - JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemLookAndFeel.addActionListener((_) -> { - setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - invalidate(); - }); - lookAndFeelMenu.add(systemLookAndFeel); - } + JMenuItem systemItem = new JMenuItem("Системная схема", KeyEvent.VK_S); + systemItem.addActionListener(e -> { + setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + invalidate(); + }); + + JMenuItem crossItem = new JMenuItem("Универсальная схема", KeyEvent.VK_S); + crossItem.addActionListener(e -> { + setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + invalidate(); + }); + + lookAndFeelMenu.add(systemItem); + lookAndFeelMenu.add(crossItem); + + return lookAndFeelMenu; + } - { - JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossplatformLookAndFeel.addActionListener((_) -> { - setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(crossplatformLookAndFeel); - } + private JMenu createTestMenu() { JMenu testMenu = new JMenu("Тесты"); testMenu.setMnemonic(KeyEvent.VK_T); testMenu.getAccessibleContext().setAccessibleDescription("Тестовые команды"); { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); - addLogMessageItem.addActionListener((_) -> Logger.debug("Новая строка")); + addLogMessageItem.addActionListener(e -> controller.onAddLogMessage()); testMenu.add(addLogMessageItem); } - JMenu fileMenu = new JMenu("Файл"); - JMenuItem exitItem = new JMenuItem("Выход"); - - exitItem.addActionListener(e -> handleExit()); - - - - fileMenu.add(exitItem); - menuBar.add(fileMenu); - - - - menuBar.add(lookAndFeelMenu); - menuBar.add(testMenu); - return menuBar; + return testMenu; } + private void handleExit() { UIManager.put("OptionPane.yesButtonText", "Да"); UIManager.put("OptionPane.noButtonText", "Нет"); @@ -130,7 +136,7 @@ private void handleExit() { ); if (choice == JOptionPane.YES_OPTION) { - System.exit(0); + controller.handleExit(); } } diff --git a/robots/src/gui/MainController.java b/robots/src/gui/MainController.java index 91d1a99c0..b4d92f445 100644 --- a/robots/src/gui/MainController.java +++ b/robots/src/gui/MainController.java @@ -14,16 +14,19 @@ public MainController() { } public MainApplicationFrame createFrame() { - MainApplicationFrame frame = new MainApplicationFrame(logWindow, gameWindow); + MainApplicationFrame frame = new MainApplicationFrame(logWindow, gameWindow, this); frame.pack(); frame.setVisible(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); return frame; } + public void onAddLogMessage() { + Logger.debug("Новая строка"); + } - private void handleExit() { - // логика выхода + public void handleExit() { + System.exit(0); } } diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/gui/RobotsProgram.java index 29c5353e7..4824933c3 100644 --- a/robots/src/gui/RobotsProgram.java +++ b/robots/src/gui/RobotsProgram.java @@ -1,7 +1,5 @@ package gui; -import java.awt.Frame; - import javax.swing.SwingUtilities; import javax.swing.UIManager; From 9723d0a97c16f35c07d62e1b0d60abb29d3ce2a5 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Thu, 17 Apr 2025 14:56:23 +0500 Subject: [PATCH 07/18] task2 and fixed task1 --- .gitignore | 38 ++++++-- .../java-project/gui/GameVisualizer$1.class | Bin 605 -> 0 bytes .../java-project/gui/GameVisualizer$2.class | Bin 610 -> 0 bytes .../java-project/gui/GameVisualizer$3.class | Bin 833 -> 0 bytes .../java-project/gui/GameVisualizer.class | Bin 5627 -> 0 bytes .../java-project/gui/GameWindow.class | Bin 856 -> 0 bytes .../java-project/gui/LogWindow.class | Bin 2580 -> 0 bytes .../gui/MainApplicationFrame$1.class | Bin 754 -> 0 bytes .../gui/MainApplicationFrame.class | Bin 6558 -> 0 bytes .../java-project/gui/MainController.class | Bin 1188 -> 0 bytes .../java-project/gui/RobotsProgram.class | Bin 1473 -> 0 bytes .../java-project/log/LogChangeListener.class | Bin 148 -> 0 bytes .../java-project/log/LogEntry.class | Bin 651 -> 0 bytes .../java-project/log/LogLevel.class | Bin 1390 -> 0 bytes .../java-project/log/LogWindowSource.class | Bin 2463 -> 0 bytes out/production/java-project/log/Logger.class | Bin 854 -> 0 bytes robots/.classpath | 6 -- robots/.project | 17 ---- .../main/java/robots}/gui/GameVisualizer.java | 2 +- .../main/java/robots}/gui/GameWindow.java | 2 +- .../main/java/robots}/gui/LogWindow.java | 8 +- .../robots}/gui/MainApplicationFrame.java | 87 ++++++++++++++++-- .../main/java/robots}/gui/MainController.java | 12 ++- .../main/java/robots}/gui/RobotsProgram.java | 11 ++- src/main/java/robots/gui/WindowConfig.java | 9 ++ .../java/robots}/log/LogChangeListener.java | 2 +- .../main/java/robots}/log/LogEntry.java | 2 +- .../main/java/robots}/log/LogLevel.java | 2 +- .../java/robots}/log/LogWindowSource.java | 3 +- .../main/java/robots}/log/Logger.java | 2 +- 30 files changed, 141 insertions(+), 62 deletions(-) delete mode 100644 out/production/java-project/gui/GameVisualizer$1.class delete mode 100644 out/production/java-project/gui/GameVisualizer$2.class delete mode 100644 out/production/java-project/gui/GameVisualizer$3.class delete mode 100644 out/production/java-project/gui/GameVisualizer.class delete mode 100644 out/production/java-project/gui/GameWindow.class delete mode 100644 out/production/java-project/gui/LogWindow.class delete mode 100644 out/production/java-project/gui/MainApplicationFrame$1.class delete mode 100644 out/production/java-project/gui/MainApplicationFrame.class delete mode 100644 out/production/java-project/gui/MainController.class delete mode 100644 out/production/java-project/gui/RobotsProgram.class delete mode 100644 out/production/java-project/log/LogChangeListener.class delete mode 100644 out/production/java-project/log/LogEntry.class delete mode 100644 out/production/java-project/log/LogLevel.class delete mode 100644 out/production/java-project/log/LogWindowSource.class delete mode 100644 out/production/java-project/log/Logger.class delete mode 100644 robots/.classpath delete mode 100644 robots/.project rename {robots/src => src/main/java/robots}/gui/GameVisualizer.java (99%) rename {robots/src => src/main/java/robots}/gui/GameWindow.java (96%) rename {robots/src => src/main/java/robots}/gui/LogWindow.java (91%) rename {robots/src => src/main/java/robots}/gui/MainApplicationFrame.java (61%) rename {robots/src => src/main/java/robots}/gui/MainController.java (68%) rename {robots/src => src/main/java/robots}/gui/RobotsProgram.java (56%) create mode 100644 src/main/java/robots/gui/WindowConfig.java rename {robots/src => src/main/java/robots}/log/LogChangeListener.java (76%) rename {robots/src => src/main/java/robots}/log/LogEntry.java (95%) rename {robots/src => src/main/java/robots}/log/LogLevel.java (93%) rename {robots/src => src/main/java/robots}/log/LogWindowSource.java (99%) rename {robots/src => src/main/java/robots}/log/Logger.java (96%) diff --git a/.gitignore b/.gitignore index 56ad388cd..028bd3cdc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,29 @@ -/.metadata -/robots/.settings -/robots/bin -eclipse.bat -.idea -/robots/src/.classpath -/robots/src/.project -./simple.txt -./my.txt \ No newline at end of file +# IntelliJ IDEA +.idea/ +*.iml +*.iws + +# Eclipse +.classpath +.project +.settings/ + +# VS Code +.vscode/ + +# Build output +/out/ +target/ +bin/ + +# Logs and temporary files +*.log +*.tmp + +# OS junk +.DS_Store +Thumbs.db + +# Personal/test files +my.txt +/net/ diff --git a/out/production/java-project/gui/GameVisualizer$1.class b/out/production/java-project/gui/GameVisualizer$1.class deleted file mode 100644 index 910bba8dac62474f55492f35d1d57a7fd9e380c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 605 zcmZuuO-~y!5Pg#@*<{(kl0f(>&_kp`K%`uHp~?Z27NmeGK)IX50>j2D*}EY1)W3v8 zLF$1Yz>h*5FGvW1CC{4~zj^kIAD{j`0NBAw1qBp+cp=76B21rUs{K=pWMA1##Ok*+ z%`HMHJy*8*mCt+c3EKh6sQ3s%j3Xq}FT|B-XQ_(YCu$_kiLjR}@m*<^b_m7QwSIsJ zO!|mIOu35Mdr?9)(MNJ<#C7*d>Xb0M`qABMeS)`}3?*T*r?foGMyKw|)0i{0UNR7I zUl`@$m!#)mL41&Y5Og0^DYNTyEWh?ofRd4RWD% l_}IvWT?O-Aggq>9RKOxWF?#%e6)feM2`n=P%y!S^^&k0Jcqsq? diff --git a/out/production/java-project/gui/GameVisualizer$2.class b/out/production/java-project/gui/GameVisualizer$2.class deleted file mode 100644 index 1f77ffbb0fa0340a7246ad7083c4d75983147096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 610 zcmZuuO;6iE5Ph4NI57rHLiuQc_K*Vvi6Dx40dWBFQ7NEGK<-Pjf(2)dyfz0;{3WCU zQV;zB{ZSQf4H81IlIP8g-@Kif{rCURUjSS9T0;qCA6|$dR0Jl@a^2pO1J%_wm$AN4 zX>(PelAUYYT;c!Dd%}8vDr!E05W@%s8W-|fw)0HK?PEPq>9Mqzl-STlXPW}$g~e`w zQH=SBLX5kL`g>6(6LXOCReW;QmzmnRRwfgeTKK4e#jb$2O|rmPM;mpR4^G{^r!h12 zPSTTcSEkyAUaUldD8zSQ|=;DDY@k|Hv+*?lBYejtDSV??WUI9 z;A~;X^y0*7bM`DEP(4&O+fOV92!9%*((PDUt1P~8`&B-Kh$6RtdL@3ts1qCXHi<41 zw3hB6T95GW3eE&=1%kGXPqdTIEaDU+@(VSAY5GH?-9{wOAf$D&KZvfl+WHOgfRR_x opb+{FA8UoMt03=1*u!T=C49jw(c>f5Fjr(oF;5K0cJ1;!0W5%eHvj+t diff --git a/out/production/java-project/gui/GameVisualizer$3.class b/out/production/java-project/gui/GameVisualizer$3.class deleted file mode 100644 index 473f833590436106ff0021c4acb4cefe92178db1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 833 zcmZuv+iuf95IvK)apIcRjYCQav|Iw@f(TL{cu1)PQMpKIsYI3cZL&%i9J}(`MdFEH zLV_Uizz6VAh*`I41BoT?%#M%GoVon|^Ya&gmv~%44tX1vizO5Ym2s*%uf;?TlukvU zKFheiO(-NMO4pzA_x?Pf>!65|4adbYTte-GI1?T5De1^F877_mDAn@CNSr1zW~v<( zs$`dtZ!`xER;7Gnt&T(?nmv5p&zm{&;-E0QH}_kGn!{Q zob{<|1QF-1UDY**Avo`&G#<)V%E$kpv+EZMcB6FwMxZ+`pvl(aH7KE#MJi~sbr@sn;O8%1zPRH6 diff --git a/out/production/java-project/gui/GameVisualizer.class b/out/production/java-project/gui/GameVisualizer.class deleted file mode 100644 index 95539a51a865b5a4f450bbd595a7f425fd1d830f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5627 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 Zt#>}@TR6&ZnKO{y{wbA8wNitb{{ex70$~6E diff --git a/out/production/java-project/gui/GameWindow.class b/out/production/java-project/gui/GameWindow.class deleted file mode 100644 index 71a6d983e4edc006dd05b71f5ccc8660138d4651..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 856 zcmZuvU2oD*7=8|86lw*Az`k^Dib{*Fe($1-7bBU`RJUY?W!{(rG}u{MQp!-Ty!0pd zH~at+N#?y*^$!`}GhmMBN!oMXbDsBop7-PD@9)O|wy+ULgke7X6n_2nAv_Mh(AQfH zf6z7zdorS!l@L=PAOaJs_@ zwHNpVHeS+FD-vXeOrvA#kIAKCw>#Xi-&?+n1Qfw>o?)h_RuV`dEn!YU1{WBT6OVn{ zt$SStrTOaU)R`e`P5^&H8WM8EH6?hLyOtwio*{Q4kaq)p%k%4&Z}N9uCy zp=Ft2d7Oy=jv&vt%Nv$&sFgS_QO;#c6hZi0Rt%yh!<|V#4h6oiV{>osg1MLryva4e-%uH zo5&IpZYsDX${%g<+8f%+UY+<;Ch{Xf>#~7$(UY^I~DHR!X95ngV%POA${71 zQKJlo*_NoeXwko&pl5l{>-aTm+ZLfyVkkzQ>jI56(iNpCB~~#ACnqMRgl^W!`iK}J zv~Ow|7Ns@7j5b8#V1RQyB!|cz43Q^mVSq)mq359 z?)x^=$G(=C;uJE&bo$ik^dbC${)s+yrptFF*|FP{sXdZ)&pr2??>n3P^Pe|w0qDh7 zA=C(LT>Sd><;7dKuPokLyvb{!i_32puSwDEt19YHub@GLf{?(v3;K+HF`l0_txWt_ zpXC~krDu;g`m`a?u+OwicfUYKBqjCYS)E#gu0!R-7(dbBMyO~~plMivl>#d=1v8$q zGb5&zwr2&Jrq5;V%%ELxCTOoM#l_OLFHWdvL92qWhE-TCuxc3{ffmQen0ca0$-8AZ zgdQoGOHLA(QQApFhZU?5X!RiLvu=FIxab~q3_XOk0tDQKb&~#iB3g!+PimuvPTVD+ zc?^;^BV)Nl=Le$FDhae#RO_2(P0%^(IeM81=a_6rGH<$U$^v(;gEC)ai%Oun1&2hB{I4(h!RRm(oBB(M~f+ZpB*YJo8L0wLtn395n8cUplmO?JAy9TQ) zK&If3K>I%nw6|bp8B-NWL}iIRs^KX5WH_?f3Laib_c3Jpc-BZX;W$zX`ZWyTM2Sb0 zia^Me+OEwKEJvf@n%TH#g>qUsh0_WKH4Ndgl9ehI7RscaA7EX2IUbWIMl?K*Q4+R1 z@#<2fJ@-L&6r5p61|4$Pa-BI9V|YTtlQ<`!GF$ydKF@*>s6HPwt&E1QVH^`I6+M?T zESAR3<(i1hI?dDxa z&-EMbq@B*UAl6)u1I-P1PsRKAK*5I^KElTWo0odfPXK4s^mtn5LH)cw!PX#$rs>Mn zFO|6o4*7nL>Q*{y`u$<&X8RSr4 zKD0iI<1m@k^LZn$;4@bBzhbf+Jq2F~blzE&9qY#en>Y>YATWm-gyoBuy%d(OEB@9} zuHYHopXKUDG*AMZjfF)WKl7-Kbzetg>^ojXG{+XuHX3f9N5^$+pm0MgergrJ716bT zt)mOrK01%cJi7aP z@z;9zI~h3;aR}QG!4AFxBYdw#aftqpqq~eZLWD2l6%TnTKpvvjt9Xq#U#E?gsQCkJ z3X%#={f;e^zES3|mn;4aff~CB8~7gir3k9z2kb^8V=`TD(bF4X)y?VDDXG TcpLBV`h*gd+MkmDm+1H#p7*Si diff --git a/out/production/java-project/gui/MainApplicationFrame$1.class b/out/production/java-project/gui/MainApplicationFrame$1.class deleted file mode 100644 index fce8218f9aa4172327e47082504759e951519776..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 754 zcmaJfgc5Ph4vvFp06TRvM-S|Eos2-2K`DoT_Jq_jc;h4VIEHCwss$lf%F6MqSb z4~YXmfFFf;>r}v@;ozCs(VI8(#`E*n_a6XWpuU6(7JPUS7Eu-0I-BU$vDD^pJWlmc zTAi7rTwbVpTcB!3x~T6H)t?9Jgb1+YBaE<&NT7BuFJ((kZA)D$V_WaENwVo-BF9$c zWPGNLwg&7i1A3PUn~%RhG{3?BRAO$@ zRv~Dg;1=!e8H)Z6U&NPe{F96q3HulmyooJZNBf-K(FV=W5MQzKmozN%`|#2JhdB5{ g9N->mtoE?Y`U>u2hu-7;?BZdWS;Zsz@TvpD-$-kxy#N3J diff --git a/out/production/java-project/gui/MainApplicationFrame.class b/out/production/java-project/gui/MainApplicationFrame.class deleted file mode 100644 index 9fb2ab869302c0e7468375568fb3dba4a52dabb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6558 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 G%=#aa2?`wm diff --git a/out/production/java-project/gui/MainController.class b/out/production/java-project/gui/MainController.class deleted file mode 100644 index 1945a26d0e536badeaffd7ba9495422bbe386413..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1188 zcmaJ>*-qO~5Ir}91dJgN_CVRXWobzlN|(@uwW<`_2T&^db`xLBrN%~%Q+RCq1O0;j z1FhHu5+Bf~76 z(w=v0&vh(Im2D;TDl$VPdx32xj6sGD<$KMy#JPk4G%4U=9oH~IBFy?3^~6VLL=(gq z5j-zEyS;760{5h2FS(SaVH6We#dU`1_@(NXp?v!y{Y)aKAa3for6v;G=7o>S5!aDG zlDHLxmy<=Ax2ToD_y;wVJ0!`U9N+QMbrzF4(zr(gC}VNg6Sg6Y6_0y<-kU_O1rKN# zK<=a^0OXX|jGnpslJvG)T9gi^0&}@i&$zX$D zV*d+@IQFbz(EcrpVv(B^u5EDJu*Bl7r2W>a+qWcDKf5o^Vp7S)IBiCNK9>NZYU$`L zs@8;_K@bOo=>C|jRo@0il1E_4Q-s%!(Rzf)0it9LtQ{eCfT15g(i0ygNcT3%(h0Gh zFgx&+JUZbK3Z5ZDPlg#huT@y5YKqCkDMr_l`-HoXA*wc>O&#J!DtL(7sm{lO+OV*|(HdshTn`pQNg zMF(RhgM2`{bwhJ^Yc1riC{mu|4kj>38H8QMFfmt3u)pXk#had}+Bk$M3x^#X!BK{( zq}GN>^`(}c)KWwY`=om7Z;3kBM*d_{?Jl3udyJvj?#jw4m#XF~9r~UpLL1Xan_V{g^MX@>pA{lahhI(i=ZZGtgmYJQ8r`MOl% zX}8l9;hIT{1k`<(d+R)uX5BYt^oFE7#^OMGn5sn8A-SebuM>6J?E(WM*71aEw+{x( z!?q#*3zT6rZp$hU`YJ{}-f6b@tcf>!fzE;X8Ptj4z-}Q1RtjP_{BG!qB^l?pM}FC~ zjn44{pNgYH9;^zz;kTj!hV#RqCZED>2bbg3T^sjs-@<}JH=)KbGdNnk{#NR-KBC}n zxU2nen|jqru6`t2-v{*~E_2oLL^Ny8bvLLc%GIxA!m879PW@4nzolnknPK|hTj?d~)dDA|2`RdkKpM=vJ2al5 zRfT3o^U(Y!upRnIVU9-Q2C^v8==3&V9%pGaf^#@e76XoGHl!0p>oZ0^AX`8C5&OU3 z0Pqb|A^bzySb9E+hW{ diff --git a/out/production/java-project/log/LogEntry.class b/out/production/java-project/log/LogEntry.class deleted file mode 100644 index 6cb702ae300dae8c457794eed6d355f45edeacc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 651 zcmZuu%TB^j5IwgP3Z+0r@coP%sK$N(#)U>#RTmf%SES%gEh%l%783tT6N!lnKfsSN zPA`ohm?rb;oO5R8etmy@0=U4w3JDnnvW6^j4En$x+oosxj(OJ`@P5pYJ9B+EK4-`@ znwkCGr--QR8oAnXB1hkS~KrQmR<4&u>S=9uM#Bo+q?}zU_7F&`t8RD92B3 zG^ZuTCawHz4t0J3)#35)Hnm1`c?QB#Pr8Fn9Sd8i?O+u4`L&zORI<`bohEm|A>Bfv zSCHtVgNTT(NRJD71Yfnpp_Pq=f7`*SJB1+$BT*75G^%Ah14G&o5C`yO%y@v`nYE#i$X>@ql znlglgf-|(HD@X#9{~e8YQB!c&k}MglD=bc@nnbqidopiB;|ks*fd@Y%hHwSd_TdEd zH6_mn3TIyz&UhbXAKJ&9kE)La3He0hQ`{7?%p8Xb^R@c_=wf5XPJ1hVK&Iw8Nfv)I zJlKzm-Dp3hW%V^B>nB-PsCM#RlO1I;~H68;r06)OLFA^B~RH%9Vj zX-1Q;Ee>ay0yBhH=#`hxZN4RJvyUBo$zSQdNh#esjo(oJ*#KS+x?n1d8+XPPDuLYT zBzV*G3N$M2-%wp^1S{;?BY0ug8F6`CcZ8X+>y1zeyZ#8L!&j;FaR=>5zMr^AdG7zk zY}NNI>nW~2fn~I7wrw=eXdgO`(E_7=wD6a-a-5EeLaTiejai<(&&zp`>$&pQI)Ny9XpDS<#Dxu_r_(C!9R9HTgX(YCeC zoKbe7P!N?MO#;D0Ho4e{X0#}1RdE0Zd8TL;#&cHTx?!$bcjv8&o!14TrR9=dE^7t7 zEYOkL2R9>u0}||ziVlg?R9Y@Fp>FDSS$^zN(Ty1CX{)OQNq8uAC1jE}+8D7 zfr+pR*Q!*ln#;2;$FuC%v)+8lUhInMTbYXLascX%dMdD&Z_HT8mXpO<+ZEbnnq^-k zQMRtJ>}a+#V_PL6=dFrKUnsmV^m_}IoPwG|UOTvt0|HvHD9~B;>1*N4GqmrAeQ=`Q zMKxncGaTY9)oVQ_`@zv~<`oJA&?av>2)xf#11@pR`>M8{q2YP|@SDOt-jn?OfUD0C zbkFyub|6wupe)6A(6|NFecwUb7TO=Wh#&H|jnP0Cf4iA2hB$hVLeI$a`-seqJRg1bka4_Li46Yrxz7M( z_D=E!4)be2vk$Poqd0=WItKkU2L1RLSDE<}p6EuyE5h*qOtXR^h4@0j{9j}vaP8mt z9saNUj+0-K{8HpMOnxK(i{B!SdHoX^@@-@_n@=#XG(56{!8x{29d%py2tDawEcgNw zZgxY(DSNkP=}EVeToeToGAbO~OrF$EPe_?k(X4vqxd!CM_FahFkcY z<_Nk1_apQY(+UO@j8NW7uDZ%gG;uA&pVVH+e>`3z`6i7CL}dH6apFh5H@F51yZc^+ zsu$z45%>bjjFKbs4f9JQ568blOWX(f9?E09{UF|Z%inm6^pt#!_if|C1BQF8@+Rmq zS~(x>^xgmqmu*OSkhS86S)iOCrh&${21Z7)!nc51GN-mR;Lm!VajVdMdgENlb0L{s ZCa$mTnw!k4E#xQjE{rdEsNhDg{SDlI0@(ln diff --git a/out/production/java-project/log/Logger.class b/out/production/java-project/log/Logger.class deleted file mode 100644 index 79b89bfd02113ac97d2d5d0afff9052950d7a04a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 854 zcmZ`%U2oGs5S&Zmx^bK|O`8@<`78w|KqJHxO2q>dBqRe5ML|4X;={Nyc6D*e--04h z2_$|1KMFDDIMCAI2m5w>J3F(xKYxAu0pKxq9F$PDQE_2mL7;gck7O^FN!WWeJW!)d zU|}~(qU@1C+3O6dSVYx^PEO*C@qRkdBPG!Giwkd}BuGC_ z;eHhjEZJzfSVl|0E$;a0NW}uyo*GUt2{hZNg%N0 zoz3?D`r6NQl!SfbrGX6>my8DMsn)4BH7=V@ToI^v&pQKto}>YdEcsEQUQRv?m3}RU zF_D&^j$}NLIx=wqRriET z=eoS^b!G+6^jTnWcN7=XbEeII78&t1&WPG}Oex&wOiSDbfekZNo-D>(2O?J)J>XXu zw0i>anTHat@ohE-;Oa2_I#2HO5^i9NQ583_T@XA(IsaEXhJB2B_bXQZrEy7DKSfi+ zE!@s&y#LT#oJX@vn$}#J4!VV!&0Gsmp_)%DA#yjyEU-o|cm5dPrf&1pzhm`nGdRKK R7uZJm=@g66U1BBN`winKpvwRN diff --git a/robots/.classpath b/robots/.classpath deleted file mode 100644 index fceb4801b..000000000 --- a/robots/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/robots/.project b/robots/.project deleted file mode 100644 index 78e165663..000000000 --- a/robots/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - Robots - - - - - - org.eclipse.jdt.core.javabuilder - - - - - - org.eclipse.jdt.core.javanature - - diff --git a/robots/src/gui/GameVisualizer.java b/src/main/java/robots/gui/GameVisualizer.java similarity index 99% rename from robots/src/gui/GameVisualizer.java rename to src/main/java/robots/gui/GameVisualizer.java index f82cfd8f8..ab09575e3 100644 --- a/robots/src/gui/GameVisualizer.java +++ b/src/main/java/robots/gui/GameVisualizer.java @@ -1,4 +1,4 @@ -package gui; +package robots.gui; import java.awt.Color; import java.awt.EventQueue; diff --git a/robots/src/gui/GameWindow.java b/src/main/java/robots/gui/GameWindow.java similarity index 96% rename from robots/src/gui/GameWindow.java rename to src/main/java/robots/gui/GameWindow.java index ecb63c00f..a04d78a7b 100644 --- a/robots/src/gui/GameWindow.java +++ b/src/main/java/robots/gui/GameWindow.java @@ -1,4 +1,4 @@ -package gui; +package robots.gui; import java.awt.BorderLayout; diff --git a/robots/src/gui/LogWindow.java b/src/main/java/robots/gui/LogWindow.java similarity index 91% rename from robots/src/gui/LogWindow.java rename to src/main/java/robots/gui/LogWindow.java index 4e446b042..66b620680 100644 --- a/robots/src/gui/LogWindow.java +++ b/src/main/java/robots/gui/LogWindow.java @@ -1,4 +1,4 @@ -package gui; +package robots.gui; import java.awt.BorderLayout; import java.awt.EventQueue; @@ -7,9 +7,9 @@ import javax.swing.JInternalFrame; import javax.swing.JPanel; -import log.LogChangeListener; -import log.LogEntry; -import log.LogWindowSource; +import robots.log.LogChangeListener; +import robots.log.LogEntry; +import robots.log.LogWindowSource; public class LogWindow extends JInternalFrame implements LogChangeListener { diff --git a/robots/src/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java similarity index 61% rename from robots/src/gui/MainApplicationFrame.java rename to src/main/java/robots/gui/MainApplicationFrame.java index 134c900ba..b034ae419 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -1,14 +1,22 @@ -package gui; +package robots.gui; -import java.awt.Dimension; -import java.awt.Toolkit; +import java.io.File; + +import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.FileOutputStream; +import java.io.FileInputStream; +import java.io.IOException; + +import java.util.Properties; + import javax.swing.*; -import log.Logger; +import robots.log.Logger; + public class MainApplicationFrame extends JFrame { @@ -42,6 +50,8 @@ private void initialize() { setJMenuBar(generateMenuBar()); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + restoreWindowStates(); + addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -79,7 +89,7 @@ private JMenu createFileMenu() { JMenu fileMenu = new JMenu("Файл"); JMenuItem exitItem = new JMenuItem("Выход"); - exitItem.addActionListener(e -> handleExit()); + exitItem.addActionListener(_ -> handleExit()); fileMenu.add(exitItem); return fileMenu; @@ -91,13 +101,13 @@ private JMenu createLookAndFeelMenu() { lookAndFeelMenu.getAccessibleContext().setAccessibleDescription("Управление режимом отображения приложения"); JMenuItem systemItem = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemItem.addActionListener(e -> { + systemItem.addActionListener(_ -> { setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); invalidate(); }); JMenuItem crossItem = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossItem.addActionListener(e -> { + crossItem.addActionListener(_ -> { setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); invalidate(); }); @@ -116,7 +126,7 @@ private JMenu createTestMenu() { { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); - addLogMessageItem.addActionListener(e -> controller.onAddLogMessage()); + addLogMessageItem.addActionListener(_ -> controller.onAddLogMessage()); testMenu.add(addLogMessageItem); } @@ -141,8 +151,7 @@ private void handleExit() { } - private void setLookAndFeel(String className) - { + private void setLookAndFeel(String className) { try { UIManager.setLookAndFeel(className); @@ -154,4 +163,62 @@ private void setLookAndFeel(String className) // just ignore } } + + + public void saveWindowStates() { + Properties props = new Properties(); + + for (JInternalFrame frame : desktopPane.getAllFrames()) { + String name = frame.getTitle(); + Rectangle bounds = frame.getBounds(); + + props.setProperty(name + ".x", String.valueOf(bounds.x)); + props.setProperty(name + ".y", String.valueOf(bounds.y)); + props.setProperty(name + ".width", String.valueOf(bounds.width)); + props.setProperty(name + ".height", String.valueOf(bounds.height)); + props.setProperty(name + ".isIcon", String.valueOf(frame.isIcon())); + props.setProperty(name + ".isMaximized", String.valueOf(frame.isMaximum())); + } + + try (FileOutputStream out = new FileOutputStream(WindowConfig.getConfigFile())) { + props.store(out, "Window state"); + } catch (IOException e) { + e.printStackTrace(); + } + } + + + public void restoreWindowStates() { + File file = WindowConfig.getConfigFile(); + if (!file.exists()) return; + + Properties props = new Properties(); + try (FileInputStream in = new FileInputStream(file)) { + props.load(in); + } catch (IOException e) { + Logger.error("Ошибка при установке LookAndFeel: " + e.getMessage()); + } + + for (JInternalFrame frame : desktopPane.getAllFrames()) { + String name = frame.getTitle(); + try { + int x = Integer.parseInt(props.getProperty(name + ".x", "100")); + int y = Integer.parseInt(props.getProperty(name + ".y", "100")); + int width = Integer.parseInt(props.getProperty(name + ".width", "300")); + int height = Integer.parseInt(props.getProperty(name + ".height", "300")); + + frame.setBounds(x, y, width, height); + + if (Boolean.parseBoolean(props.getProperty(name + ".isIcon", "false"))) + frame.setIcon(true); + if (Boolean.parseBoolean(props.getProperty(name + ".isMaximized", "false"))) + frame.setMaximum(true); + + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + } diff --git a/robots/src/gui/MainController.java b/src/main/java/robots/gui/MainController.java similarity index 68% rename from robots/src/gui/MainController.java rename to src/main/java/robots/gui/MainController.java index b4d92f445..f3fa46518 100644 --- a/robots/src/gui/MainController.java +++ b/src/main/java/robots/gui/MainController.java @@ -1,24 +1,24 @@ -package gui; +package robots.gui; import java.awt.*; -import log.Logger; +import robots.log.Logger; public class MainController { private final LogWindow logWindow; private final GameWindow gameWindow; + private MainApplicationFrame frame; public MainController() { this.logWindow = new LogWindow(Logger.getDefaultLogSource()); this.gameWindow = new GameWindow(); } - public MainApplicationFrame createFrame() { - MainApplicationFrame frame = new MainApplicationFrame(logWindow, gameWindow, this); + public void createFrame() { + frame = new MainApplicationFrame(logWindow, gameWindow, this); frame.pack(); frame.setVisible(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); - return frame; } public void onAddLogMessage() { @@ -26,6 +26,8 @@ public void onAddLogMessage() { } public void handleExit() { + if (frame != null) + frame.saveWindowStates(); System.exit(0); } diff --git a/robots/src/gui/RobotsProgram.java b/src/main/java/robots/gui/RobotsProgram.java similarity index 56% rename from robots/src/gui/RobotsProgram.java rename to src/main/java/robots/gui/RobotsProgram.java index 4824933c3..956bd789d 100644 --- a/robots/src/gui/RobotsProgram.java +++ b/src/main/java/robots/gui/RobotsProgram.java @@ -1,21 +1,24 @@ -package gui; +package robots.gui; + +import robots.log.Logger; import javax.swing.SwingUtilities; import javax.swing.UIManager; +import java.util.Locale; public class RobotsProgram { public static void main(String[] args) { + Locale.setDefault(new Locale("ru", "RU")); try { UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception e) { - e.printStackTrace(); + Logger.error("Ошибка при установке LookAndFeel: " + e.getMessage()); } SwingUtilities.invokeLater(() -> { - MainController mainController = new MainController(); - MainApplicationFrame _ = mainController.createFrame(); + new MainController().createFrame(); }); } diff --git a/src/main/java/robots/gui/WindowConfig.java b/src/main/java/robots/gui/WindowConfig.java new file mode 100644 index 000000000..2f95f25ef --- /dev/null +++ b/src/main/java/robots/gui/WindowConfig.java @@ -0,0 +1,9 @@ +package robots.gui; + +import java.io.File; + +public class WindowConfig { + public static File getConfigFile() { + return new File(System.getProperty("user.home"), ".robot-windows.config"); + } +} diff --git a/robots/src/log/LogChangeListener.java b/src/main/java/robots/log/LogChangeListener.java similarity index 76% rename from robots/src/log/LogChangeListener.java rename to src/main/java/robots/log/LogChangeListener.java index 2ba48db75..26ddea5cb 100644 --- a/robots/src/log/LogChangeListener.java +++ b/src/main/java/robots/log/LogChangeListener.java @@ -1,4 +1,4 @@ -package log; +package robots.log; public interface LogChangeListener { diff --git a/robots/src/log/LogEntry.java b/src/main/java/robots/log/LogEntry.java similarity index 95% rename from robots/src/log/LogEntry.java rename to src/main/java/robots/log/LogEntry.java index 3d9147107..ab539b24d 100644 --- a/robots/src/log/LogEntry.java +++ b/src/main/java/robots/log/LogEntry.java @@ -1,4 +1,4 @@ -package log; +package robots.log; public class LogEntry { diff --git a/robots/src/log/LogLevel.java b/src/main/java/robots/log/LogLevel.java similarity index 93% rename from robots/src/log/LogLevel.java rename to src/main/java/robots/log/LogLevel.java index 582d010cc..898e8dbfb 100644 --- a/robots/src/log/LogLevel.java +++ b/src/main/java/robots/log/LogLevel.java @@ -1,4 +1,4 @@ -package log; +package robots.log; public enum LogLevel { diff --git a/robots/src/log/LogWindowSource.java b/src/main/java/robots/log/LogWindowSource.java similarity index 99% rename from robots/src/log/LogWindowSource.java rename to src/main/java/robots/log/LogWindowSource.java index 9aa27edf6..afceb19fb 100644 --- a/robots/src/log/LogWindowSource.java +++ b/src/main/java/robots/log/LogWindowSource.java @@ -1,4 +1,5 @@ -package log; +package robots.log; + import java.util.ArrayList; import java.util.Collections; diff --git a/robots/src/log/Logger.java b/src/main/java/robots/log/Logger.java similarity index 96% rename from robots/src/log/Logger.java rename to src/main/java/robots/log/Logger.java index 5ff4fa964..81d72c8cc 100644 --- a/robots/src/log/Logger.java +++ b/src/main/java/robots/log/Logger.java @@ -1,4 +1,4 @@ -package log; +package robots.log; public final class Logger { From 290e7cdbdfeb4fe949c52c92feff6bee034e999f Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Thu, 17 Apr 2025 14:57:45 +0500 Subject: [PATCH 08/18] add task2 --- net | 1 - 1 file changed, 1 deletion(-) delete mode 160000 net diff --git a/net b/net deleted file mode 160000 index 10760b596..000000000 --- a/net +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 10760b596803fd8219c89cf784d948f066bf4767 From 42b5d7ad1dfa2c393f862a3c438698e38c8bc382 Mon Sep 17 00:00:00 2001 From: Maxim <144677273+orelkrylatiy@users.noreply.github.com> Date: Thu, 17 Apr 2025 14:59:39 +0500 Subject: [PATCH 09/18] Delete my.txt --- my.txt | 56 -------------------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 my.txt diff --git a/my.txt b/my.txt deleted file mode 100644 index 6e5615f98..000000000 --- a/my.txt +++ /dev/null @@ -1,56 +0,0 @@ - -=============================================================================================================== -🧠 Что такое MVC (Model–View–Controller)? -MVC — это архитектурный шаблон для разделения логики в программе: - -Компонент Что делает Пример в GUI -🧩 Model Хранит данные и бизнес-логику список логов, состояние игры -🖼️ View Отображает данные (GUI) окно, кнопки, таблицы -🕹️ Controller Обрабатывает действия пользователя и обновляет Model/View обработка кликов, вызов логики -=============================================================================================================== -1. Model -LogEntry — это элемент данных лога (чистая модель). - -Logger — это контроллер модели (может менять состояние модели). - -GameState (если есть) — состояние игры. - -2. View -MainApplicationFrame — главное окно. - -GameWindow, LogWindow — визуальные представления (View). - -GameVisualizer — возможно, рисует объекты (чистый View). - -3. Controller -LogChangeListener — похоже на контроллер (слушатель изменений, вызывает обновление View). - -Внутри GameWindow может быть код, который слушает кнопки и вызывает действия → это тоже контроллерская часть. -=============================================================================================================== - -Задавай себе 3 вопроса: - -Этот класс хранит данные? → значит, это Model. - -Он отображает что-то на экране, но сам по себе ничего не делает? → View. - -Он реагирует на действия и вызывает методы моделей или обновляет представление? → Controller. -=============================================================================================================== - -// JFrame — основное окно -// JDesktopPane — рабочий стол (панель для окон). -// JInternalFrame — подокна (внутренние окна). - -=============================================================================================================== - -JFrame - └── JPanel - ├── JLabel - ├── JTextField - └── JButton - -=============================================================================================================== - - - -=============================================================================================================== \ No newline at end of file From ab1cc9e5f9ef7d321b7c40a697aedb2bad882807 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Thu, 17 Apr 2025 15:03:16 +0500 Subject: [PATCH 10/18] Refactor: change project structure --- src/main/java/robots/log/LogWindowSource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/robots/log/LogWindowSource.java b/src/main/java/robots/log/LogWindowSource.java index afceb19fb..6d64a1969 100644 --- a/src/main/java/robots/log/LogWindowSource.java +++ b/src/main/java/robots/log/LogWindowSource.java @@ -60,6 +60,7 @@ public void append(LogLevel logLevel, String strMessage) } } } + for (LogChangeListener listener : activeListeners) { listener.onLogChanged(); From 26e27d648ad19ad34413e91bd4f29ed583050eb7 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 23 Apr 2025 10:22:50 +0500 Subject: [PATCH 11/18] fixed task2 bugs --- .../java/robots/gui/MainApplicationFrame.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index b034ae419..de4b3a859 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -34,6 +34,10 @@ public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainCont } private void initialize() { + gameWindow.setName("gameWindow"); + logWindow.setName("logWindow"); + + setLogWindow(logWindow); int inset = 50; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); @@ -169,21 +173,25 @@ public void saveWindowStates() { Properties props = new Properties(); for (JInternalFrame frame : desktopPane.getAllFrames()) { - String name = frame.getTitle(); + String name = frame.getName(); Rectangle bounds = frame.getBounds(); props.setProperty(name + ".x", String.valueOf(bounds.x)); props.setProperty(name + ".y", String.valueOf(bounds.y)); props.setProperty(name + ".width", String.valueOf(bounds.width)); props.setProperty(name + ".height", String.valueOf(bounds.height)); - props.setProperty(name + ".isIcon", String.valueOf(frame.isIcon())); + try { + props.setProperty(name + ".isIcon", String.valueOf(frame.isIcon())); + } catch (Exception e) { + Logger.error("Ошибка при получении isIcon: " + e.getMessage()); + } props.setProperty(name + ".isMaximized", String.valueOf(frame.isMaximum())); } try (FileOutputStream out = new FileOutputStream(WindowConfig.getConfigFile())) { props.store(out, "Window state"); } catch (IOException e) { - e.printStackTrace(); + Logger.error("Ошибка при восстановлении положения окна " + e.getMessage()); } } @@ -200,12 +208,12 @@ public void restoreWindowStates() { } for (JInternalFrame frame : desktopPane.getAllFrames()) { - String name = frame.getTitle(); + String name = frame.getName(); try { - int x = Integer.parseInt(props.getProperty(name + ".x", "100")); - int y = Integer.parseInt(props.getProperty(name + ".y", "100")); - int width = Integer.parseInt(props.getProperty(name + ".width", "300")); - int height = Integer.parseInt(props.getProperty(name + ".height", "300")); + int x = parseIntSafe(props, name + ".x", 100); + int y = parseIntSafe(props, name + ".y", 100); + int width = parseIntSafe(props, name + ".width", 300); + int height = parseIntSafe(props, name + ".height", 300); frame.setBounds(x, y, width, height); @@ -215,10 +223,18 @@ public void restoreWindowStates() { frame.setMaximum(true); } catch (Exception e) { - e.printStackTrace(); + Logger.error("Ошибка при восстановлении положения окна " + name + ": " + e.getMessage()); } } } + private int parseIntSafe(Properties props, String key, int defaultValue) { + try { + return Integer.parseInt(props.getProperty(key)); + } catch (NumberFormatException | NullPointerException e) { + return defaultValue; + } + } + } From 6779c5172e57bdcab1b670986c199d2c1c3e8e60 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 7 May 2025 10:28:41 +0500 Subject: [PATCH 12/18] fixed task3 --- src/main/java/robots/gui/AppContext.java | 15 +++++ .../java/robots/gui/RobotPositionWindow.java | 23 ++++++++ .../robots/log/RobotPositionListener.java | 6 ++ .../java/robots/log/RobotPositionSource.java | 56 +++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 src/main/java/robots/gui/AppContext.java create mode 100644 src/main/java/robots/gui/RobotPositionWindow.java create mode 100644 src/main/java/robots/log/RobotPositionListener.java create mode 100644 src/main/java/robots/log/RobotPositionSource.java diff --git a/src/main/java/robots/gui/AppContext.java b/src/main/java/robots/gui/AppContext.java new file mode 100644 index 000000000..547b2d2e6 --- /dev/null +++ b/src/main/java/robots/gui/AppContext.java @@ -0,0 +1,15 @@ +package robots.gui; + +public class AppContext { + public final LogWindow logWindow; + public final GameWindow gameWindow; + public final MainController controller; + public final RobotPositionWindow positionWindow; + + public AppContext(LogWindow logWindow, GameWindow gameWindow, MainController controller, RobotPositionWindow positionWindow) { + this.logWindow = logWindow; + this.gameWindow = gameWindow; + this.controller = controller; + this.positionWindow = positionWindow; + } +} diff --git a/src/main/java/robots/gui/RobotPositionWindow.java b/src/main/java/robots/gui/RobotPositionWindow.java new file mode 100644 index 000000000..d81944499 --- /dev/null +++ b/src/main/java/robots/gui/RobotPositionWindow.java @@ -0,0 +1,23 @@ +package robots.gui; + +import robots.log.RobotPositionListener; +import robots.log.RobotPositionSource; + +import javax.swing.*; + +public class RobotPositionWindow extends JInternalFrame implements RobotPositionListener { + private final JLabel label; + + public RobotPositionWindow(RobotPositionSource source) { + super("Координаты робота", true, true, true, true); + label = new JLabel("x: 0, y: 0"); + getContentPane().add(label); + pack(); + source.registerListener(this); + } + + @Override + public void onPositionChanged(double x, double y) { + SwingUtilities.invokeLater(() -> label.setText("x: " + (int)x + ", y: " + (int)y)); + } +} diff --git a/src/main/java/robots/log/RobotPositionListener.java b/src/main/java/robots/log/RobotPositionListener.java new file mode 100644 index 000000000..00b7caf84 --- /dev/null +++ b/src/main/java/robots/log/RobotPositionListener.java @@ -0,0 +1,6 @@ +package robots.log; + +public interface RobotPositionListener { + void onPositionChanged(double x, double y); + +} diff --git a/src/main/java/robots/log/RobotPositionSource.java b/src/main/java/robots/log/RobotPositionSource.java new file mode 100644 index 000000000..0e5a56f65 --- /dev/null +++ b/src/main/java/robots/log/RobotPositionSource.java @@ -0,0 +1,56 @@ +package robots.log; + +import java.util.ArrayList; +import java.util.Collections; + +public class RobotPositionSource { + private final ArrayList listeners = new ArrayList<>(); + private volatile RobotPositionListener[] activeListeners; + + private double x = 0; + private double y = 0; + + public synchronized void setPosition(double x, double y) { + this.x = x; + this.y = y; + notifyListeners(); + } + + public synchronized double getX() { + return x; + } + + public synchronized double getY() { + return y; + } + + public void registerListener(RobotPositionListener listener) { + synchronized (listeners) { + listeners.add(listener); + activeListeners = null; + } + } + + public void unregisterListener(RobotPositionListener listener) { + synchronized (listeners) { + listeners.remove(listener); + activeListeners = null; + } + } + + private void notifyListeners() { + RobotPositionListener[] currentListeners = activeListeners; + if (currentListeners == null) { + synchronized (listeners) { + if (activeListeners == null) { + activeListeners = listeners.toArray(new RobotPositionListener[0]); + currentListeners = activeListeners; + } + } + } + + for (RobotPositionListener listener : currentListeners) { + listener.onPositionChanged(x, y); + } + } +} From 547110fa1ec0ba037f077f12a867a02eb7693571 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 7 May 2025 16:39:38 +0500 Subject: [PATCH 13/18] fixed task3 --- src/main/java/robots/gui/AppContext.java | 16 ++++++ .../java/robots/gui/RobotPositionWindow.java | 23 ++++++++ .../robots/log/RobotPositionListener.java | 6 ++ .../java/robots/log/RobotPositionSource.java | 56 +++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 src/main/java/robots/gui/AppContext.java create mode 100644 src/main/java/robots/gui/RobotPositionWindow.java create mode 100644 src/main/java/robots/log/RobotPositionListener.java create mode 100644 src/main/java/robots/log/RobotPositionSource.java diff --git a/src/main/java/robots/gui/AppContext.java b/src/main/java/robots/gui/AppContext.java new file mode 100644 index 000000000..a9196b5ee --- /dev/null +++ b/src/main/java/robots/gui/AppContext.java @@ -0,0 +1,16 @@ +package robots.gui; + +public class AppContext { + public final LogWindow logWindow; + public final GameWindow gameWindow; + public final MainController controller; + public final RobotPositionWindow positionWindow; + + public AppContext(LogWindow logWindow, GameWindow gameWindow, MainController controller, RobotPositionWindow positionWindow) { + this.logWindow = logWindow; + this.gameWindow = gameWindow; + this.controller = controller; + this.positionWindow = positionWindow; + } + +} diff --git a/src/main/java/robots/gui/RobotPositionWindow.java b/src/main/java/robots/gui/RobotPositionWindow.java new file mode 100644 index 000000000..d81944499 --- /dev/null +++ b/src/main/java/robots/gui/RobotPositionWindow.java @@ -0,0 +1,23 @@ +package robots.gui; + +import robots.log.RobotPositionListener; +import robots.log.RobotPositionSource; + +import javax.swing.*; + +public class RobotPositionWindow extends JInternalFrame implements RobotPositionListener { + private final JLabel label; + + public RobotPositionWindow(RobotPositionSource source) { + super("Координаты робота", true, true, true, true); + label = new JLabel("x: 0, y: 0"); + getContentPane().add(label); + pack(); + source.registerListener(this); + } + + @Override + public void onPositionChanged(double x, double y) { + SwingUtilities.invokeLater(() -> label.setText("x: " + (int)x + ", y: " + (int)y)); + } +} diff --git a/src/main/java/robots/log/RobotPositionListener.java b/src/main/java/robots/log/RobotPositionListener.java new file mode 100644 index 000000000..00b7caf84 --- /dev/null +++ b/src/main/java/robots/log/RobotPositionListener.java @@ -0,0 +1,6 @@ +package robots.log; + +public interface RobotPositionListener { + void onPositionChanged(double x, double y); + +} diff --git a/src/main/java/robots/log/RobotPositionSource.java b/src/main/java/robots/log/RobotPositionSource.java new file mode 100644 index 000000000..0e5a56f65 --- /dev/null +++ b/src/main/java/robots/log/RobotPositionSource.java @@ -0,0 +1,56 @@ +package robots.log; + +import java.util.ArrayList; +import java.util.Collections; + +public class RobotPositionSource { + private final ArrayList listeners = new ArrayList<>(); + private volatile RobotPositionListener[] activeListeners; + + private double x = 0; + private double y = 0; + + public synchronized void setPosition(double x, double y) { + this.x = x; + this.y = y; + notifyListeners(); + } + + public synchronized double getX() { + return x; + } + + public synchronized double getY() { + return y; + } + + public void registerListener(RobotPositionListener listener) { + synchronized (listeners) { + listeners.add(listener); + activeListeners = null; + } + } + + public void unregisterListener(RobotPositionListener listener) { + synchronized (listeners) { + listeners.remove(listener); + activeListeners = null; + } + } + + private void notifyListeners() { + RobotPositionListener[] currentListeners = activeListeners; + if (currentListeners == null) { + synchronized (listeners) { + if (activeListeners == null) { + activeListeners = listeners.toArray(new RobotPositionListener[0]); + currentListeners = activeListeners; + } + } + } + + for (RobotPositionListener listener : currentListeners) { + listener.onPositionChanged(x, y); + } + } +} From 5db5d8980d60a1f47ae5eb92cad87ef40af7c516 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 7 May 2025 16:41:05 +0500 Subject: [PATCH 14/18] fixed task3 --- src/main/java/robots/gui/GameVisualizer.java | 17 +++++++-------- .../java/robots/gui/MainApplicationFrame.java | 9 +++++--- src/main/java/robots/gui/MainController.java | 5 ++++- src/main/java/robots/log/Logger.java | 21 ++++++++++--------- 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/main/java/robots/gui/GameVisualizer.java b/src/main/java/robots/gui/GameVisualizer.java index ab09575e3..626f1acaa 100644 --- a/src/main/java/robots/gui/GameVisualizer.java +++ b/src/main/java/robots/gui/GameVisualizer.java @@ -1,5 +1,5 @@ package robots.gui; - +import robots.log.Logger; import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; @@ -15,14 +15,7 @@ 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; @@ -31,10 +24,11 @@ private static Timer initTimer() private volatile int m_targetPositionY = 100; private static final double maxVelocity = 0.1; - private static final double maxAngularVelocity = 0.001; + private static final double maxAngularVelocity = 0.001; public GameVisualizer() { + Timer m_timer = new Timer("events generator", true); m_timer.schedule(new TimerTask() { @Override @@ -61,6 +55,7 @@ public void mouseClicked(MouseEvent e) } }); setDoubleBuffered(true); + } protected void setTargetPosition(Point p) @@ -110,6 +105,8 @@ protected void onModelUpdateEvent() } moveRobot(velocity, angularVelocity, 10); + + Logger.getrobotPositionModel().setPosition(m_robotPositionX, m_robotPositionY); } private static double applyLimits(double value, double min, double max) diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index de4b3a859..209f76df7 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -23,13 +23,16 @@ public class MainApplicationFrame extends JFrame private final LogWindow logWindow; private final GameWindow gameWindow; private final MainController controller; + private final RobotPositionWindow robotPositionWindow; + private final JDesktopPane desktopPane = new JDesktopPane(); - - public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainController mainController) { + + public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainController mainController, RobotPositionWindow robotPositionWindow) { this.logWindow = logWindow; this.gameWindow = gameWindow; this.controller = mainController; + this.robotPositionWindow = robotPositionWindow; initialize(); } @@ -50,6 +53,7 @@ private void initialize() { addWindow(logWindow); addWindow(gameWindow); + addWindow(robotPositionWindow); setJMenuBar(generateMenuBar()); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); @@ -74,7 +78,6 @@ protected void setLogWindow(LogWindow logWindow ) Logger.debug("Протокол работает"); } - // окна внутри этого стола protected void addWindow(JInternalFrame frame) { desktopPane.add(frame); diff --git a/src/main/java/robots/gui/MainController.java b/src/main/java/robots/gui/MainController.java index f3fa46518..51f5d3dd3 100644 --- a/src/main/java/robots/gui/MainController.java +++ b/src/main/java/robots/gui/MainController.java @@ -3,19 +3,22 @@ import java.awt.*; import robots.log.Logger; +import robots.log.RobotPositionSource; public class MainController { private final LogWindow logWindow; private final GameWindow gameWindow; private MainApplicationFrame frame; + private final RobotPositionWindow robotPositionWindow; public MainController() { this.logWindow = new LogWindow(Logger.getDefaultLogSource()); this.gameWindow = new GameWindow(); + this.robotPositionWindow = new RobotPositionWindow(Logger.getrobotPositionModel()); } public void createFrame() { - frame = new MainApplicationFrame(logWindow, gameWindow, this); + frame = new MainApplicationFrame(logWindow, gameWindow, this, robotPositionWindow); frame.pack(); frame.setVisible(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); diff --git a/src/main/java/robots/log/Logger.java b/src/main/java/robots/log/Logger.java index 81d72c8cc..c34d4d311 100644 --- a/src/main/java/robots/log/Logger.java +++ b/src/main/java/robots/log/Logger.java @@ -1,24 +1,25 @@ package robots.log; -public final class Logger -{ +public final class Logger { private static final LogWindowSource defaultLogSource = new LogWindowSource(100); - + private static final RobotPositionSource robotPositionModel = new RobotPositionSource(); + private Logger() { } - public static void debug(String strMessage) - { + public static void debug(String strMessage) { defaultLogSource.append(LogLevel.Debug, strMessage); } - - public static void error(String strMessage) - { + + public static void error(String strMessage) { defaultLogSource.append(LogLevel.Error, strMessage); } - public static LogWindowSource getDefaultLogSource() - { + public static LogWindowSource getDefaultLogSource() { return defaultLogSource; } + + public static RobotPositionSource getrobotPositionModel() { + return robotPositionModel; + } } From 5b33342fb8a4625d4f8e6c34193cbe8fe508e5f7 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 7 May 2025 20:57:31 +0500 Subject: [PATCH 15/18] task4 --- src/main/java/robots/gui/GameVisualizer.java | 56 ++++----- .../java/robots/gui/MainApplicationFrame.java | 5 + src/main/java/robots/gui/MainController.java | 2 + src/main/java/robots/gui/NewSnakeWindow.java | 15 +++ src/main/java/robots/gui/SnakePanel.java | 108 ++++++++++++++++ src/main/java/robots/log/LogWindowSource.java | 116 +++++++++--------- 6 files changed, 211 insertions(+), 91 deletions(-) create mode 100644 src/main/java/robots/gui/NewSnakeWindow.java create mode 100644 src/main/java/robots/gui/SnakePanel.java diff --git a/src/main/java/robots/gui/GameVisualizer.java b/src/main/java/robots/gui/GameVisualizer.java index 626f1acaa..7f238e8ca 100644 --- a/src/main/java/robots/gui/GameVisualizer.java +++ b/src/main/java/robots/gui/GameVisualizer.java @@ -11,7 +11,7 @@ import java.util.Timer; import java.util.TimerTask; -import javax.swing.JPanel; +import javax.swing.*; public class GameVisualizer extends JPanel { @@ -24,27 +24,19 @@ public class GameVisualizer extends JPanel private volatile int m_targetPositionY = 100; private static final double maxVelocity = 0.1; - private static final double maxAngularVelocity = 0.001; + private static final double maxAngularVelocity = 0.01; public GameVisualizer() { Timer m_timer = new Timer("events generator", true); - m_timer.schedule(new TimerTask() - { - @Override - public void run() - { - onRedrawEvent(); - } - }, 0, 50); - m_timer.schedule(new TimerTask() - { + m_timer.schedule(new TimerTask() { @Override - public void run() - { - onModelUpdateEvent(); + public void run() { + onModelUpdateEvent(); // сначала обновляем модель + onRedrawEvent(); // потом вызываем repaint } - }, 0, 10); + }, 0, 5); // например, 50 кадров в секунду + addMouseListener(new MouseAdapter() { @Override @@ -62,6 +54,7 @@ protected void setTargetPosition(Point p) { m_targetPositionX = p.x; m_targetPositionY = p.y; + EventQueue.invokeLater(this::repaint); } protected void onRedrawEvent() @@ -95,20 +88,22 @@ protected void onModelUpdateEvent() 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; - } + double angleDiff = normalizeAngle(angleToTarget - m_robotDirection); + angularVelocity = angleDiff > 0 ? maxAngularVelocity : -maxAngularVelocity; + moveRobot(velocity, angularVelocity, 10); Logger.getrobotPositionModel().setPosition(m_robotPositionX, m_robotPositionY); } - + + private static double normalizeAngle(double angle) { + while (angle < -Math.PI) angle += 2 * Math.PI; + while (angle > Math.PI) angle -= 2 * Math.PI; + return angle; + } + + private static double applyLimits(double value, double min, double max) { if (value < min) @@ -194,14 +189,15 @@ private void drawRobot(Graphics2D g, int x, int y, double direction) 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); + + private void drawTarget(Graphics2D g, int x, int y) { + AffineTransform oldTransform = g.getTransform(); // сохранение + g.setTransform(new AffineTransform()); // сброс g.setColor(Color.GREEN); fillOval(g, x, y, 5, 5); g.setColor(Color.BLACK); drawOval(g, x, y, 5, 5); + g.setTransform(oldTransform); // восстановление } + } diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index 209f76df7..b7a694dad 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -33,6 +33,7 @@ public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainCont this.gameWindow = gameWindow; this.controller = mainController; this.robotPositionWindow = robotPositionWindow; + initialize(); } @@ -55,6 +56,10 @@ private void initialize() { addWindow(gameWindow); addWindow(robotPositionWindow); + addWindow(new NewSnakeWindow()); + + add(new SnakePanel()); + setJMenuBar(generateMenuBar()); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); diff --git a/src/main/java/robots/gui/MainController.java b/src/main/java/robots/gui/MainController.java index 51f5d3dd3..49296afb4 100644 --- a/src/main/java/robots/gui/MainController.java +++ b/src/main/java/robots/gui/MainController.java @@ -10,8 +10,10 @@ public class MainController { private final GameWindow gameWindow; private MainApplicationFrame frame; private final RobotPositionWindow robotPositionWindow; + private final SnakePanel snakePanel; public MainController() { + this.snakePanel = new SnakePanel(); this.logWindow = new LogWindow(Logger.getDefaultLogSource()); this.gameWindow = new GameWindow(); this.robotPositionWindow = new RobotPositionWindow(Logger.getrobotPositionModel()); diff --git a/src/main/java/robots/gui/NewSnakeWindow.java b/src/main/java/robots/gui/NewSnakeWindow.java new file mode 100644 index 000000000..3fd42ddfa --- /dev/null +++ b/src/main/java/robots/gui/NewSnakeWindow.java @@ -0,0 +1,15 @@ +package robots.gui; + +import javax.swing.*; +import java.awt.*; + +public class NewSnakeWindow extends JInternalFrame { + public NewSnakeWindow() { + super("Новая змейка", true, true, true, true); + setSize(500, 500); + setLocation(100, 100); + setLayout(new BorderLayout()); + add(new SnakePanel(), BorderLayout.CENTER); + pack(); + } +} diff --git a/src/main/java/robots/gui/SnakePanel.java b/src/main/java/robots/gui/SnakePanel.java new file mode 100644 index 000000000..7d95be342 --- /dev/null +++ b/src/main/java/robots/gui/SnakePanel.java @@ -0,0 +1,108 @@ +package robots.gui; + +import robots.log.Logger; + +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; + +public class SnakePanel extends JPanel { + private double snakeX = 100; + private double snakeY = 100; + private double direction = 0; + + private int targetX = 150; + private int targetY = 100; + + private static final double SPEED = 1.5; + private static final double ROTATION_SPEED = 0.05; + + public SnakePanel() { + setBackground(Color.WHITE); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + targetX = e.getX(); + targetY = e.getY(); + SwingUtilities.invokeLater(() -> { + repaint(); + }); + + } + }); + + Timer timer = new Timer(true); + timer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + updateModel(); + SwingUtilities.invokeLater(() -> { + repaint(); + }); } + }, 0, 10); + } + + private void updateModel() { + double angleToTarget = Math.atan2(targetY - snakeY, targetX - snakeX); + double angleDiff = normalizeAngle(angleToTarget - direction); + + if (Math.abs(angleDiff) > ROTATION_SPEED) { + direction += Math.signum(angleDiff) * ROTATION_SPEED; + } else { + direction = angleToTarget; + } + + double dx = SPEED * Math.cos(direction); + double dy = SPEED * Math.sin(direction); + + if (distance(snakeX, snakeY, targetX, targetY) > SPEED) { + snakeX += dx; + snakeY += dy; + } + Logger.getrobotPositionModel().setPosition(snakeX, snakeY); + } + + private double normalizeAngle(double angle) { + while (angle < -Math.PI) angle += 2 * Math.PI; + while (angle > Math.PI) angle -= 2 * Math.PI; + return angle; + } + + private double distance(double x1, double y1, double x2, double y2) { + return Math.hypot(x1 - x2, y1 - y2); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + drawSnake((Graphics2D) g); + drawTarget((Graphics2D) g); + } + + private void drawSnake(Graphics2D g) { + int bodyLength = 30; + int bodyWidth = 10; + + AffineTransform old = g.getTransform(); + g.rotate(direction, snakeX, snakeY); + + g.setColor(Color.MAGENTA); + g.fillOval((int)(snakeX - bodyLength / 2), (int)(snakeY - bodyWidth / 2), bodyLength, bodyWidth); + g.setColor(Color.BLACK); + g.drawOval((int)(snakeX - bodyLength / 2), (int)(snakeY - bodyWidth / 2), bodyLength, bodyWidth); + + g.setTransform(old); + } + + private void drawTarget(Graphics2D g) { + g.setColor(Color.GREEN); + g.fillOval(targetX - 4, targetY - 4, 8, 8); + g.setColor(Color.BLACK); + g.drawOval(targetX - 4, targetY - 4, 8, 8); + } +} diff --git a/src/main/java/robots/log/LogWindowSource.java b/src/main/java/robots/log/LogWindowSource.java index 6d64a1969..40691e9f0 100644 --- a/src/main/java/robots/log/LogWindowSource.java +++ b/src/main/java/robots/log/LogWindowSource.java @@ -1,89 +1,83 @@ package robots.log; +import java.lang.ref.WeakReference; +import java.util.*; -import java.util.ArrayList; -import java.util.Collections; - -/** - * Что починить: - * 1. Этот класс порождает утечку ресурсов (связанные слушатели оказываются - * удерживаемыми в памяти) - * 2. Этот класс хранит активные сообщения лога, но в такой реализации он - * их лишь накапливает. Надо же, чтобы количество сообщений в логе было ограничено - * величиной m_iQueueLength (т.е. реально нужна очередь сообщений - * ограниченного размера) - */ -public class LogWindowSource -{ - - private final ArrayList m_messages; - private final ArrayList m_listeners; +public class LogWindowSource { + private final int m_iQueueLength; + private final Deque m_messages; + private final List> m_listeners = new ArrayList<>(); private volatile LogChangeListener[] m_activeListeners; - - public LogWindowSource(int iQueueLength) - { - m_messages = new ArrayList(iQueueLength); - m_listeners = new ArrayList(); + + public LogWindowSource(int iQueueLength) { + this.m_iQueueLength = iQueueLength; + this.m_messages = new ArrayDeque<>(iQueueLength); } - - public void registerListener(LogChangeListener listener) - { - synchronized(m_listeners) - { - m_listeners.add(listener); + + public void registerListener(LogChangeListener listener) { + synchronized (m_listeners) { + m_listeners.add(new WeakReference<>(listener)); m_activeListeners = null; } } - - public void unregisterListener(LogChangeListener listener) - { - synchronized(m_listeners) - { - m_listeners.remove(listener); + + public void unregisterListener(LogChangeListener listener) { + synchronized (m_listeners) { + m_listeners.removeIf(ref -> { + LogChangeListener l = ref.get(); + return l == null || l == 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); + synchronized (m_messages) { + if (m_messages.size() >= m_iQueueLength) { + m_messages.pollFirst(); + } + m_messages.addLast(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; + if (activeListeners == null) { + synchronized (m_listeners) { + List snapshot = new ArrayList<>(); + for (WeakReference ref : m_listeners) { + LogChangeListener l = ref.get(); + if (l != null) { + snapshot.add(l); + } } + activeListeners = snapshot.toArray(new LogChangeListener[0]); + m_activeListeners = activeListeners; } } - for (LogChangeListener listener : activeListeners) - { + for (LogChangeListener listener : activeListeners) { listener.onLogChanged(); } } - - public int size() - { + + public int size() { return m_messages.size(); } - public Iterable range(int startFrom, int count) - { - if (startFrom < 0 || startFrom >= m_messages.size()) - { - return Collections.emptyList(); + public Iterable range(int startFrom, int count) { + synchronized (m_messages) { + if (startFrom < 0 || startFrom >= m_messages.size()) { + return Collections.emptyList(); + } + List list = new ArrayList<>(m_messages); + int indexTo = Math.min(startFrom + count, list.size()); + return list.subList(startFrom, indexTo); } - int indexTo = Math.min(startFrom + count, m_messages.size()); - return m_messages.subList(startFrom, indexTo); } - public Iterable all() - { - return m_messages; + public Iterable all() { + synchronized (m_messages) { + return new ArrayList<>(m_messages); + } } } From c225d3ddde09590e46185a9e2bd73868e32559cb Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 14 May 2025 09:44:14 +0500 Subject: [PATCH 16/18] task4 add second snake and lives --- .../java/robots/gui/MainApplicationFrame.java | 2 +- src/main/java/robots/gui/SnakePanel.java | 69 ++++++++++++++++--- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index b7a694dad..e75f20f00 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -53,7 +53,7 @@ private void initialize() { gameWindow.setSize(400, 400); addWindow(logWindow); - addWindow(gameWindow); + // addWindow(gameWindow); addWindow(robotPositionWindow); addWindow(new NewSnakeWindow()); diff --git a/src/main/java/robots/gui/SnakePanel.java b/src/main/java/robots/gui/SnakePanel.java index 7d95be342..85d6bb0e6 100644 --- a/src/main/java/robots/gui/SnakePanel.java +++ b/src/main/java/robots/gui/SnakePanel.java @@ -11,10 +11,21 @@ import java.util.TimerTask; public class SnakePanel extends JPanel { + private static final double LEADER_SPEED = 1.5; + private static final double FOLLOWER_SPEED = 0.8; // медленнее + + private int lives = 3; + private static final int MAX_LIVES = 5; + private static final double CATCH_DISTANCE = 10.0; // если ближе — атака + private double snakeX = 100; private double snakeY = 100; private double direction = 0; + private double followerX = 50; + private double followerY = 50; + private double followerDirection = 0; + private int targetX = 150; private int targetY = 100; @@ -48,6 +59,7 @@ public void run() { } private void updateModel() { + // === ОСНОВНАЯ ЗМЕЯ === double angleToTarget = Math.atan2(targetY - snakeY, targetX - snakeX); double angleDiff = normalizeAngle(angleToTarget - direction); @@ -57,14 +69,44 @@ private void updateModel() { direction = angleToTarget; } - double dx = SPEED * Math.cos(direction); - double dy = SPEED * Math.sin(direction); + double dx = LEADER_SPEED * Math.cos(direction); + double dy = LEADER_SPEED * Math.sin(direction); if (distance(snakeX, snakeY, targetX, targetY) > SPEED) { snakeX += dx; snakeY += dy; } + Logger.getrobotPositionModel().setPosition(snakeX, snakeY); + + // === ВТОРАЯ ЗМЕЯ: ПРЕСЛЕДОВАТЕЛЬ === + double angleToLeader = Math.atan2(snakeY - followerY, snakeX - followerX); + double followerAngleDiff = normalizeAngle(angleToLeader - followerDirection); + + if (Math.abs(followerAngleDiff) > ROTATION_SPEED) { + followerDirection += Math.signum(followerAngleDiff) * ROTATION_SPEED; + } else { + followerDirection = angleToLeader; + } + + double followerDx = FOLLOWER_SPEED * Math.cos(followerDirection); + double followerDy = FOLLOWER_SPEED * Math.sin(followerDirection); + + if (distance(followerX, followerY, snakeX, snakeY) > SPEED) { + followerX += followerDx; + followerY += followerDy; + } + + // если змея добралась до цели + if (distance(snakeX, snakeY, targetX, targetY) <= LEADER_SPEED) { + if (lives < MAX_LIVES) lives++; + // можно обновить + } + + if (distance(followerX, followerY, snakeX, snakeY) < CATCH_DISTANCE) { + if (lives > 0) lives--; + } + } private double normalizeAngle(double angle) { @@ -80,25 +122,36 @@ private double distance(double x1, double y1, double x2, double y2) { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); - drawSnake((Graphics2D) g); + drawSnake((Graphics2D) g, snakeX, snakeY, direction, Color.MAGENTA); + drawSnake((Graphics2D) g, followerX, followerY, followerDirection, Color.BLUE); drawTarget((Graphics2D) g); + + drawLives((Graphics2D) g); + } + + private void drawLives(Graphics2D g) { + g.setColor(Color.RED); + g.setFont(new Font("Arial", Font.BOLD, 16)); + g.drawString("Lives: " + "❤️".repeat(lives), 10, 20); } - private void drawSnake(Graphics2D g) { + + private void drawSnake(Graphics2D g, double x, double y, double dir, Color color) { int bodyLength = 30; int bodyWidth = 10; AffineTransform old = g.getTransform(); - g.rotate(direction, snakeX, snakeY); + g.rotate(dir, x, y); - g.setColor(Color.MAGENTA); - g.fillOval((int)(snakeX - bodyLength / 2), (int)(snakeY - bodyWidth / 2), bodyLength, bodyWidth); + g.setColor(color); + g.fillOval((int)(x - bodyLength / 2), (int)(y - bodyWidth / 2), bodyLength, bodyWidth); g.setColor(Color.BLACK); - g.drawOval((int)(snakeX - bodyLength / 2), (int)(snakeY - bodyWidth / 2), bodyLength, bodyWidth); + g.drawOval((int)(x - bodyLength / 2), (int)(y - bodyWidth / 2), bodyLength, bodyWidth); g.setTransform(old); } + private void drawTarget(Graphics2D g) { g.setColor(Color.GREEN); g.fillOval(targetX - 4, targetY - 4, 8, 8); From ba807636b273035520df60cdc3df5b0c565ee5a0 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 14 May 2025 10:13:19 +0500 Subject: [PATCH 17/18] task4 fix lives --- src/main/java/robots/gui/SnakePanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/robots/gui/SnakePanel.java b/src/main/java/robots/gui/SnakePanel.java index 85d6bb0e6..8a7510555 100644 --- a/src/main/java/robots/gui/SnakePanel.java +++ b/src/main/java/robots/gui/SnakePanel.java @@ -158,4 +158,5 @@ private void drawTarget(Graphics2D g) { g.setColor(Color.BLACK); g.drawOval(targetX - 4, targetY - 4, 8, 8); } + } From 5198a0f6f1a21377fbb20ee59544b8ab5fb376e9 Mon Sep 17 00:00:00 2001 From: orelkrylatiy Date: Wed, 21 May 2025 10:23:13 +0500 Subject: [PATCH 18/18] task3 fix bugs --- src/main/java/robots/gui/AppContext.java | 4 +--- src/main/java/robots/gui/GameVisualizer.java | 4 +++- .../java/robots/gui/MainApplicationFrame.java | 16 +++++-------- src/main/java/robots/gui/MainController.java | 23 ++++--------------- src/main/java/robots/log/Logger.java | 5 ---- src/main/java/robots/log/RobotModel.java | 11 +++++++++ 6 files changed, 25 insertions(+), 38 deletions(-) create mode 100644 src/main/java/robots/log/RobotModel.java diff --git a/src/main/java/robots/gui/AppContext.java b/src/main/java/robots/gui/AppContext.java index 547b2d2e6..32a3c223e 100644 --- a/src/main/java/robots/gui/AppContext.java +++ b/src/main/java/robots/gui/AppContext.java @@ -3,13 +3,11 @@ public class AppContext { public final LogWindow logWindow; public final GameWindow gameWindow; - public final MainController controller; public final RobotPositionWindow positionWindow; - public AppContext(LogWindow logWindow, GameWindow gameWindow, MainController controller, RobotPositionWindow positionWindow) { + public AppContext(LogWindow logWindow, GameWindow gameWindow, RobotPositionWindow positionWindow) { this.logWindow = logWindow; this.gameWindow = gameWindow; - this.controller = controller; this.positionWindow = positionWindow; } } diff --git a/src/main/java/robots/gui/GameVisualizer.java b/src/main/java/robots/gui/GameVisualizer.java index 626f1acaa..195e50e68 100644 --- a/src/main/java/robots/gui/GameVisualizer.java +++ b/src/main/java/robots/gui/GameVisualizer.java @@ -1,5 +1,7 @@ package robots.gui; import robots.log.Logger; +import robots.log.RobotModel; + import java.awt.Color; import java.awt.EventQueue; import java.awt.Graphics; @@ -106,7 +108,7 @@ protected void onModelUpdateEvent() moveRobot(velocity, angularVelocity, 10); - Logger.getrobotPositionModel().setPosition(m_robotPositionX, m_robotPositionY); + RobotModel.getRobotPositionModel().setPosition(m_robotPositionX, m_robotPositionY); } private static double applyLimits(double value, double min, double max) diff --git a/src/main/java/robots/gui/MainApplicationFrame.java b/src/main/java/robots/gui/MainApplicationFrame.java index 209f76df7..78cab6f00 100644 --- a/src/main/java/robots/gui/MainApplicationFrame.java +++ b/src/main/java/robots/gui/MainApplicationFrame.java @@ -22,17 +22,14 @@ public class MainApplicationFrame extends JFrame { private final LogWindow logWindow; private final GameWindow gameWindow; - private final MainController controller; private final RobotPositionWindow robotPositionWindow; - private final JDesktopPane desktopPane = new JDesktopPane(); - public MainApplicationFrame(LogWindow logWindow, GameWindow gameWindow, MainController mainController, RobotPositionWindow robotPositionWindow) { - this.logWindow = logWindow; - this.gameWindow = gameWindow; - this.controller = mainController; - this.robotPositionWindow = robotPositionWindow; + public MainApplicationFrame(AppContext appContext) { + this.logWindow = appContext.logWindow; + this.gameWindow = appContext.gameWindow; + this.robotPositionWindow = appContext.positionWindow; initialize(); } @@ -133,10 +130,9 @@ private JMenu createTestMenu() { { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); - addLogMessageItem.addActionListener(_ -> controller.onAddLogMessage()); + addLogMessageItem.addActionListener(_ -> Logger.debug("Новая строка")); testMenu.add(addLogMessageItem); } - return testMenu; } @@ -153,7 +149,7 @@ private void handleExit() { ); if (choice == JOptionPane.YES_OPTION) { - controller.handleExit(); + System.exit(0); } } diff --git a/src/main/java/robots/gui/MainController.java b/src/main/java/robots/gui/MainController.java index 51f5d3dd3..9ad9000fd 100644 --- a/src/main/java/robots/gui/MainController.java +++ b/src/main/java/robots/gui/MainController.java @@ -3,35 +3,20 @@ import java.awt.*; import robots.log.Logger; -import robots.log.RobotPositionSource; +import robots.log.RobotModel; public class MainController { - private final LogWindow logWindow; - private final GameWindow gameWindow; - private MainApplicationFrame frame; - private final RobotPositionWindow robotPositionWindow; + private final AppContext appContext; public MainController() { - this.logWindow = new LogWindow(Logger.getDefaultLogSource()); - this.gameWindow = new GameWindow(); - this.robotPositionWindow = new RobotPositionWindow(Logger.getrobotPositionModel()); + this.appContext = new AppContext(new LogWindow(Logger.getDefaultLogSource()), new GameWindow(), new RobotPositionWindow(RobotModel.getRobotPositionModel())); } public void createFrame() { - frame = new MainApplicationFrame(logWindow, gameWindow, this, robotPositionWindow); + MainApplicationFrame frame = new MainApplicationFrame(appContext); frame.pack(); frame.setVisible(true); frame.setExtendedState(Frame.MAXIMIZED_BOTH); } - public void onAddLogMessage() { - Logger.debug("Новая строка"); - } - - public void handleExit() { - if (frame != null) - frame.saveWindowStates(); - System.exit(0); - } - } diff --git a/src/main/java/robots/log/Logger.java b/src/main/java/robots/log/Logger.java index c34d4d311..5636d11a2 100644 --- a/src/main/java/robots/log/Logger.java +++ b/src/main/java/robots/log/Logger.java @@ -2,7 +2,6 @@ public final class Logger { private static final LogWindowSource defaultLogSource = new LogWindowSource(100); - private static final RobotPositionSource robotPositionModel = new RobotPositionSource(); private Logger() { } @@ -18,8 +17,4 @@ public static void error(String strMessage) { public static LogWindowSource getDefaultLogSource() { return defaultLogSource; } - - public static RobotPositionSource getrobotPositionModel() { - return robotPositionModel; - } } diff --git a/src/main/java/robots/log/RobotModel.java b/src/main/java/robots/log/RobotModel.java new file mode 100644 index 000000000..9950bf463 --- /dev/null +++ b/src/main/java/robots/log/RobotModel.java @@ -0,0 +1,11 @@ +package robots.log; + +public final class RobotModel { + private static final RobotPositionSource robotPositionModel = new RobotPositionSource(); + + private RobotModel() {} + + public static RobotPositionSource getRobotPositionModel() { + return robotPositionModel; + } +}