Skip to content

Settings Dialog

Samera2022 edited this page Jan 30, 2026 · 1 revision

Settings Dialog

Relevant source files

Purpose and Scope

The Settings Dialog provides a modal interface for configuring application-wide preferences in MouseMacros. This document covers the SettingsDialog class, its UI components, configuration options, and integration with the configuration system. For information about the underlying configuration persistence, see Configuration Files. For details on hotkey customization which is accessed through this dialog, see Hotkey Dialog. For theming implementation details, see Theming System.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L1-L220


Overview

The SettingsDialog class extends JDialog and presents a modal settings interface that blocks interaction with the main application window until closed. The dialog organizes configuration options into a hierarchical structure with primary settings and indented sub-settings, providing users with controls for:

  • System settings synchronization (language and dark mode)
  • Manual language selection
  • Dark mode toggle
  • Default macro file storage configuration
  • Access to auxiliary dialogs (hotkeys, about, update information)

Settings changes are not applied until the user clicks the Save button, at which point the configuration is persisted via ConfigManager, localization is reloaded, and the UI theme is updated throughout the application.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L25-L220


UI Structure and Layout

Dialog Construction

The dialog uses a BorderLayout with a main content panel in the center and a save button panel in the south position. The content panel uses BoxLayout with vertical axis orientation and has a 20-30 pixel border for padding.

Layout Component Position Purpose
content panel BorderLayout.CENTER Contains all settings controls with vertical stacking
savePanel BorderLayout.SOUTH Contains centered Save button

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L31-L34

Component Hierarchy

The following diagram shows the actual UI component structure with variable names as they appear in the code:

flowchart TD

SettingsDialog["SettingsDialog<br>(extends JDialog)"]
content["content<br>(JPanel, BoxLayout.Y_AXIS)"]
savePanel["savePanel<br>(JPanel, FlowLayout.CENTER)"]
settingTitle["settingTitle<br>(JLabel)"]
separator["JSeparator"]
followSysPanel["followSysPanel<br>(JPanel, FlowLayout.LEFT)"]
followSysLabel["followSysLabel<br>(JLabel)"]
followSysBox["followSysBox<br>(JCheckBox)"]
subSettingsPanel["subSettingsPanel<br>(JPanel, BoxLayout.Y_AXIS)<br>indented 32px"]
langPanel["langPanel<br>(JPanel, FlowLayout.LEFT)"]
langLabel["langLabel<br>(JLabel)"]
langCombo["langCombo<br>(JComboBox<String>)"]
darkModePanel["darkModePanel<br>(JPanel, FlowLayout.LEFT)"]
darkModeLabel["darkModeLabel<br>(JLabel)"]
darkModeBox["darkModeBox<br>(JCheckBox)"]
enableDefaultStoragePanel["enableDefaultStoragePanel<br>(JPanel, FlowLayout.LEFT)"]
enableDefaultStorageLabel["enableDefaultStorageLabel<br>(JLabel)"]
enableDefaultStorageBox["enableDefaultStorageBox<br>(JCheckBox)"]
pathIndentPanel["pathIndentPanel<br>(JPanel, BoxLayout.Y_AXIS)<br>indented 32px"]
pathPanel["pathPanel<br>(JPanel, FlowLayout.LEFT)"]
pathLabel["pathLabel<br>(JLabel)"]
pathField["pathField<br>(JTextField)"]
browseBtn["browseBtn<br>(JButton)"]
hotkeyPanel["hotkeyPanel<br>(JPanel, FlowLayout.LEFT)"]
hotkeyBtn["hotkeyBtn<br>(JButton)"]
aboutBtn["aboutBtn<br>(JButton)"]
updateInfoBtn["updateInfoBtn<br>(JButton)"]
saveSettingsBtn["saveSettingsBtn<br>(JButton)"]

SettingsDialog --> content
SettingsDialog --> savePanel
content --> settingTitle
content --> separator
content --> followSysPanel
content --> subSettingsPanel
content --> enableDefaultStoragePanel
content --> pathIndentPanel
content --> hotkeyPanel
followSysPanel --> followSysLabel
followSysPanel --> followSysBox
subSettingsPanel --> langPanel
subSettingsPanel --> darkModePanel
langPanel --> langLabel
langPanel --> langCombo
darkModePanel --> darkModeLabel
darkModePanel --> darkModeBox
enableDefaultStoragePanel --> enableDefaultStorageLabel
enableDefaultStoragePanel --> enableDefaultStorageBox
pathIndentPanel --> pathPanel
pathPanel --> pathLabel
pathPanel --> pathField
pathPanel --> browseBtn
hotkeyPanel --> hotkeyBtn
hotkeyPanel --> aboutBtn
hotkeyPanel --> updateInfoBtn
savePanel --> saveSettingsBtn
Loading

Diagram: SettingsDialog Component Hierarchy

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L32-L194


Configuration Options

Follow System Settings

The "Follow System Settings" checkbox (followSysBox) controls whether the application automatically syncs language and dark mode preferences with the operating system. This is a top-level setting at line 46-55.

Field Type Configuration Key
followSysBox JCheckBox config.followSystemSettings

