# Configuration and Persistence > **Relevant source files** > * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java) > * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java) > * [src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java) ## Purpose and Scope The Configuration and Persistence system manages two distinct categories of application data: durable user preferences and ephemeral runtime state. This dual-persistence architecture separates configuration settings that survive across installations from session-specific UI state that changes during normal operation. This page covers the overall architecture and integration of both persistence subsystems. For detailed information about specific components, see: * [ConfigManager](ConfigManager) - Configuration loading, saving, and language discovery * [Configuration Files and Settings](Configuration-Files-and-Settings) - config.cfg structure and Config class fields * [CacheManager](CacheManager) - Runtime state caching, cache.json structure, and window management For information about how configuration integrates with the UI, see [Settings Dialog](Settings-Dialog). **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L1-L133](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L1-L133) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L1-L62](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L1-L62) --- ## Architecture Overview The persistence system employs a dual-manager architecture that separates durable configuration from volatile runtime state: ### Persistence Architecture Diagram ```mermaid flowchart TD ConfigStatic["ConfigManager static block
lines 25-29"] CacheStatic["CacheManager static field
line 17"] ConfigManager["ConfigManager
Static Utility Class"] CacheManager["CacheManager
Static Utility Class"] ConfigObj["Config
User Preferences
lines 31-44"] CacheObj["Cache
Runtime State
CacheManager:23-28"] ConfigFile["config.cfg
CONFIG_DIR"] CacheFile["cache.json
CACHE_PATH"] FileUtil["FileUtil
getLocalStoragePath()"] Gson["Gson
JSON Serialization"] SettingsDialog["SettingsDialog
reads/writes config"] MacroSettingsDialog["MacroSettingsDialog
reads/writes config"] ExitDialog["ExitDialog
reads/writes cache"] MainFrame["MainFrame
reads config and cache"] MacroManager["MacroManager
reads config"] ConfigStatic --> ConfigManager CacheStatic --> CacheManager ConfigManager --> ConfigObj CacheManager --> CacheObj ConfigManager --> Gson ConfigManager --> FileUtil CacheManager --> Gson CacheManager --> FileUtil ConfigObj --> ConfigFile CacheObj --> CacheFile FileUtil --> ConfigFile FileUtil --> CacheFile SettingsDialog --> ConfigManager MacroSettingsDialog --> ConfigManager ExitDialog --> CacheManager MainFrame --> ConfigManager MainFrame --> CacheManager MacroManager --> ConfigManager subgraph Consumers ["Consumers"] SettingsDialog MacroSettingsDialog ExitDialog MainFrame MacroManager end subgraph subGraph4 ["File I/O"] FileUtil Gson end subgraph subGraph3 ["Persistence Layer"] ConfigFile CacheFile end subgraph subGraph2 ["Data Objects"] ConfigObj CacheObj end subgraph subGraph1 ["Manager Layer"] ConfigManager CacheManager end subgraph subGraph0 ["Static Initialization"] ConfigStatic CacheStatic end ``` **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L14-L29](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L14-L29) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L13-L17](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L13-L17) * [src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java L1-L103](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java#L1-L103) --- ## Persistence Components The system consists of two primary manager classes that work in parallel to manage different types of application state: ### ConfigManager `ConfigManager` is a static utility class that manages durable user preferences. It exposes a single public static field: | Field | Type | Purpose | | --- | --- | --- | | `config` | `Config` | Application-level settings (language, theme, hotkeys, macro settings) | The field is initialized in a static block [ConfigManager.java L25-L29](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ConfigManager.java#L25-L29) ensuring configuration is loaded before any other application code executes. **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L14-L29](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L14-L29) ### CacheManager `CacheManager` is a static utility class that manages ephemeral runtime state. It exposes a single public static field: | Field | Type | Purpose | | --- | --- | --- | | `cache` | `Cache` | Runtime UI state (last used directories, window sizes, exit preferences) | The field is initialized during class loading [CacheManager.java L17](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/CacheManager.java#L17-L17) loading cached state from the previous session. **Sources:** [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L13-L17](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L13-L17) ### Data Structure Class Diagram ```mermaid classDiagram class Config { +boolean followSystemSettings +String lang +boolean enableDarkMode +boolean enableDefaultStorage +String defaultMmcStoragePath +boolean enableQuickMode +boolean allowLongStr +String readjustFrameMode +Map keyMap +boolean enableCustomMacroSettings +int repeatTime +double repeatDelay } class Cache { +String lastLoadDirectory +String lastSaveDirectory +Map windowSizeMap +String defaultCloseOperation } class ConfigManager { +static String CONFIG_DIR +static Config config +static Config loadConfig() +static void saveConfig(Config) +static void reloadConfig() +static String[] getAvailableLangs() } class CacheManager { +static Cache cache +static void reloadCache() +static void saveCache() } ConfigManager --> Config CacheManager --> Cache ``` **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L31-L44](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L31-L44) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L23-L28](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L23-L28) ### Config Fields Reference | Field Name | Type | Default Value | Purpose | | --- | --- | --- | --- | | `followSystemSettings` | `boolean` | `true` | When enabled, synchronizes `lang` and `enableDarkMode` with OS settings | | `lang` | `String` | `"zh_cn"` | Current language code (e.g., "en_us", "zh_cn", "ja_jp") | | `enableDarkMode` | `boolean` | `false` | Dark theme enabled state | | `enableDefaultStorage` | `boolean` | `false` | When true, uses `defaultMmcStoragePath` for file operations | | `defaultMmcStoragePath` | `String` | `""` (empty) | Default directory for saving/loading .mmc macro files | | `enableQuickMode` | `boolean` | `false` | Enables quick playback mode (ignores recorded delays) | | `allowLongStr` | `boolean` | `false` | Allows long strings in UI components | | `readjustFrameMode` | `String` | `"STANDARDIZED"` | Frame resize mode: `MIXED`, `STANDARDIZED`, or `MEMORIZED` | | `keyMap` | `Map` | `new HashMap<>()` | Custom hotkey assignments (e.g., "record" → "F2") | | `enableCustomMacroSettings` | `boolean` | `false` | Enables per-macro custom settings | | `repeatTime` | `int` | `1` | Number of times to repeat macro playback | | `repeatDelay` | `double` | `0` | Delay in seconds between macro repetitions | **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L31-L44](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L31-L44) ### Cache Fields Reference | Field Name | Type | Default Value | Purpose | | --- | --- | --- | --- | | `lastLoadDirectory` | `String` | `""` (empty) | Last directory used for loading macro files | | `lastSaveDirectory` | `String` | `""` (empty) | Last directory used for saving macro files | | `windowSizeMap` | `Map` | `new HashMap<>()` | Stores window sizes by window name | | `defaultCloseOperation` | `String` | `""` (empty) | Default close behavior: `exit_on_close`, `minimize_to_tray`, or empty | **Sources:** [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L23-L28](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L23-L28) --- ## Persistence Strategy The system persists data to two separate JSON files in platform-specific application data directories: ### File Locations The storage directory is resolved via `FileUtil.getLocalStoragePath()` [ConfigManager.java L26](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ConfigManager.java#L26-L26) which returns platform-specific paths: * **Windows:** `%LOCALAPPDATA%/MouseMacros/` * **macOS:** `~/Library/Application Support/MouseMacros/` * **Linux:** `~/.local/share/MouseMacros/` The two persistence files are: | File | Manager | Constant | Content | | --- | --- | --- | --- | | `config.cfg` | `ConfigManager` | `CONFIG_PATH` | User preferences (`Config` object serialized as JSON) | | `cache.json` | `CacheManager` | `CACHE_PATH` | Runtime state (`Cache` object serialized as JSON) | **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L15-L27](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L15-L27) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L15](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L15-L15) ### Configuration Serialization Flow ```mermaid sequenceDiagram participant Application Code participant ConfigManager participant Gson participant FileUtil participant File System note over Application Code,File System: Save Configuration Application Code->>ConfigManager: saveConfig(config) ConfigManager->>ConfigManager: Check CONFIG_DIR exists ConfigManager->>Gson: Create if needed (line 69-70) Gson-->>ConfigManager: toJson(config) ConfigManager->>FileUtil: JSON string FileUtil->>File System: writeFile(CONFIG_PATH, json) note over Application Code,File System: Load Configuration Application Code->>ConfigManager: Write UTF-8 encoded JSON ConfigManager->>FileUtil: loadConfig() loop [File exists and valid] FileUtil-->>ConfigManager: readFile(CONFIG_PATH) ConfigManager->>Gson: JSON string Gson-->>ConfigManager: fromJson(json, Config.class) ConfigManager->>ConfigManager: Config object ConfigManager-->>Application Code: Create new Config() end ConfigManager-->>Application Code: Save default config (line 53-54) ``` **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L49-L76](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L49-L76) ### Cache Serialization Flow ```mermaid sequenceDiagram participant Application Code participant CacheManager participant Gson participant java.nio.file.Files participant File System note over Application Code,File System: Save Cache Application Code->>CacheManager: saveCache() CacheManager->>CacheManager: Get CACHE_PATH CacheManager->>CacheManager: Ensure parent directory exists CacheManager->>Gson: (line 42) Gson-->>CacheManager: toJson(cache) CacheManager->>java.nio.file.Files: JSON string java.nio.file.Files->>File System: write(cachePath, json.getBytes()) note over Application Code,File System: Load Cache CacheManager->>CacheManager: Write UTF-8 encoded JSON CacheManager->>CacheManager: loadCache() during static init loop [File exists] CacheManager->>java.nio.file.Files: Get CACHE_PATH java.nio.file.Files-->>CacheManager: readAllBytes(cachePath) CacheManager->>Gson: byte array Gson-->>CacheManager: fromJson(json, Cache.class) CacheManager->>CacheManager: Cache object CacheManager-->>CacheManager: Create new Cache() end ``` **Sources:** [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L34-L61](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L34-L61) ### Directory Creation Both managers ensure the parent directory exists before writing: **ConfigManager** [ConfigManager.java L69-L70](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ConfigManager.java#L69-L70) : ``` java.io.File dir = new java.io.File(CONFIG_DIR); if (!dir.exists()) dir.mkdirs(); ``` **CacheManager** [CacheManager.java L42](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/CacheManager.java#L42-L42) : ``` if (cachePath.getParent() != null) Files.createDirectories(cachePath.getParent()); ``` This guarantees that persistence files can be saved on first run, even when the application data directory doesn't exist. **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L66-L76](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L66-L76) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L38-L48](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L38-L48) --- ## Static Initialization Configuration loading occurs during class initialization, before any application code executes. This is achieved through a static initialization block: ### Static Initialization Sequence ```mermaid sequenceDiagram participant JVM Class Loader participant ConfigManager participant CacheManager participant FileUtil participant Gson note over JVM Class Loader,Gson: ConfigManager Static Initialization JVM Class Loader->>ConfigManager: Load ConfigManager class ConfigManager->>ConfigManager: Initialize Gson (line 18) ConfigManager->>ConfigManager: Execute static block (lines 25-29) ConfigManager->>FileUtil: getLocalStoragePath() FileUtil-->>ConfigManager: Platform-specific path ConfigManager->>ConfigManager: Set CONFIG_DIR and CONFIG_PATH ConfigManager->>ConfigManager: loadConfig() loop [config.cfg exists] ConfigManager->>FileUtil: readFile(CONFIG_PATH) FileUtil-->>ConfigManager: JSON content ConfigManager->>Gson: fromJson(json, Config.class) Gson-->>ConfigManager: Config object ConfigManager->>ConfigManager: new Config() with defaults ConfigManager->>ConfigManager: saveConfig(defaultConfig) ConfigManager->>ConfigManager: Assign to static config field note over JVM Class Loader,Gson: CacheManager Static Initialization JVM Class Loader->>CacheManager: Load CacheManager class CacheManager->>CacheManager: Initialize Gson (line 16) CacheManager->>CacheManager: Initialize CACHE_PATH (line 15) CacheManager->>FileUtil: getLocalStoragePath() FileUtil-->>CacheManager: Platform-specific path CacheManager->>CacheManager: loadCache() (line 17) CacheManager->>CacheManager: Read file via Files.readAllBytes CacheManager->>Gson: fromJson(json, Cache.class) Gson-->>CacheManager: Cache object CacheManager->>CacheManager: new Cache() with defaults end CacheManager->>CacheManager: Assign to static cache field note over JVM Class Loader,Gson: Both managers ready for use ``` **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L18-L29](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L18-L29) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L15-L17](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L15-L17) ### Access Patterns Once initialized, both managers are accessed statically throughout the application: **Configuration Access:** ``` // Direct field access String language = ConfigManager.config.lang; boolean darkMode = ConfigManager.config.enableDarkMode; int repeatCount = ConfigManager.config.repeatTime; ``` **Cache Access:** ``` // Direct field access String lastDir = CacheManager.cache.lastLoadDirectory; String defaultOp = CacheManager.cache.defaultCloseOperation; // Persistence CacheManager.cache.lastSaveDirectory = "/path/to/dir"; CacheManager.saveCache(); ``` Configuration access pattern appears in [SettingsDialog.java L11](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/SettingsDialog.java#L11-L11) and [MainFrame](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/MainFrame) while cache access pattern appears in [ExitDialog.java L83-L88](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ExitDialog.java#L83-L88) **Sources:** * [src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L1-L180](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java#L1-L180) * [src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java L81-L100](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java#L81-L100) --- ## System Integration The configuration system integrates with the operating system through the `followSystemSettings` flag, enabling automatic synchronization with OS preferences. ### System Settings Synchronization When `config.followSystemSettings` is `true`, the application queries the OS for: 1. **System Language:** Via `SystemUtil.getSystemLang(availableLangs)` 2. **Dark Mode Preference:** Via `SystemUtil.isSystemDarkMode()` This synchronization occurs in the `SettingsDialog` [SettingsDialog.java L154-L168](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/SettingsDialog.java#L154-L168) : ```mermaid flowchart TD FollowSys["config.followSystemSettings"] SysUtil["SystemUtil"] GetLang["getSystemLang()"] GetDark["isSystemDarkMode()"] OSLang["System Language
Locale"] OSDark["Windows Registry
AppsUseLightTheme"] LangCombo["langCombo
Disabled when following"] DarkBox["darkModeBox
Disabled when following"] FollowSys --> SysUtil GetLang --> OSLang GetDark --> OSDark OSLang --> LangCombo OSDark --> DarkBox subgraph subGraph3 ["UI State"] LangCombo DarkBox end subgraph OS ["OS"] OSLang OSDark end subgraph subGraph1 ["System Queries"] SysUtil GetLang GetDark SysUtil --> GetLang SysUtil --> GetDark end subgraph Configuration ["Configuration"] FollowSys end ``` **Sources:** [src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L154-L168](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java#L154-L168) ### ItemListener Implementation The synchronization logic is implemented through an `ItemListener` attached to the "Follow System Settings" checkbox: **Key behaviors:** * When checked: Disables manual controls and queries system settings * When unchecked: Re-enables manual controls, preserving last user selections * Initial load: Executes once during dialog construction [SettingsDialog.java L168](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/SettingsDialog.java#L168-L168) **Sources:** [src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L154-L168](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java#L154-L168) --- ## Language Discovery The `ConfigManager.getAvailableLangs()` method [ConfigManager.java L69-L114](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ConfigManager.java#L69-L114) detects available language files for the language selector in `SettingsDialog`. It handles two runtime environments: ### Environment Detection Flow ```mermaid flowchart TD Start["getAvailableLangs()"] CheckDevMode["Localizer.isDevMode()"] DevPath["Read lang/ directory
from filesystem
(lines 72-81)"] DevList["FileUtil.listFileNames('lang')"] DevFilter["Filter *.json files
Remove .json extension"] CheckProtocol["Check resource protocol"] JarPath["JAR protocol
(lines 85-96)"] FilePath["file protocol
(lines 97-109)"] JarEnum["Enumerate JAR entries
Filter lang/*.json"] FileList["List directory
Filter *.json"] Return["Return String[] of lang codes"] Start --> CheckDevMode CheckDevMode --> DevPath CheckDevMode --> CheckProtocol DevPath --> DevList DevList --> DevFilter DevFilter --> Return CheckProtocol --> JarPath CheckProtocol --> FilePath JarPath --> JarEnum FilePath --> FileList JarEnum --> Return FileList --> Return ``` **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L69-L114](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L69-L114) ### Discovery Scenarios | Scenario | Detection Method | Implementation | | --- | --- | --- | | Development mode | File system access to `lang/` directory | `FileUtil.listFileNames("lang")` [line 73](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/line 73) | | JAR deployment | Enumerate JAR entries matching `lang/*.json` | `JarFile.entries()` iteration [lines 86-96](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/lines 86-96) | | file:// protocol | URI-based file listing | `File.listFiles()` with filter [lines 99-109](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/lines 99-109) | All methods strip the `.json` extension to return language codes (e.g., `"en_us"`, `"zh_cn"`). **Sources:** [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L69-L114](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L69-L114) --- ## Usage Patterns by Component Different UI components interact with the persistence system based on their responsibilities: ### SettingsDialog Usage `SettingsDialog` reads and writes configuration settings [SettingsDialog.java L1-L180](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/SettingsDialog.java#L1-L180) : **Read Pattern:** ```javascript import static io.github.samera2022.mouse_macros.manager.ConfigManager.config; // Initialize UI from config langCombo.setSelectedItem(config.lang); darkModeBox.setSelected(config.enableDarkMode); followSystemBox.setSelected(config.followSystemSettings); ``` **Write Pattern:** ``` // Modify in-memory config config.lang = (String) langCombo.getSelectedItem(); config.enableDarkMode = darkModeBox.isSelected(); config.followSystemSettings = followSystemBox.isSelected(); // Persist changes ConfigManager.saveConfig(config); ``` **Sources:** [src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L1-L180](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java#L1-L180) ### ExitDialog Usage `ExitDialog` uses `CacheManager` to persist exit preferences [ExitDialog.java L81-L100](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ExitDialog.java#L81-L100) : **Cache Write Pattern:** ``` String op = ""; if (exitOnCloseRadio.isSelected()) op = CacheManager.EXIT_ON_CLOSE; if (minimizeToTrayRadio.isSelected()) op = CacheManager.MINIMIZE_TO_TRAY; if (rememberOptionBox.isSelected()) { CacheManager.cache.defaultCloseOperation = op; CacheManager.saveCache(); } switch (op) { case CacheManager.EXIT_ON_CLOSE: System.exit(0); break; case CacheManager.MINIMIZE_TO_TRAY: mf.minimizeToTray(); break; } ``` The cache constants are defined in [CacheManager.java L19-L21](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/CacheManager.java#L19-L21) : | Constant | Value | Purpose | | --- | --- | --- | | `EXIT_ON_CLOSE` | `"exit_on_close"` | Application exits when closed | | `MINIMIZE_TO_TRAY` | `"minimize_to_tray"` | Application minimizes to system tray when closed | | `UNKNOWN` | `""` (empty) | No default close behavior set | **Sources:** * [src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java L81-L100](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/ExitDialog.java#L81-L100) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L19-L21](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L19-L21) ### MacroManager Usage `MacroManager` reads configuration settings for playback behavior: **Read Pattern:** ``` // Check execution settings boolean quickMode = ConfigManager.config.enableQuickMode; int repeatCount = ConfigManager.config.repeatTime; double repeatDelay = ConfigManager.config.repeatDelay; // Check storage settings boolean useDefaultPath = ConfigManager.config.enableDefaultStorage; String defaultPath = ConfigManager.config.defaultMmcStoragePath; ``` **Sources:** [src/io/github/samera2022/mouse_macros/manager/MacroManager.java](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/MacroManager.java) --- ## Configuration Constants `ConfigManager` defines constants for the `readjustFrameMode` setting [ConfigManager.java L21-L23](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/ConfigManager.java#L21-L23) : | Constant | Value | Purpose | | --- | --- | --- | | `RFM_MIXED` | `"MIXED"` | Use memorized sizes when available, otherwise use standardized sizes | | `RFM_STANDARDIZED` | `"STANDARDIZED"` | Always calculate standardized window sizes based on content | | `RFM_MEMORIZED` | `"MEMORIZED"` | Always use memorized window sizes from `CacheManager` | `CacheManager` defines constants for exit behavior [CacheManager.java L19-L21](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/CacheManager.java#L19-L21) : | Constant | Value | Purpose | | --- | --- | --- | | `EXIT_ON_CLOSE` | `"exit_on_close"` | Application exits when main window is closed | | `MINIMIZE_TO_TRAY` | `"minimize_to_tray"` | Application minimizes to system tray when closed | | `UNKNOWN` | `""` (empty) | No default close behavior configured | These constants are used throughout the application to maintain consistency in configuration values. **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L21-L23](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L21-L23) * [src/io/github/samera2022/mouse_macros/manager/CacheManager.java L19-L21](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/CacheManager.java#L19-L21) --- ## Summary The Configuration System provides: 1. **Static Initialization:** Configuration loaded before application code executes 2. **Two-Tier Persistence:** Separate files for application settings (`config.cfg`) and UI state (`cache.json`) 3. **System Integration:** Optional synchronization with OS language and dark mode settings 4. **Environment Awareness:** Supports both development and JAR-packaged execution 5. **Simple Access:** Static fields enable straightforward configuration access throughout the codebase 6. **Automatic Defaults:** Missing configuration files trigger creation of defaults with sensible values For implementation details, see the child pages: * [ConfigManager](ConfigManager) - Core configuration management logic * [Configuration Files](Configuration-Files-and-Settings) - File structure and field specifications * [File Chooser Configuration](CacheManager) - UI state persistence mechanism **Sources:** * [src/io/github/samera2022/mouse_macros/manager/ConfigManager.java L1-L146](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/ConfigManager.java#L1-L146) * [src/io/github/samera2022/mouse_macros/manager/config/FileChooserConfig.java L1-L28](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/manager/config/FileChooserConfig.java#L1-L28) * [src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L1-L180](https://github.com/Samera2022/MouseMacros/blob/1eb6620b/src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java#L1-L180)