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

基于Maven的CodenameOne项目CSS主题切换及.res文件生成咨询

问题

我在基于Maven的CodenameOne项目中切换CSS主题时遇到了困难,操作步骤及问题如下:

  1. 已通过Steve的博客将项目迁移至Maven,当前使用现有theme.css;
  2. 项目启动时的主题初始化代码:
try {
    resources = Resources.openLayered("/MailAngel");
    java.util.Hashtable vals = resources.getTheme(resources.getThemeResourceNames()[0]);
    UIManager.getInstance().setThemeProps(vals);

    Resources theme = Resources.openLayered( Constants.THEME_LIGHT );
    UIManager.getInstance().addThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
    Resources.setGlobalResources(theme);

    //todo: get the device language
    initLocale();
    //init google nalytics
    //setAnalyticsService();     
} catch (Throwable e) {
    e.printStackTrace();
    Log.e(e);
}
  1. 参考KitchenSink示例,在maven common/src/main/css目录下添加dark-theme.css后,执行以下切换代码:
try {
    Resources resources = Resources.openLayered( "/dark-theme" );
    UIManager.getInstance().addThemeProps(resources.getTheme(resources.getThemeResourceNames()[0]));

    Display.getInstance().getCurrent().refreshTheme();
    Utility.setTheme(theme);

} catch(IOException e){
    ComponentUtility.showStatusError("Sorry, unable to switch theme: " + e.getMessage() );
    e.printStackTrace();
}
  1. 执行时出现报错:java.io.IOException: /dark-theme.res not found,完整堆栈信息:
java.io.IOException: /dark-theme.res not found
at com.codename1.ui.util.Resources.open(Resources.java:756)
at com.codename1.ui.util.Resources.openLayered(Resources.java:720)
at com.codename1.ui.util.Resources.openLayered(Resources.java:684)
at net.mailangel.pay.containers.ThemeContainer.update(ThemeContainer.java:111)
at net.mailangel.pay.containers.ThemeContainer.lambda$getButttonContainer$0(ThemeContainer.java:58)
at com.codename1.ui.util.EventDispatcher.fireActionEvent(EventDispatcher.java:349)
at com.codename1.ui.Button.fireActionEvent(Button.java:687)
at com.codename1.ui.Button.released(Button.java:728)
at com.codename1.ui.Button.pointerReleased(Button.java:835)
at com.codename1.ui.LeadUtil.pointerReleased(LeadUtil.java:153)
at com.codename1.ui.Form.pointerReleased(Form.java:3881)
at com.codename1.ui.Component.pointerReleased(Component.java:5266)
at com.codename1.ui.Display.handleEvent(Display.java:2409)
at com.codename1.ui.Display.edtLoopImpl(Display.java:1285)
at com.codename1.ui.Display.mainEDTLoop(Display.java:1203)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)

环境:IDE为IntelliJ,Java 8,Maven 3.6.3,CodenameOne 7.0.80,项目无build.xml文件。

咨询问题:

  • 如何在基于Maven的CodenameOne项目中成功切换CSS主题?
  • 如何通过CSS生成.res文件?

解决方案

一、通过CSS生成.res文件

在Maven版CodenameOne项目中,CSS文件需通过Maven插件自动编译为.res资源文件,步骤如下:

  1. 确保CSS文件放在common/src/main/css目录下(你已正确放置dark-theme.css);
  2. 在项目根目录执行Maven构建命令:mvn clean package,CodenameOne的Maven插件会自动将目录下的CSS编译为同名.res文件,输出到common/target/classes目录;
  3. 构建完成后,检查common/target/classes目录,确认dark-theme.res已生成,该文件会被打包进应用资源中。

二、正确切换CSS主题的步骤

修改主题切换代码,修正资源加载与主题应用逻辑:

  1. 去掉资源路径前的/,直接使用文件名即可;
  2. 使用setThemeProps替换当前主题属性(addThemeProps是追加属性,会导致新旧主题混合);
  3. 更新全局资源并刷新所有已打开窗体的主题。

修改后的切换代码示例:

try {
    // 加载深色主题资源,无需前缀/
    Resources darkTheme = Resources.openLayered("dark-theme");
    Hashtable<String, Object> themeProps = darkTheme.getTheme(darkTheme.getThemeResourceNames()[0]);
    
    // 完全替换当前主题属性
    UIManager.getInstance().setThemeProps(themeProps);
    // 更新全局资源
    Resources.setGlobalResources(darkTheme);
    
    // 刷新当前显示的窗体
    Display.getInstance().getCurrent().refreshTheme();
    // 遍历所有已打开窗体,强制刷新主题
    for (Form f : Display.getInstance().getAllForms()) {
        f.refreshTheme();
    }
    
    Utility.setTheme("dark-theme"); // 确保参数与主题标识一致

} catch(IOException e){
    ComponentUtility.showStatusError("Sorry, unable to switch theme: " + e.getMessage() );
    e.printStackTrace();
}

另外,启动时的初始化代码可简化,避免重复叠加主题:

try {
    // 加载主主题资源
    Resources mainResources = Resources.openLayered("MailAngel");
    Hashtable<String, Object> mainThemeProps = mainResources.getTheme(mainResources.getThemeResourceNames()[0]);
    UIManager.getInstance().setThemeProps(mainThemeProps);
    
    // 按需叠加浅色主题,确保路径正确
    if (Constants.THEME_LIGHT.equals("light-theme")) {
        Resources lightTheme = Resources.openLayered(Constants.THEME_LIGHT);
        UIManager.getInstance().addThemeProps(lightTheme.getTheme(lightTheme.getThemeResourceNames()[0]));
        Resources.setGlobalResources(lightTheme);
    }
    
    initLocale();
} catch (Throwable e) {
    e.printStackTrace();
    Log.e(e);
}

内容的提问来源于stack exchange,提问作者Mohammed Hussein

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:18:26