如何在两个JFrame间传递设置信息?Swing游戏项目需求
解决JFrame主题(深色/浅色模式)同步问题
下面提供两种实用方案,适配不同项目复杂度:
方案1:共享配置类+观察者模式(解耦首选)
通过全局单例配置类管理主题状态,同时提供监听机制,让主窗口自动响应主题变化。
1. 创建全局配置类
import java.util.ArrayList; import java.util.List; public class AppConfig { // 单例确保全局唯一实例 private static final AppConfig INSTANCE = new AppConfig(); private boolean isDarkMode; private List<ThemeChangeListener> listeners = new ArrayList<>(); private AppConfig() {} public static AppConfig getInstance() { return INSTANCE; } public boolean isDarkMode() { return isDarkMode; } public void setDarkMode(boolean darkMode) { this.isDarkMode = darkMode; notifyThemeChange(); } public void addThemeChangeListener(ThemeChangeListener listener) { listeners.add(listener); } public void removeThemeChangeListener(ThemeChangeListener listener) { listeners.remove(listener); } private void notifyThemeChange() { for (ThemeChangeListener listener : listeners) { listener.onThemeChanged(isDarkMode); } } // 主题变化回调接口 public interface ThemeChangeListener { void onThemeChanged(boolean isDarkMode); } }
2. 主JFrame实现监听并响应主题变化
import javax.swing.*; import java.awt.*; public class MainFrame extends JFrame implements AppConfig.ThemeChangeListener { private JButton settingsBtn; public MainFrame() { initUI(); // 注册主题监听 AppConfig.getInstance().addThemeChangeListener(this); // 初始化应用当前主题 applyTheme(AppConfig.getInstance().isDarkMode()); } private void initUI() { setTitle("SpiceWars 主界面"); setSize(800, 600); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(new FlowLayout()); settingsBtn = new JButton("打开设置"); settingsBtn.addActionListener(e -> new SettingsFrame().setVisible(true)); add(settingsBtn); } // 实现主题变化回调 @Override public void onThemeChanged(boolean isDarkMode) { applyTheme(isDarkMode); } // 统一主题应用逻辑 private void applyTheme(boolean isDarkMode) { Color bgColor = isDarkMode ? new Color(30, 30, 30) : Color.WHITE; Color fgColor = isDarkMode ? Color.WHITE : Color.BLACK; getContentPane().setBackground(bgColor); settingsBtn.setBackground(isDarkMode ? new Color(50, 50, 50) : Color.LIGHT_GRAY); settingsBtn.setForeground(fgColor); // 可扩展添加其他组件的主题设置 } }
3. 设置JFrame修改全局配置
import javax.swing.*; import java.awt.*; public class SettingsFrame extends JFrame { private JCheckBox darkModeCheckbox; public SettingsFrame() { initUI(); // 初始化复选框为当前配置状态 darkModeCheckbox.setSelected(AppConfig.getInstance().isDarkMode()); } private void initUI() { setTitle("设置"); setSize(300, 200); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setLayout(new FlowLayout()); darkModeCheckbox = new JCheckBox("启用深色模式"); darkModeCheckbox.addActionListener(e -> AppConfig.getInstance().setDarkMode(darkModeCheckbox.isSelected()) ); add(darkModeCheckbox); } }
方案2:直接传递主窗口引用(小型项目快速实现)
适合简单场景,直接让设置窗口持有主窗口引用,修改主题时调用主窗口的更新方法。
1. 主JFrame添加公开的主题更新方法
public class MainFrame extends JFrame { private JButton settingsBtn; public MainFrame() { initUI(); } private void initUI() { // 同方案1的初始化代码 settingsBtn.addActionListener(e -> new SettingsFrame(this).setVisible(true)); } // 公开的主题应用方法 public void applyTheme(boolean isDarkMode) { Color bgColor = isDarkMode ? new Color(30, 30, 30) : Color.WHITE; Color fgColor = isDarkMode ? Color.WHITE : Color.BLACK; getContentPane().setBackground(bgColor); settingsBtn.setBackground(isDarkMode ? new Color(50, 50, 50) : Color.LIGHT_GRAY); settingsBtn.setForeground(fgColor); } }
2. 设置JFrame接收主窗口引用并触发更新
import javax.swing.*; import java.awt.*; public class SettingsFrame extends JFrame { private JCheckBox darkModeCheckbox; private MainFrame mainFrame; // 构造方法接收主窗口引用 public SettingsFrame(MainFrame mainFrame) { this.mainFrame = mainFrame; initUI(); } private void initUI() { // 同方案1的初始化代码 darkModeCheckbox.addActionListener(e -> mainFrame.applyTheme(darkModeCheckbox.isSelected()) ); } }
额外建议
- 把主题应用逻辑抽成单独方法,避免重复代码
- 如果需要持久化设置(重启后保留主题),可在
AppConfig中添加读写配置文件的逻辑(比如用Properties类) - Swing组件更新确保在事件调度线程(EDT)中执行,上述代码因在ActionListener中触发,已符合要求
内容的提问来源于stack exchange,提问作者JonasOFF
相关产品推荐
相关产品推荐