When enabled, this checkbox:

  • Disables manual controls for langCombo and darkModeBox
  • Automatically sets language via SystemUtil.getSystemLang()
  • Automatically sets dark mode via SystemUtil.isSystemDarkMode()

The synchronization logic is implemented in an ItemListener attached at lines 196-210.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L43-L55, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L196-L210

Language Selection

The language dropdown (langCombo) allows manual selection from available language files discovered by ConfigManager.getAvailableLangs(). The combo box is populated at line 66 and initially set to config.lang.

This control is part of the indented subSettingsPanel (lines 58-90), indicating it is a sub-option of the follow system settings feature. It becomes disabled when followSysBox is checked.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L63-L74

Dark Mode Toggle

The dark mode checkbox (darkModeBox) enables or disables the dark theme. It is initialized with config.enableDarkMode and is located within the indented subSettingsPanel below the language selector.

When follow system settings is enabled, this checkbox is automatically synchronized with the OS dark mode preference and becomes disabled for manual editing.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L76-L88

Default Storage Configuration

The default storage system consists of two parts:

  1. Enable Default Storage (enableDefaultStorageBox) - A top-level checkbox that enables/disables automatic storage path usage
  2. Default Storage Path (pathField and browseBtn) - An indented text field and browse button for specifying the directory
Component Type Configuration Key
enableDefaultStorageBox JCheckBox config.enableDefaultStorage
pathField JTextField config.defaultMmcStoragePath
browseBtn JButton Opens JFileChooser

The path controls are enabled/disabled based on the checkbox state, with custom background and foreground color handling for disabled state (lines 127-133) to work around MetalLookAndFeel limitations.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L92-L151

Auxiliary Dialog Buttons

Three buttons provide access to related dialogs:

Button Variable Label Key Opens Dialog
hotkeyBtn settings.custom_hotkey HotkeyDialog
aboutBtn settings.about_author AboutDialog
updateInfoBtn settings.update_info UpdateInfoDialog

Each button uses SwingUtilities.invokeLater() to ensure the dialog is created and displayed on the Event Dispatch Thread.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L153-L168


Interaction Logic and State Management

Conditional Control Enablement

The dialog implements two distinct control hierarchies with parent-child relationships:

Follow System Settings Hierarchy

flowchart TD

followSysBox["followSysBox<br>(JCheckBox)"]
langCombo["langCombo<br>(JComboBox)"]
darkModeBox["darkModeBox<br>(JCheckBox)"]

followSysBox --> langCombo
followSysBox --> darkModeBox
followSysBox --> langCombo
followSysBox --> darkModeBox
Loading

Diagram: Follow System Settings Control Flow

The followSysListener (lines 196-210) implements this logic:

  • When followSysBox is checked: disable langCombo and darkModeBox, then set their values from SystemUtil
  • When unchecked: enable both controls for manual selection

Default Storage Hierarchy

flowchart TD

enableDefaultStorageBox["enableDefaultStorageBox<br>(JCheckBox)"]
pathField["pathField<br>(JTextField)"]
browseBtn["browseBtn<br>(JButton)"]

enableDefaultStorageBox --> pathField
enableDefaultStorageBox --> browseBtn
enableDefaultStorageBox --> pathField
Loading

Diagram: Default Storage Control Flow

The enableDefaultStorageListener (lines 122-136) implements this logic:

  • When enableDefaultStorageBox is checked: enable pathField and browseBtn, set normal colors
  • When unchecked: disable controls, set disabled colors based on dark mode

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L122-L136, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L196-L210

Directory Selection

The browse button (browseBtn) opens a JFileChooser configured for directory selection. If pathField already contains a path, the chooser initializes to that directory (lines 112-113). On approval, the selected directory's absolute path is written to pathField.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L108-L118


Save Operation and Persistence

Save Button Action Sequence

The following diagram illustrates the complete save operation triggered by the Save button:


Diagram: Save Settings Operation Sequence

The save operation is implemented in the ActionListener attached to saveSettingsBtn at lines 172-190 and performs the following steps:

  1. Update Configuration Object: Copy values from UI controls to ConfigManager.config fields
  2. Persist Changes: Call ConfigManager.saveConfig() to write to config.cfg, then reloadConfig() to refresh
  3. Reload Localization: Call Localizer.load() with the new language
  4. Update UI: Refresh MainFrame texts, apply theme to both dialog and main frame content panes, adjust frame width
  5. Close Dialog: Call dispose() to close the dialog

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L172-L190

Configuration Fields Modified

UI Control Configuration Field Type
followSysBox config.followSystemSettings boolean
langCombo config.lang String
darkModeBox config.enableDarkMode boolean
enableDefaultStorageBox config.enableDefaultStorage boolean
pathField config.defaultMmcStoragePath String

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L173-L177


Integration with Other Systems

ConfigManager Integration

The dialog reads initial values from and writes final values to the config object managed by ConfigManager. The static import at line 22 provides direct access to ConfigManager.config.

