From d825d74b260717ef6cfb564fdf54c882fe7ebb43 Mon Sep 17 00:00:00 2001 From: showman-1 Date: Fri, 6 Mar 2026 13:50:08 +0500 Subject: [PATCH 1/5] add wind "Menu" and "exit" --- robots/src/gui/MainApplicationFrame.java | 85 ++++++++++++++++++------ 1 file changed, 63 insertions(+), 22 deletions(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 62e943e..1cb03df 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -10,6 +10,7 @@ import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; @@ -18,26 +19,26 @@ /** * Что требуется сделать: - * 1. Метод создания меню перегружен функционалом и трудно читается. + * 1. Метод создания меню перегружен функционалом и трудно читается. * Следует разделить его на серию более простых методов (или вообще выделить отдельный класс). * */ public class MainApplicationFrame extends JFrame { private final JDesktopPane desktopPane = new JDesktopPane(); - + public MainApplicationFrame() { //Make the big window be indented 50 pixels from each edge //of the screen. - int inset = 50; + int inset = 50; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setBounds(inset, inset, - screenSize.width - inset*2, - screenSize.height - inset*2); + screenSize.width - inset*2, + screenSize.height - inset*2); setContentPane(desktopPane); - - + + LogWindow logWindow = createLogWindow(); addWindow(logWindow); @@ -46,9 +47,9 @@ public MainApplicationFrame() { addWindow(gameWindow); setJMenuBar(generateMenuBar()); - setDefaultCloseOperation(EXIT_ON_CLOSE); + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); } - + protected LogWindow createLogWindow() { LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); @@ -59,21 +60,21 @@ protected LogWindow createLogWindow() 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); @@ -82,28 +83,42 @@ protected void addWindow(JInternalFrame frame) // 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); + //// menuItem.addActionListener(this); // menu.add(menuItem); -// +// // return menuBar; // } - + private JMenuBar generateMenuBar() { JMenuBar menuBar = new JMenuBar(); - + // НОВОЕ МЕНЮ "Файл" + JMenu fileMenu = new JMenu("Файл"); + fileMenu.setMnemonic(KeyEvent.VK_F); + + // Пункт "Выход" + { + JMenuItem exitMenuItem = new JMenuItem("Выход", KeyEvent.VK_X); + exitMenuItem.addActionListener((event) -> { + exitApplication(); + }); + fileMenu.add(exitMenuItem); + } + + menuBar.add(fileMenu); + JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( "Управление режимом отображения приложения"); - + { JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); systemLookAndFeel.addActionListener((event) -> { @@ -126,7 +141,7 @@ private JMenuBar generateMenuBar() testMenu.setMnemonic(KeyEvent.VK_T); testMenu.getAccessibleContext().setAccessibleDescription( "Тестовые команды"); - + { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); addLogMessageItem.addActionListener((event) -> { @@ -139,7 +154,7 @@ private JMenuBar generateMenuBar() menuBar.add(testMenu); return menuBar; } - + private void setLookAndFeel(String className) { try @@ -148,9 +163,35 @@ private void setLookAndFeel(String className) SwingUtilities.updateComponentTreeUI(this); } catch (ClassNotFoundException | InstantiationException - | IllegalAccessException | UnsupportedLookAndFeelException e) + | IllegalAccessException | UnsupportedLookAndFeelException e) { // just ignore } } + /** + * НОВЫЙ МЕТОД: Обработка выхода из приложения с подтверждением + */ + private void exitApplication() + { + // Настраиваем кнопки диалога на русском языке + Object[] options = {"Да", "Нет", "Отмена"}; + + int result = JOptionPane.showOptionDialog( + this, // родительский компонент + "Вы действительно хотите выйти из приложения?", // сообщение + "Подтверждение выхода", // заголовок + JOptionPane.YES_NO_CANCEL_OPTION, // тип опций + JOptionPane.QUESTION_MESSAGE, // тип сообщения + null, // иконка (по умолчанию) + options, // массив кнопок + options[1]); // кнопка по умолчанию ("Нет") + + // Обрабатываем результат + if (result == JOptionPane.YES_OPTION) { + // Пользователь подтвердил выход + Logger.debug("Приложение завершает работу"); + System.exit(0); + } + // В остальных случаях (Нет, Отмена, закрытие диалога) просто возвращаемся + } } From 2b494874df8857859aae526e2773dba84d808194 Mon Sep 17 00:00:00 2001 From: showman-1 Date: Fri, 6 Mar 2026 13:50:56 +0500 Subject: [PATCH 2/5] add wind "Menu" and "exit" --- robots/src/gui/MainApplicationFrame.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 1cb03df..e962254 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -186,7 +186,7 @@ private void exitApplication() options, // массив кнопок options[1]); // кнопка по умолчанию ("Нет") - // Обрабатываем результат + // Обрабатываем результа if (result == JOptionPane.YES_OPTION) { // Пользователь подтвердил выход Logger.debug("Приложение завершает работу"); From 16961b9706969b2b7aec25d5529e64e6c1e61378 Mon Sep 17 00:00:00 2001 From: showman-1 Date: Tue, 24 Mar 2026 14:55:19 +0500 Subject: [PATCH 3/5] division into methods --- robots/src/gui/MainApplicationFrame.java | 189 ++++++++++++----------- 1 file changed, 95 insertions(+), 94 deletions(-) diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index e962254..41c99bd 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -17,19 +17,11 @@ import log.Logger; -/** - * Что требуется сделать: - * 1. Метод создания меню перегружен функционалом и трудно читается. - * Следует разделить его на серию более простых методов (или вообще выделить отдельный класс). - * - */ public class MainApplicationFrame extends JFrame { private final JDesktopPane desktopPane = new JDesktopPane(); public MainApplicationFrame() { - //Make the big window be indented 50 pixels from each edge - //of the screen. int inset = 50; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setBounds(inset, inset, @@ -38,7 +30,6 @@ public MainApplicationFrame() { setContentPane(desktopPane); - LogWindow logWindow = createLogWindow(); addWindow(logWindow); @@ -46,7 +37,7 @@ public MainApplicationFrame() { gameWindow.setSize(400, 400); addWindow(gameWindow); - setJMenuBar(generateMenuBar()); + setJMenuBar(createMenuBar()); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); } @@ -67,92 +58,108 @@ protected void addWindow(JInternalFrame frame) frame.setVisible(true); } -// protected JMenuBar createMenuBar() { -// JMenuBar menuBar = new JMenuBar(); -// -// //Set up the lone menu. -// JMenu menu = new JMenu("Document"); -// menu.setMnemonic(KeyEvent.VK_D); -// menuBar.add(menu); -// -// //Set up the first menu item. -// JMenuItem menuItem = new JMenuItem("New"); -// menuItem.setMnemonic(KeyEvent.VK_N); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_N, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("new"); -//// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// //Set up the second menu item. -// menuItem = new JMenuItem("Quit"); -// menuItem.setMnemonic(KeyEvent.VK_Q); -// menuItem.setAccelerator(KeyStroke.getKeyStroke( -// KeyEvent.VK_Q, ActionEvent.ALT_MASK)); -// menuItem.setActionCommand("quit"); - //// menuItem.addActionListener(this); -// menu.add(menuItem); -// -// return menuBar; -// } - - private JMenuBar generateMenuBar() + /** + * Главный метод создания меню - собирает все части воедино + */ + private JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); - // НОВОЕ МЕНЮ "Файл" + + menuBar.add(createFileMenu()); + menuBar.add(createLookAndFeelMenu()); + menuBar.add(createTestMenu()); + + return menuBar; + } + + /** + * Создает меню "Файл" с пунктом "Выход" + */ + private JMenu createFileMenu() + { JMenu fileMenu = new JMenu("Файл"); fileMenu.setMnemonic(KeyEvent.VK_F); + fileMenu.add(createExitMenuItem()); + return fileMenu; + } - // Пункт "Выход" - { - JMenuItem exitMenuItem = new JMenuItem("Выход", KeyEvent.VK_X); - exitMenuItem.addActionListener((event) -> { - exitApplication(); - }); - fileMenu.add(exitMenuItem); - } - - menuBar.add(fileMenu); + /** + * Создает пункт меню "Выход" + */ + private JMenuItem createExitMenuItem() + { + JMenuItem exitMenuItem = new JMenuItem("Выход", KeyEvent.VK_X); + exitMenuItem.addActionListener((event) -> exitApplication()); + return exitMenuItem; + } + /** + * Создает меню "Режим отображения" с пунктами смены темы + */ + private JMenu createLookAndFeelMenu() + { JMenu lookAndFeelMenu = new JMenu("Режим отображения"); lookAndFeelMenu.setMnemonic(KeyEvent.VK_V); lookAndFeelMenu.getAccessibleContext().setAccessibleDescription( "Управление режимом отображения приложения"); - { - JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); - systemLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(systemLookAndFeel); - } + lookAndFeelMenu.add(createSystemLookAndFeelMenuItem()); + lookAndFeelMenu.add(createCrossplatformLookAndFeelMenuItem()); - { - JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); - crossplatformLookAndFeel.addActionListener((event) -> { - setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); - this.invalidate(); - }); - lookAndFeelMenu.add(crossplatformLookAndFeel); - } + return lookAndFeelMenu; + } + /** + * Создает пункт меню "Системная схема" + */ + private JMenuItem createSystemLookAndFeelMenuItem() + { + JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); + systemLookAndFeel.addActionListener((event) -> { + setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + this.invalidate(); + }); + return systemLookAndFeel; + } + + /** + * Создает пункт меню "Универсальная схема" + */ + private JMenuItem createCrossplatformLookAndFeelMenuItem() + { + JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); + crossplatformLookAndFeel.addActionListener((event) -> { + setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + this.invalidate(); + }); + return 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((event) -> { - Logger.debug("Новая строка"); - }); - testMenu.add(addLogMessageItem); - } + testMenu.add(createAddLogMessageMenuItem()); - menuBar.add(lookAndFeelMenu); - menuBar.add(testMenu); - return menuBar; + return testMenu; + } + + /** + * Создает пункт меню "Сообщение в лог" + */ + private JMenuItem createAddLogMessageMenuItem() + { + JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); + addLogMessageItem.addActionListener((event) -> { + Logger.debug("Новая строка"); + }); + return addLogMessageItem; } private void setLookAndFeel(String className) @@ -168,30 +175,24 @@ private void setLookAndFeel(String className) // just ignore } } - /** - * НОВЫЙ МЕТОД: Обработка выхода из приложения с подтверждением - */ + private void exitApplication() { - // Настраиваем кнопки диалога на русском языке Object[] options = {"Да", "Нет", "Отмена"}; int result = JOptionPane.showOptionDialog( - this, // родительский компонент - "Вы действительно хотите выйти из приложения?", // сообщение - "Подтверждение выхода", // заголовок - JOptionPane.YES_NO_CANCEL_OPTION, // тип опций - JOptionPane.QUESTION_MESSAGE, // тип сообщения - null, // иконка (по умолчанию) - options, // массив кнопок - options[1]); // кнопка по умолчанию ("Нет") - - // Обрабатываем результа + this, + "Вы действительно хотите выйти из приложения?", + "Подтверждение выхода", + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, + options, + options[1]); + if (result == JOptionPane.YES_OPTION) { - // Пользователь подтвердил выход Logger.debug("Приложение завершает работу"); System.exit(0); } - // В остальных случаях (Нет, Отмена, закрытие диалога) просто возвращаемся } -} +} \ No newline at end of file From db799567cacc491238434437461cd3a077d1fdb9 Mon Sep 17 00:00:00 2001 From: showman-1 Date: Tue, 7 Apr 2026 13:22:18 +0500 Subject: [PATCH 4/5] save size window --- robots/src/gui/MainApplicationFrame.java | 69 +++++++++-------- robots/src/gui/WindowStateManager.java | 98 ++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 31 deletions(-) create mode 100644 robots/src/gui/WindowStateManager.java diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 41c99bd..1e75a62 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -3,6 +3,8 @@ 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; @@ -20,8 +22,15 @@ public class MainApplicationFrame extends JFrame { private final JDesktopPane desktopPane = new JDesktopPane(); + private WindowStateManager stateManager; + private LogWindow logWindow; + private GameWindow gameWindow; public MainApplicationFrame() { + stateManager = new WindowStateManager(); + + stateManager.loadFromFile(); + int inset = 50; Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setBounds(inset, inset, @@ -30,21 +39,32 @@ public MainApplicationFrame() { setContentPane(desktopPane); - LogWindow logWindow = createLogWindow(); - addWindow(logWindow); + logWindow = createLogWindow(); + gameWindow = new GameWindow(); + gameWindow.setSize(400, 400); + + stateManager.applyWindowState(logWindow, "logWindow"); + stateManager.applyWindowState(gameWindow, "gameWindow"); - GameWindow gameWindow = new GameWindow(); - gameWindow.setSize(400, 400); + addWindow(logWindow); addWindow(gameWindow); setJMenuBar(createMenuBar()); + + // Обработчик закрытия окна setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + exitApplication(); + } + }); } protected LogWindow createLogWindow() { LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource()); - logWindow.setLocation(10,10); + logWindow.setLocation(10, 10); logWindow.setSize(300, 800); setMinimumSize(logWindow.getSize()); logWindow.pack(); @@ -58,23 +78,15 @@ protected void addWindow(JInternalFrame frame) frame.setVisible(true); } - /** - * Главный метод создания меню - собирает все части воедино - */ private JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); - menuBar.add(createFileMenu()); menuBar.add(createLookAndFeelMenu()); menuBar.add(createTestMenu()); - return menuBar; } - /** - * Создает меню "Файл" с пунктом "Выход" - */ private JMenu createFileMenu() { JMenu fileMenu = new JMenu("Файл"); @@ -83,9 +95,6 @@ private JMenu createFileMenu() return fileMenu; } - /** - * Создает пункт меню "Выход" - */ private JMenuItem createExitMenuItem() { JMenuItem exitMenuItem = new JMenuItem("Выход", KeyEvent.VK_X); @@ -93,9 +102,6 @@ private JMenuItem createExitMenuItem() return exitMenuItem; } - /** - * Создает меню "Режим отображения" с пунктами смены темы - */ private JMenu createLookAndFeelMenu() { JMenu lookAndFeelMenu = new JMenu("Режим отображения"); @@ -109,9 +115,6 @@ private JMenu createLookAndFeelMenu() return lookAndFeelMenu; } - /** - * Создает пункт меню "Системная схема" - */ private JMenuItem createSystemLookAndFeelMenuItem() { JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S); @@ -122,9 +125,6 @@ private JMenuItem createSystemLookAndFeelMenuItem() return systemLookAndFeel; } - /** - * Создает пункт меню "Универсальная схема" - */ private JMenuItem createCrossplatformLookAndFeelMenuItem() { JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S); @@ -135,9 +135,6 @@ private JMenuItem createCrossplatformLookAndFeelMenuItem() return crossplatformLookAndFeel; } - /** - * Создает меню "Тесты" с тестовыми командами - */ private JMenu createTestMenu() { JMenu testMenu = new JMenu("Тесты"); @@ -150,9 +147,6 @@ private JMenu createTestMenu() return testMenu; } - /** - * Создает пункт меню "Сообщение в лог" - */ private JMenuItem createAddLogMessageMenuItem() { JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S); @@ -191,8 +185,21 @@ private void exitApplication() options[1]); if (result == JOptionPane.YES_OPTION) { + saveWindowStates(); + Logger.debug("Приложение завершает работу"); System.exit(0); } } + + private void saveWindowStates() + { + if (logWindow != null) { + stateManager.saveWindowState(logWindow, "logWindow"); + } + if (gameWindow != null) { + stateManager.saveWindowState(gameWindow, "gameWindow"); + } + stateManager.saveToFile(); + } } \ No newline at end of file diff --git a/robots/src/gui/WindowStateManager.java b/robots/src/gui/WindowStateManager.java new file mode 100644 index 0000000..278b28d --- /dev/null +++ b/robots/src/gui/WindowStateManager.java @@ -0,0 +1,98 @@ +package gui; + +import java.awt.Point; +import java.io.*; +import java.util.Properties; +import javax.swing.JInternalFrame; + +public class WindowStateManager { + + private static final String CONFIG_FILE = System.getProperty("user.home") + + File.separator + + ".robot_game_config.properties"; + + private Properties properties; + + public WindowStateManager() { + properties = new Properties(); + } + + public void saveWindowState(JInternalFrame frame, String windowKey) { + try { + Point location = frame.getLocation(); + properties.setProperty(windowKey + ".x", String.valueOf(location.x)); + properties.setProperty(windowKey + ".y", String.valueOf(location.y)); + + properties.setProperty(windowKey + ".width", String.valueOf(frame.getWidth())); + properties.setProperty(windowKey + ".height", String.valueOf(frame.getHeight())); + + if (frame.isIcon()) { + properties.setProperty(windowKey + ".state", "ICONIFIED"); + } else if (frame.isMaximum()) { + properties.setProperty(windowKey + ".state", "MAXIMIZED"); + } else { + properties.setProperty(windowKey + ".state", "NORMAL"); + } + + } catch (Exception e) { + System.err.println("Ошибка сохранения состояния окна " + windowKey + ": " + e.getMessage()); + } + } + + public void saveToFile() { + try (FileOutputStream out = new FileOutputStream(CONFIG_FILE)) { + properties.store(out, "Robot Game Configuration"); + } catch (IOException e) { + System.err.println("Ошибка сохранения конфигурации: " + e.getMessage()); + } + } + + public boolean loadFromFile() { + File configFile = new File(CONFIG_FILE); + if (!configFile.exists()) { + return false; + } + + try (FileInputStream in = new FileInputStream(configFile)) { + properties.load(in); + return true; + } catch (IOException e) { + System.err.println("Ошибка загрузки конфигурации: " + e.getMessage()); + return false; + } + } + + public void applyWindowState(JInternalFrame frame, String windowKey) { + try { + String xStr = properties.getProperty(windowKey + ".x"); + String yStr = properties.getProperty(windowKey + ".y"); + if (xStr != null && yStr != null) { + frame.setLocation(Integer.parseInt(xStr), Integer.parseInt(yStr)); + } + + String widthStr = properties.getProperty(windowKey + ".width"); + String heightStr = properties.getProperty(windowKey + ".height"); + if (widthStr != null && heightStr != null) { + frame.setSize(Integer.parseInt(widthStr), Integer.parseInt(heightStr)); + } + + String state = properties.getProperty(windowKey + ".state"); + if (state != null) { + switch (state) { + case "ICONIFIED": + frame.setIcon(true); + break; + case "MAXIMIZED": + try { + frame.setMaximum(true); + } catch (Exception e) { + } + break; + } + } + + } catch (Exception e) { + System.err.println("Ошибка восстановления окна " + windowKey + ": " + e.getMessage()); + } + } +} \ No newline at end of file From ca33453247b81ddc893a79178d18e2b016f17902 Mon Sep 17 00:00:00 2001 From: showman-1 Date: Tue, 14 Apr 2026 14:34:33 +0500 Subject: [PATCH 5/5] moving reading and writing of the config to a separate class --- robots/src/gui/MainApplicationFrame.java | 2 +- robots/src/gui/WindowStateLoader.java | 65 ++++++++++++++++++ robots/src/gui/WindowStateManager.java | 87 +++--------------------- robots/src/gui/WindowStateSaver.java | 44 ++++++++++++ 4 files changed, 121 insertions(+), 77 deletions(-) create mode 100644 robots/src/gui/WindowStateLoader.java create mode 100644 robots/src/gui/WindowStateSaver.java diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java index 1e75a62..c472886 100644 --- a/robots/src/gui/MainApplicationFrame.java +++ b/robots/src/gui/MainApplicationFrame.java @@ -172,7 +172,7 @@ private void setLookAndFeel(String className) private void exitApplication() { - Object[] options = {"Да", "Нет", "Отмена"}; + Object[] options = {"Да", "Нет"}; int result = JOptionPane.showOptionDialog( this, diff --git a/robots/src/gui/WindowStateLoader.java b/robots/src/gui/WindowStateLoader.java new file mode 100644 index 0000000..0862366 --- /dev/null +++ b/robots/src/gui/WindowStateLoader.java @@ -0,0 +1,65 @@ +package gui; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Properties; +import javax.swing.JInternalFrame; + +public class WindowStateLoader { + + private static final String CONFIG_FILE = System.getProperty("user.home") + + File.separator + + ".robot_game_config.properties"; + + public Properties loadFromFile() { + Properties properties = new Properties(); + File configFile = new File(CONFIG_FILE); + + if (!configFile.exists()) { + return properties; + } + + try (FileInputStream in = new FileInputStream(configFile)) { + properties.load(in); + } catch (IOException e) { + System.err.println("Ошибка загрузки конфигурации: " + e.getMessage()); + } + + return properties; + } + + public void applyWindowState(Properties properties, JInternalFrame frame, String windowKey) { + try { + String xStr = properties.getProperty(windowKey + ".x"); + String yStr = properties.getProperty(windowKey + ".y"); + if (xStr != null && yStr != null) { + frame.setLocation(Integer.parseInt(xStr), Integer.parseInt(yStr)); + } + + String widthStr = properties.getProperty(windowKey + ".width"); + String heightStr = properties.getProperty(windowKey + ".height"); + if (widthStr != null && heightStr != null) { + frame.setSize(Integer.parseInt(widthStr), Integer.parseInt(heightStr)); + } + + String state = properties.getProperty(windowKey + ".state"); + if (state != null) { + switch (state) { + case "ICONIFIED": + frame.setIcon(true); + break; + case "MAXIMIZED": + try { + frame.setMaximum(true); + } catch (Exception e) { + } + break; + } + } + + } catch (Exception e) { + System.err.println("Ошибка восстановления окна " + windowKey + ": " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/robots/src/gui/WindowStateManager.java b/robots/src/gui/WindowStateManager.java index 278b28d..2a49bf1 100644 --- a/robots/src/gui/WindowStateManager.java +++ b/robots/src/gui/WindowStateManager.java @@ -1,98 +1,33 @@ package gui; -import java.awt.Point; -import java.io.*; import java.util.Properties; import javax.swing.JInternalFrame; public class WindowStateManager { - private static final String CONFIG_FILE = System.getProperty("user.home") + - File.separator + - ".robot_game_config.properties"; - private Properties properties; + private WindowStateSaver saver; + private WindowStateLoader loader; public WindowStateManager() { - properties = new Properties(); + this.properties = new Properties(); + this.saver = new WindowStateSaver(); + this.loader = new WindowStateLoader(); } - public void saveWindowState(JInternalFrame frame, String windowKey) { - try { - Point location = frame.getLocation(); - properties.setProperty(windowKey + ".x", String.valueOf(location.x)); - properties.setProperty(windowKey + ".y", String.valueOf(location.y)); - - properties.setProperty(windowKey + ".width", String.valueOf(frame.getWidth())); - properties.setProperty(windowKey + ".height", String.valueOf(frame.getHeight())); - - if (frame.isIcon()) { - properties.setProperty(windowKey + ".state", "ICONIFIED"); - } else if (frame.isMaximum()) { - properties.setProperty(windowKey + ".state", "MAXIMIZED"); - } else { - properties.setProperty(windowKey + ".state", "NORMAL"); - } - - } catch (Exception e) { - System.err.println("Ошибка сохранения состояния окна " + windowKey + ": " + e.getMessage()); - } + public void loadFromFile() { + this.properties = loader.loadFromFile(); } public void saveToFile() { - try (FileOutputStream out = new FileOutputStream(CONFIG_FILE)) { - properties.store(out, "Robot Game Configuration"); - } catch (IOException e) { - System.err.println("Ошибка сохранения конфигурации: " + e.getMessage()); - } + saver.saveToFile(properties); } - public boolean loadFromFile() { - File configFile = new File(CONFIG_FILE); - if (!configFile.exists()) { - return false; - } - - try (FileInputStream in = new FileInputStream(configFile)) { - properties.load(in); - return true; - } catch (IOException e) { - System.err.println("Ошибка загрузки конфигурации: " + e.getMessage()); - return false; - } + public void saveWindowState(JInternalFrame frame, String windowKey) { + saver.saveWindowState(properties, frame, windowKey); } public void applyWindowState(JInternalFrame frame, String windowKey) { - try { - String xStr = properties.getProperty(windowKey + ".x"); - String yStr = properties.getProperty(windowKey + ".y"); - if (xStr != null && yStr != null) { - frame.setLocation(Integer.parseInt(xStr), Integer.parseInt(yStr)); - } - - String widthStr = properties.getProperty(windowKey + ".width"); - String heightStr = properties.getProperty(windowKey + ".height"); - if (widthStr != null && heightStr != null) { - frame.setSize(Integer.parseInt(widthStr), Integer.parseInt(heightStr)); - } - - String state = properties.getProperty(windowKey + ".state"); - if (state != null) { - switch (state) { - case "ICONIFIED": - frame.setIcon(true); - break; - case "MAXIMIZED": - try { - frame.setMaximum(true); - } catch (Exception e) { - } - break; - } - } - - } catch (Exception e) { - System.err.println("Ошибка восстановления окна " + windowKey + ": " + e.getMessage()); - } + loader.applyWindowState(properties, frame, windowKey); } } \ No newline at end of file diff --git a/robots/src/gui/WindowStateSaver.java b/robots/src/gui/WindowStateSaver.java new file mode 100644 index 0000000..5db619c --- /dev/null +++ b/robots/src/gui/WindowStateSaver.java @@ -0,0 +1,44 @@ +package gui; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; +import javax.swing.JInternalFrame; + +public class WindowStateSaver { + + private static final String CONFIG_FILE = System.getProperty("user.home") + + File.separator + + ".robot_game_config.properties"; + + public void saveWindowState(Properties properties, JInternalFrame frame, String windowKey) { + try { + java.awt.Point location = frame.getLocation(); + properties.setProperty(windowKey + ".x", String.valueOf(location.x)); + properties.setProperty(windowKey + ".y", String.valueOf(location.y)); + + properties.setProperty(windowKey + ".width", String.valueOf(frame.getWidth())); + properties.setProperty(windowKey + ".height", String.valueOf(frame.getHeight())); + + if (frame.isIcon()) { + properties.setProperty(windowKey + ".state", "ICONIFIED"); + } else if (frame.isMaximum()) { + properties.setProperty(windowKey + ".state", "MAXIMIZED"); + } else { + properties.setProperty(windowKey + ".state", "NORMAL"); + } + + } catch (Exception e) { + System.err.println("Ошибка сохранения состояния окна " + windowKey + ": " + e.getMessage()); + } + } + + public void saveToFile(Properties properties) { + try (FileOutputStream out = new FileOutputStream(CONFIG_FILE)) { + properties.store(out, "Robot Game Configuration"); + } catch (IOException e) { + System.err.println("Ошибка сохранения конфигурации: " + e.getMessage()); + } + } +} \ No newline at end of file