为不同的用户提供不同的GWT视觉主题

时间:2011-10-31 22:44:28

标签: gwt

我的问题是:您如何根据登录的用户允许不同的GWT视觉主题? 我想决定当客户登录时使用哪个主题(即在GWT应用程序加载之前,所以我很确定它应该是可能的)。 我试图使用基于自定义属性的类替换,但是失败了,因为只有最后一个继承的模块的图像集变得可见,即使我可以选择正确的css文件...我已经到处搜索但找不到答案!

3 个答案:

答案 0 :(得分:1)

感谢您对Thomas的建议,但此解决方案的问题在于您假设我可以将CSS样式表添加到ClientBundle(我尝试过但除非您将css文件和附带的图片复制到您的项目,你不能这样做)。主题来自外部GWT模块。我希望以这种方式保持模块化(每次我们需要一个新主题时,将大量资源导入我的项目会很痛苦。)

我想到的解决方法是在运行时自己编写注入代码(只是在HTML头中注入一个链接标记)。 为了完整起见,这里是代码:

protected void doInjection(String cssFilePath) {
    // <link type="text/css" rel="stylesheet" href="sol.css">
    Element headEl = Document.get().getElementsByTagName("head").getItem(0);
    HeadElement head = HeadElement.as(headEl);
    LinkElement link = Document.get().createLinkElement();
    link.setType("text/css");
    link.setRel("stylesheet");
    link.setHref(GWT.getModuleBaseURL() + cssFilePath);
    head.appendChild(link);
}

你用这样的方法调用这个方法:

doInjection("gwt/standard/standard.css");

然后,从项目的GWT模块文件继承所有Resources模块。例如:

  <inherits name='com.google.gwt.user.theme.standard.StandardResources'/>
  <inherits name='com.google.gwt.user.theme.dark.DarkResources'/>   

继承模块的* Resources版本可避免自动注入样式表。

要决定使用哪个主题,我在模块文件中创建了一个自定义GWT属性,根据此属性的值,我将一个默认的Java类(只插入默认主题)替换为另一个Java类(如果应该使用不同的主题,则为默认类的子类。这有额外的好处,我可以在每个主题中包含我自己的ResourceBundle资源,因为除了注入正确的css文件之外,与主题一起使用的替换Java类也可以为我的GWT代码提供替代资源。

修改

我想补充一点重要说明: 上述解决方案效果很好。但是,如果您的应用使用不同的Locales或其他GWT属性,这种方法可能会导致编译排列的数量爆炸!只有6种不同的主题和3种不同的Locales,在您通常拥有的标准6种不同浏览器版本之上,GWT编译器将创建6 x 3 x 6 = 108种不同的编辑!这太疯狂了!!

我决定遵循的更好的解决方案是在用户登录后将属性设置为HttpSession,然后根据此属性的值加载相应的css文件(onModuleLoad中的第一件事) ()我的入门级课程)。与上述解决方案的唯一区别在于您如何选择主题。

答案 1 :(得分:1)

我使用了一种不同的方法,它主要依靠CSS的强大功能和一行GWT代码来切换主题。

首先,定义要应用的主题。我使用枚举。

public enum Theme {
    DARK,
    BRIGHT;
}
public static String getDefault() {
    return BRIGHT.name();
}

现在,当您启动应用时,请应用默认主题(Theme.getDefault())。当用户选择其他主题时,请应用它:

public static void setTheme(String theme) {
   /*
    * Setting style on Body element allows us to "theme" the RootPanel as well.
    */

    Document.get().getBody().setClassName(theme);
}

当您应用新主题时,应用的外观会立即更改而无需重新加载页面。

最后,定义CSS文件中所需的所有主题元素:

.DARK {background: #000; color: #CCC}
.BRIGHT {background: #ebebeb; color: #000}

.gwt-DialogBox {border-radius: 6px}
.DARK .gwt-DialogBox {border: 3px solid #555}
.BRIGHT .gwt-DialogBox {border: 3px solid #CCC}

请注意,您只在不同主题的规则前添加主题选择器。

答案 2 :(得分:0)

我会尝试以下一般方法:

  1. 为每个视觉主题定义一个CSS文件。
  2. ClientBundle所描述的那样,将它们全部放在here
  3. 暂停注入主题CSS,直到您对用户进行身份验证。您可以注入显示登录屏幕所需的常规CSS。
  4. 然后根据用户使用CssResource的ensureInjected()方法注入主题CSS。