Key integration points:

  • Initialization: Lines 47, 67, 80, 96, 106 read from config fields
  • Available Languages: Line 65 calls ConfigManager.getAvailableLangs() to populate dropdown
  • Persistence: Lines 179-180 call ConfigManager.saveConfig() and reloadConfig()

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L22, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L65, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L179-L180

Localizer Integration

The dialog uses Localizer.get() throughout to fetch translated strings for all text elements. Translation keys include:

Translation Key Usage
settings Dialog title and header
settings.follow_system_settings Follow system checkbox label
settings.switch_lang Language selection label
settings.enable_dark_mode Dark mode checkbox label
settings.enable_default_storage Default storage checkbox label
settings.default_mmc_storage_path Storage path label
settings.browse Browse button
settings.custom_hotkey Hotkey button
settings.about_author About button
settings.update_info Update info button
settings.save_settings Save button

After saving with a new language selection, line 181 calls Localizer.load() to reload translations, and line 182 calls MAIN_FRAME.refreshMainFrameTexts() to update all displayed text.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L28-L171, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L181-L182

ComponentUtil and Theming

The dialog applies theming at two points:

  1. Initialization: Line 215 applies theme to dialog content pane based on config.enableDarkMode
  2. Save Operation: Lines 186-187 reapply theme to both dialog and main frame based on new dark mode setting

The theme mode is determined by a ternary expression: config.enableDarkMode ? OtherConsts.DARK_MODE : OtherConsts.LIGHT_MODE.

Window size caching is applied at line 216 via ComponentUtil.applyWindowSizeCache() with default dimensions 521x359.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L186-L187, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L215-L216

MainFrame Integration

The dialog maintains a static reference to MainFrame.MAIN_FRAME (imported at line 23) and calls the following methods on it:

  • refreshMainFrameTexts() - Updates all text labels after language change
  • adjustFrameWidth() - Adjusts window width after text changes

The theme is also applied to the main frame's content pane during the save operation to ensure consistent appearance.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L23, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L182, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L187-L188

SystemUtil Integration

When follow system settings is enabled, the dialog queries the operating system for preferences:

  • SystemUtil.getSystemLang(ConfigManager.getAvailableLangs()) - Returns system language code
  • SystemUtil.isSystemDarkMode() - Returns system dark mode preference

These calls occur within the followSysListener at lines 202-203.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L202-L203


Dialog Lifecycle

Construction and Initialization

The constructor (lines 27-219) performs the following initialization sequence:

  1. Set dialog properties: title, name ("settings"), modal flag
  2. Create and configure content panel with BoxLayout
  3. Build all UI components hierarchically
  4. Attach ItemListener instances to checkboxes for control enablement logic
  5. Apply initial theme via ComponentUtil.setMode()
  6. Apply cached window size with default 521x359
  7. Center dialog relative to itself (line 217 - note: this may be a bug as it should likely center relative to parent)
  8. Add WindowClosingAdapter for size caching on close

The dialog is modal (setModal(true) at line 30), meaning it blocks input to other windows while visible.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L27-L219

Window Closing and Caching

The WindowClosingAdapter attached at line 218 ensures that when the dialog is closed (via Save button or window close button), the current window size is cached to cache.json via CacheManager. This allows the dialog to remember its size across application sessions.

The dialog is named "settings" (line 29) for the caching mechanism to identify it.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L29, src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L218


Color Handling for Disabled Components

The dialog implements custom color management for disabled text fields due to limitations in MetalLookAndFeel. When pathField is disabled, the code explicitly sets background and foreground colors based on the current dark mode setting:

Disabled State Colors:

Theme Background Foreground
Dark Mode ColorConsts.DARK_MODE_DISABLED_BACKGROUND ColorConsts.DARK_MODE_DISABLED_FOREGROUND
Light Mode ColorConsts.LIGHT_MODE_DISABLED_BACKGROUND ColorConsts.LIGHT_MODE_DISABLED_FOREGROUND

Enabled State Colors:

Theme Background Foreground
Dark Mode ColorConsts.DARK_MODE_PANEL_BACKGROUND ColorConsts.DARK_MODE_PANEL_FOREGROUND
Light Mode ColorConsts.LIGHT_MODE_PANEL_BACKGROUND ColorConsts.LIGHT_MODE_PANEL_FOREGROUND

This manual color management occurs in the enableDefaultStorageListener at lines 127-133, with a comment noting the lack of built-in support in MetalLookAndFeel.

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L126-L133


Summary Table of Key Components

Component Variable Type Purpose Configuration Field
followSysBox JCheckBox Toggle OS settings sync config.followSystemSettings
langCombo JComboBox<String> Select application language config.lang
darkModeBox JCheckBox Toggle dark theme config.enableDarkMode
enableDefaultStorageBox JCheckBox Enable default save location config.enableDefaultStorage
pathField JTextField Display/edit storage path config.defaultMmcStoragePath
browseBtn JButton Open directory chooser -
hotkeyBtn JButton Open hotkey configuration -
aboutBtn JButton Open about dialog -
updateInfoBtn JButton Open update information -
saveSettingsBtn JButton Persist changes and close -

Sources: src/io/github/samera2022/mouse_macros/ui/frame/SettingsDialog.java L46-L192

Clone this wiki locally