diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..b58b603
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,5 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..f5bd2df
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..514065c
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/.idea/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200.iml" "b/.idea/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200.iml"
new file mode 100644
index 0000000..8df936b
--- /dev/null
+++ "b/.idea/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200.iml"
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$1.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$1.class"
new file mode 100644
index 0000000..3f0bf76
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$1.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$2.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$2.class"
new file mode 100644
index 0000000..206d146
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$2.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$3.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$3.class"
new file mode 100644
index 0000000..7967164
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer$3.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer.class"
new file mode 100644
index 0000000..5acf845
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameVisualizer.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameWindow.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameWindow.class"
new file mode 100644
index 0000000..3de6a18
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/GameWindow.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/LogWindow.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/LogWindow.class"
new file mode 100644
index 0000000..6905baa
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/LogWindow.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame$1.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame$1.class"
new file mode 100644
index 0000000..0ce8269
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame$1.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame.class"
new file mode 100644
index 0000000..fcf25cc
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MainApplicationFrame.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MenuBarFactory.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MenuBarFactory.class"
new file mode 100644
index 0000000..5077bfb
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/MenuBarFactory.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/RobotsProgram.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/RobotsProgram.class"
new file mode 100644
index 0000000..78f21e6
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/gui/RobotsProgram.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogChangeListener.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogChangeListener.class"
new file mode 100644
index 0000000..3581271
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogChangeListener.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogEntry.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogEntry.class"
new file mode 100644
index 0000000..1fb6da6
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogEntry.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogLevel.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogLevel.class"
new file mode 100644
index 0000000..0094a34
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogLevel.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogWindowSource.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogWindowSource.class"
new file mode 100644
index 0000000..3f7b03c
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/LogWindowSource.class" differ
diff --git "a/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/Logger.class" "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/Logger.class"
new file mode 100644
index 0000000..75ec665
Binary files /dev/null and "b/out/production/\320\276\320\276\320\277 4 \321\201\320\265\320\274\320\265\321\201\321\202\321\200/log/Logger.class" differ
diff --git a/robots/src/gui/MainApplicationFrame.java b/robots/src/gui/MainApplicationFrame.java
index 62e943e..1e3ef54 100644
--- a/robots/src/gui/MainApplicationFrame.java
+++ b/robots/src/gui/MainApplicationFrame.java
@@ -2,14 +2,17 @@
import java.awt.Dimension;
import java.awt.Toolkit;
-import java.awt.event.KeyEvent;
-
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import javax.swing.JOptionPane;
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;
@@ -25,19 +28,18 @@
public class MainApplicationFrame extends JFrame
{
private final JDesktopPane desktopPane = new JDesktopPane();
-
+ private static final String CONFIG_FILE = System.getProperty("user.home") + File.separator + ".robot-config.properties";
+
public MainApplicationFrame() {
- //Make the big window be indented 50 pixels from each edge
- //of the screen.
- int inset = 50;
+ loadWindowState();
+ 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);
@@ -45,10 +47,36 @@ public MainApplicationFrame() {
gameWindow.setSize(400, 400);
addWindow(gameWindow);
- setJMenuBar(generateMenuBar());
- setDefaultCloseOperation(EXIT_ON_CLOSE);
+ loadInternalWindowsState();
+
+ MenuBarFactory menuFactory = new MenuBarFactory(this);
+ setJMenuBar(menuFactory.createMenuBar());
+
+ //закрытие приложения через крестик
+ addWindowListener(new WindowAdapter() {
+ @Override
+ public void windowClosing(WindowEvent e) {
+ exitApplication();
+ }
+ });
}
-
+
+ public void exitApplication() {
+ //так как в UIManager уже установлен русский язык, то не нужно делать это дополнительно
+ saveWindowState();
+ int result = JOptionPane.showConfirmDialog(
+ this,
+ "Вы действительно хотите выйти из приложения?",
+ "Подтверждение выхода",
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE
+ );
+
+ if (result == JOptionPane.YES_OPTION) {
+ System.exit(0);
+ }
+ }
+
protected LogWindow createLogWindow()
{
LogWindow logWindow = new LogWindow(Logger.getDefaultLogSource());
@@ -59,98 +87,154 @@ 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);
-// 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(
- "Управление режимом отображения приложения");
-
- {
- JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S);
- systemLookAndFeel.addActionListener((event) -> {
- setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- this.invalidate();
- });
- lookAndFeelMenu.add(systemLookAndFeel);
- }
-
- {
- JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S);
- crossplatformLookAndFeel.addActionListener((event) -> {
- setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
- this.invalidate();
- });
- lookAndFeelMenu.add(crossplatformLookAndFeel);
- }
- 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);
- }
-
- menuBar.add(lookAndFeelMenu);
- menuBar.add(testMenu);
- return menuBar;
- }
-
- private void setLookAndFeel(String className)
+ /**
+ * Метод для смены Look&Feel (публичный, чтобы был доступен из MenuBarFactory)
+ */
+ public void setLookAndFeel(String className)
{
try
{
UIManager.setLookAndFeel(className);
+ RobotsProgram.setRussianUIManagerText();
SwingUtilities.updateComponentTreeUI(this);
}
catch (ClassNotFoundException | InstantiationException
- | IllegalAccessException | UnsupportedLookAndFeelException e)
+ | IllegalAccessException | UnsupportedLookAndFeelException e)
{
// just ignore
}
}
+
+ /**
+ * Загружает состояние главного окна из файла конфигурации.
+ * Если файл отсутствует, устанавливает размеры по умолчанию.
+ */
+ private void loadWindowState() {
+ Properties props = new Properties();
+ File configFile = new File(CONFIG_FILE);
+ if (!configFile.exists()) {
+ // геометрия по умолчанию (как было в конструкторе)
+ int inset = 50;
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ setBounds(inset, inset,
+ screenSize.width - inset * 2,
+ screenSize.height - inset * 2);
+ return;
+ }
+
+ try (FileInputStream fis = new FileInputStream(configFile)) {
+ props.load(fis);
+
+ int x = Integer.parseInt(props.getProperty("main.x", "50"));
+ int y = Integer.parseInt(props.getProperty("main.y", "50"));
+ int width = Integer.parseInt(props.getProperty("main.width", "800"));
+ int height = Integer.parseInt(props.getProperty("main.height", "600"));
+ int state = Integer.parseInt(props.getProperty("main.state", String.valueOf(JFrame.NORMAL)));
+
+ setBounds(x, y, width, height);
+ setExtendedState(state);
+ } catch (IOException | NumberFormatException e) {
+ Logger.debug("Не удалось загрузить конфигурацию: " + e.getMessage());
+ // в случае ошибки используем геометрию по умолчанию
+ int inset = 50;
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ setBounds(inset, inset,
+ screenSize.width - inset * 2,
+ screenSize.height - inset * 2);
+ }
+ }
+
+ /*
+ * Сохраняет состояние главного окна и всех внутренних окон в файл.
+ */
+ private void saveWindowState() {
+ Properties props = new Properties();
+
+ // Главное окно
+ props.setProperty("main.x", String.valueOf(getX()));
+ props.setProperty("main.y", String.valueOf(getY()));
+ props.setProperty("main.width", String.valueOf(getWidth()));
+ props.setProperty("main.height", String.valueOf(getHeight()));
+ props.setProperty("main.state", String.valueOf(getExtendedState()));
+
+ // Внутренние окна
+ JInternalFrame[] frames = desktopPane.getAllFrames();
+ for (int i = 0; i < frames.length; i++) {
+ JInternalFrame f = frames[i];
+ String title = f.getTitle();
+ if (title == null || title.isEmpty()) continue;
+
+ String prefix = "window." + i + ".";
+ props.setProperty(prefix + "title", title);
+ props.setProperty(prefix + "x", String.valueOf(f.getX()));
+ props.setProperty(prefix + "y", String.valueOf(f.getY()));
+ props.setProperty(prefix + "width", String.valueOf(f.getWidth()));
+ props.setProperty(prefix + "height", String.valueOf(f.getHeight()));
+ props.setProperty(prefix + "icon", String.valueOf(f.isIcon()));
+ props.setProperty(prefix + "maximized", String.valueOf(f.isMaximum()));
+ }
+
+ try (FileOutputStream fos = new FileOutputStream(CONFIG_FILE)) {
+ props.store(fos, "Robot program configuration");
+ } catch (IOException e) {
+ Logger.debug("Не удалось сохранить конфигурацию: " + e.getMessage());
+ }
+ }
+
+ /**
+ * Восстанавливает состояние внутренних окон после их создания.
+ */
+ private void loadInternalWindowsState() {
+ Properties props = new Properties();
+ File configFile = new File(CONFIG_FILE);
+ if (!configFile.exists()) return;
+
+ try (FileInputStream fis = new FileInputStream(configFile)) {
+ props.load(fis);
+
+ JInternalFrame[] frames = desktopPane.getAllFrames();
+ for (JInternalFrame frame : frames) {
+ String title = frame.getTitle();
+ if (title == null) continue;
+
+ // Ищем запись с таким же заголовком
+ for (String key : props.stringPropertyNames()) {
+ if (key.endsWith(".title") && props.getProperty(key).equals(title)) {
+ String prefix = key.substring(0, key.length() - 6); // убираем ".title"
+ try {
+ int x = Integer.parseInt(props.getProperty(prefix + ".x", "0"));
+ int y = Integer.parseInt(props.getProperty(prefix + ".y", "0"));
+ int w = Integer.parseInt(props.getProperty(prefix + ".width", "300"));
+ int h = Integer.parseInt(props.getProperty(prefix + ".height", "200"));
+ boolean icon = Boolean.parseBoolean(props.getProperty(prefix + ".icon", "false"));
+ boolean maximized = Boolean.parseBoolean(props.getProperty(prefix + ".maximized", "false"));
+
+ frame.setBounds(x, y, w, h);
+ try {
+ if (maximized) {
+ frame.setMaximum(true);
+ } else if (icon) {
+ frame.setIcon(true);
+ }
+ } catch (java.beans.PropertyVetoException e) {
+ Logger.debug("Не удалось установить состояние окна " + title + ": " + e.getMessage());
+ }
+ } catch (NumberFormatException e) {
+ Logger.debug("Ошибка парсинга конфигурации для окна " + title);
+ }
+ break;
+ }
+ }
+ }
+ } catch (IOException e) {
+ Logger.debug("Не удалось загрузить конфигурацию внутренних окон: " + e.getMessage());
+ }
+ }
}
diff --git a/robots/src/gui/MenuBarFactory.java b/robots/src/gui/MenuBarFactory.java
new file mode 100644
index 0000000..c286689
--- /dev/null
+++ b/robots/src/gui/MenuBarFactory.java
@@ -0,0 +1,123 @@
+package gui;
+
+import java.awt.event.KeyEvent;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.UIManager;
+import log.Logger;
+
+/**
+ * Фабрика для создания строки меню приложения
+ */
+public class MenuBarFactory {
+
+ private final MainApplicationFrame frame;
+
+ public MenuBarFactory(MainApplicationFrame frame) {
+ this.frame = frame;
+ }
+
+ /**
+ * Создает главную строку меню
+ */
+ public 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.getAccessibleContext().setAccessibleDescription(
+ "Управление файлами и приложением");
+
+ fileMenu.add(createExitMenuItem());
+
+ return fileMenu;
+ }
+
+ /**
+ * Создает пункт меню для выхода из приложения
+ */
+ private JMenuItem createExitMenuItem() {
+ JMenuItem exitMenuItem = new JMenuItem("Выход", KeyEvent.VK_X);
+ exitMenuItem.addActionListener((event) -> {
+ frame.exitApplication();
+ });
+ return exitMenuItem;
+ }
+
+
+ /**
+ * Создает меню "Режим отображения"
+ */
+ private JMenu createLookAndFeelMenu() {
+ JMenu lookAndFeelMenu = new JMenu("Режим отображения");
+ lookAndFeelMenu.setMnemonic(KeyEvent.VK_V);
+ lookAndFeelMenu.getAccessibleContext().setAccessibleDescription(
+ "Управление режимом отображения приложения");
+
+ lookAndFeelMenu.add(createSystemLookAndFeelItem());
+ lookAndFeelMenu.add(createCrossPlatformLookAndFeelItem());
+
+ return lookAndFeelMenu;
+ }
+
+ /**
+ * Создает пункт меню для системной схемы оформления
+ */
+ private JMenuItem createSystemLookAndFeelItem() {
+ JMenuItem systemLookAndFeel = new JMenuItem("Системная схема", KeyEvent.VK_S);
+ systemLookAndFeel.addActionListener((event) -> {
+ frame.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ frame.invalidate();
+ });
+ return systemLookAndFeel;
+ }
+
+ /**
+ * Создает пункт меню для универсальной схемы оформления
+ */
+ private JMenuItem createCrossPlatformLookAndFeelItem() {
+ JMenuItem crossplatformLookAndFeel = new JMenuItem("Универсальная схема", KeyEvent.VK_S);
+ crossplatformLookAndFeel.addActionListener((event) -> {
+ frame.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+ frame.invalidate();
+ });
+ return crossplatformLookAndFeel;
+ }
+
+ /**
+ * Создает меню "Тесты"
+ */
+ private JMenu createTestMenu() {
+ JMenu testMenu = new JMenu("Тесты");
+ testMenu.setMnemonic(KeyEvent.VK_T);
+ testMenu.getAccessibleContext().setAccessibleDescription(
+ "Тестовые команды");
+
+ testMenu.add(createAddLogMessageItem());
+
+ return testMenu;
+ }
+
+ /**
+ * Создает пункт меню для добавления сообщения в лог
+ */
+ private JMenuItem createAddLogMessageItem() {
+ JMenuItem addLogMessageItem = new JMenuItem("Сообщение в лог", KeyEvent.VK_S);
+ addLogMessageItem.addActionListener((event) -> {
+ Logger.debug("Новая строка");
+ });
+ return addLogMessageItem;
+ }
+}
diff --git a/robots/src/gui/RobotsProgram.java b/robots/src/gui/RobotsProgram.java
index ae0930a..468cc39 100644
--- a/robots/src/gui/RobotsProgram.java
+++ b/robots/src/gui/RobotsProgram.java
@@ -1,25 +1,96 @@
package gui;
import java.awt.Frame;
-
+import java.util.Locale;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class RobotsProgram
{
public static void main(String[] args) {
- try {
- UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
+ Locale.setDefault(new Locale("ru", "RU"));
+ setRussianUIManagerText();
+ try {
+ UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
// UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
- } catch (Exception e) {
- e.printStackTrace();
- }
- SwingUtilities.invokeLater(() -> {
- MainApplicationFrame frame = new MainApplicationFrame();
- frame.pack();
- frame.setVisible(true);
- frame.setExtendedState(Frame.MAXIMIZED_BOTH);
- });
- }}
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ SwingUtilities.invokeLater(() -> {
+ MainApplicationFrame frame = new MainApplicationFrame();
+ frame.pack();
+ frame.setVisible(true);
+ frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+ });
+ }
+
+ protected static void setRussianUIManagerText() {
+ // JOptionPane
+ UIManager.put("OptionPane.yesButtonText", "Да");
+ UIManager.put("OptionPane.noButtonText", "Нет");
+ UIManager.put("OptionPane.cancelButtonText", "Отмена");
+ UIManager.put("OptionPane.okButtonText", "OK");
+ UIManager.put("OptionPane.titleText", "Выберите опцию");
+
+ // JFileChooser
+ UIManager.put("FileChooser.openButtonText", "Открыть");
+ UIManager.put("FileChooser.openButtonToolTipText", "Открыть выбранный файл");
+ UIManager.put("FileChooser.saveButtonText", "Сохранить");
+ UIManager.put("FileChooser.saveButtonToolTipText", "Сохранить выбранный файл");
+ UIManager.put("FileChooser.cancelButtonText", "Отмена");
+ UIManager.put("FileChooser.cancelButtonToolTipText", "Отменить выбор");
+ UIManager.put("FileChooser.directoryOpenButtonText", "Открыть");
+ UIManager.put("FileChooser.directoryOpenButtonToolTipText", "Открыть выбранную папку");
+
+ UIManager.put("FileChooser.lookInLabelText", "Папка:");
+ UIManager.put("FileChooser.fileNameLabelText", "Имя файла:");
+ UIManager.put("FileChooser.filesOfTypeLabelText", "Тип файлов:");
+ UIManager.put("FileChooser.upFolderToolTipText", "На уровень вверх");
+ UIManager.put("FileChooser.homeFolderToolTipText", "Домашняя папка");
+ UIManager.put("FileChooser.newFolderToolTipText", "Создать новую папку");
+ UIManager.put("FileChooser.listViewButtonToolTipText", "Список");
+ UIManager.put("FileChooser.detailsViewButtonToolTipText", "Таблица");
+ UIManager.put("FileChooser.fileNameHeaderText", "Имя");
+ UIManager.put("FileChooser.fileSizeHeaderText", "Размер");
+ UIManager.put("FileChooser.fileTypeHeaderText", "Тип");
+ UIManager.put("FileChooser.fileDateHeaderText", "Изменен");
+ UIManager.put("FileChooser.fileAttrHeaderText", "Атрибуты");
+
+ UIManager.put("FileChooser.acceptAllFileFilterText", "Все файлы");
+ UIManager.put("FileChooser.newFolderDialogTitle", "Новая папка");
+ UIManager.put("FileChooser.newFolderPromptText", "Имя новой папки:");
+
+ // JColorChooser
+ UIManager.put("ColorChooser.previewText", "Предпросмотр");
+ UIManager.put("ColorChooser.okText", "OK");
+ UIManager.put("ColorChooser.cancelText", "Отмена");
+ UIManager.put("ColorChooser.resetText", "Сброс");
+ UIManager.put("ColorChooser.sampleText", "Образец текста");
+
+ UIManager.put("ColorChooser.swatchesNameText", "Образцы");
+ UIManager.put("ColorChooser.swatchesRecentText", "Последние:");
+ UIManager.put("ColorChooser.hsvNameText", "HSV");
+ UIManager.put("ColorChooser.hslNameText", "HSL");
+ UIManager.put("ColorChooser.rgbNameText", "RGB");
+ UIManager.put("ColorChooser.cmykNameText", "CMYK");
+
+ UIManager.put("ColorChooser.hueText", "Оттенок");
+ UIManager.put("ColorChooser.saturationText", "Насыщенность");
+ UIManager.put("ColorChooser.valueText", "Значение");
+ UIManager.put("ColorChooser.lightnessText", "Освещенность");
+ UIManager.put("ColorChooser.redText", "Красный");
+ UIManager.put("ColorChooser.greenText", "Зеленый");
+ UIManager.put("ColorChooser.blueText", "Синий");
+ UIManager.put("ColorChooser.cyanText", "Голубой");
+ UIManager.put("ColorChooser.magentaText", "Пурпурный");
+ UIManager.put("ColorChooser.yellowText", "Желтый");
+ UIManager.put("ColorChooser.blackText", "Черный");
+
+ // JOptionPane (дополнительные настройки)
+ UIManager.put("OptionPane.inputDialogTitle", "Ввод данных");
+ UIManager.put("OptionPane.messageDialogTitle", "Сообщение");
+ UIManager.put("OptionPane.titleText", "Выберите опцию");
+ }
+}