You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在两个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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:10:36