允许不同用户使用不同的GWT视觉主题
我的问题是:如何根据登录的用户允许不同的GWT视觉主题? 我想决定在客户登录时使用哪个主题(那是在GWT应用程序加载之前,所以我很确定这应该是可能的)。允许不同用户使用不同的GWT视觉主题,gwt,Gwt,我的问题是:如何根据登录的用户允许不同的GWT视觉主题? 我想决定在客户登录时使用哪个主题(那是在GWT应用程序加载之前,所以我很确定这应该是可能的)。 我尝试使用基于自定义属性的类替换,但失败了,因为只有最后继承的模块的图像集可见,即使我可以选择正确的css文件。。。我到处都找遍了,找不到答案 我会尝试以下一般方法: 为每个视觉主题定义一个CSS文件 按说明将它们全部放入一个容器中 在对用户进行身份验证之前,不要注入主题CSS。您可以插入显示登录屏幕所需的通用CSS 然后根据用户使用CssRe
我尝试使用基于自定义属性的类替换,但失败了,因为只有最后继承的模块的图像集可见,即使我可以选择正确的css文件。。。我到处都找遍了,找不到答案 我会尝试以下一般方法:
谢谢你的建议,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);
}
然后,从项目的GWT模块文件继承所有资源模块。例如:
<inherits name='com.google.gwt.user.theme.standard.StandardResources'/>
<inherits name='com.google.gwt.user.theme.dark.DarkResources'/>
继承模块的*Resources版本可避免自动注入样式表
为了决定要使用哪个主题,我在模块文件中创建了一个自定义GWT属性,根据该属性的值,如果应该使用不同的主题,我用不同的Java类(默认类的子类)替换默认Java类(只插入默认主题)。这有一个额外的好处,我可以在每个主题中包含我自己的ResourceBundle资源,因为与主题一起使用的替换Java类,除了注入正确的css文件之外,还可以为我的GWT代码提供替代资源
编辑
我想补充一点重要的意见:
上面描述的解决方案非常有效。但是如果您的应用程序使用不同的地区或其他GWT属性,这种方法可能会导致编译排列的数量激增!只有6个不同的主题和3个不同的地区,在您通常拥有的标准6个不同的浏览器版本之上,GWT编译器将创建6 x 3 x 6=108个不同的编译!!这太疯狂了
一个更好的解决方案,我最终决定遵循,是在用户登录后在HttpSession中设置一个属性,然后根据该属性的值加载相应的css文件(在我的入口点类的onModuleLoad()中的第一件事)。与上述解决方案的唯一区别在于如何选择主题。我使用了不同的方法,主要依靠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}
请注意,您只在不同主题的规则前面添加了一个主题选择器。是否有理由在根文档上使用
setClassName
,而不是RootPanel.get().setStyleName(主题)
或RootPanel.get().setStylePrimaryName(主题)
?关键原因是RootPanel通常已经有一些类名。这些其他课程将不以“主题”为主题。换句话说,如果您同时将“DARK”和“myApp”应用于根面板,则选择器“.DARK.myApp”将不起作用。我没有尝试为此使用setStylePrimaryName()和setStyleDependentName()。
.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}