近期打算用ribbon的界面编写swing的界面,当然ribbon需要自定义组件,自定义组件以后需要依靠laf定义编写想office2007界面风格的颜色,需要定义laf。对于laf进行了简单的研究。
jdk内部的laf的组成
在jdk内部,laf定义主要依靠LookAndFeel抽象类来定义的,其中他主要定义了可插入外观的laf,在jdk内部主要包括下面几个外观
LookAndFeel
|
|-> BasicLookAndFeel 标准桌面 LookAndFeel 类(JLF、Mac、Windows 等)从该基类派生
|
|->MetalLookAndFeel
|->MotifLookAndFeel
|->SynthLookAndFeel 提供创建自定义外观的基础
|->WindowsLookAndFeel
|->MultiLookAndFeel 多路外观允许同时将多个 UI 与一个组件相关联。
SynthLookAndFeel 是jdk内部提供的一个用来自定义laf的主要实现类,通过配置文件进行定义,但是考虑到office2007风格不简简单单的处理一下界面的颜色,所以不采用这个,打算自定义扩展BasicLookAndFeel,下面说一下laf的处理逻辑。其实说到laf的实现机制,主要还需要依靠swing的mvc,其中swing的mvc主要包括了Modle,compont,ui deletage,其中主要的展现渲染逻辑都放在了ui delegage中,这样就给我们动态定义UI做好了基础。
laf如何执行的,可以从我们使用laf的代码进行分析,首先我们调用UIManager.setLookAndFeel()进行设定,其中代码都执行了什么内容,如下
public static void setLookAndFeel(LookAndFeel newLookAndFeel)
throws UnsupportedLookAndFeelException
{
if ((newLookAndFeel != null) && !newLookAndFeel.isSupportedLookAndFeel()) {
String s = newLookAndFeel.toString() + " not supported on this platform";
throw new UnsupportedLookAndFeelException(s);
}
LAFState lafState = getLAFState();
LookAndFeel oldLookAndFeel = lafState.lookAndFeel;
if (oldLookAndFeel != null) {
oldLookAndFeel.uninitialize(); -----1
}
lafState.lookAndFeel = newLookAndFeel;
if (newLookAndFeel != null) {
sun.swing.DefaultLookup.setDefaultLookup(null);
newLookAndFeel.initialize(); -----2
lafState.setLookAndFeelDefaults(newLookAndFeel.getDefaults()); ----3
}
else {
lafState.setLookAndFeelDefaults(null);
}
SwingPropertyChangeSupport changeSupport = lafState.
getPropertyChangeSupport(false);
if (changeSupport != null) {
changeSupport.firePropertyChange("lookAndFeel", oldLookAndFeel,
newLookAndFeel);
}
}
这三个步骤是主要的执行代码,其中主要的getDefaults里面的代码执行如下:
BasicLookAndFeel 中提供了一个getDefaults方法,他里面记录了所有的定义的步骤,看看他里面主要进行了那些操作。
initClassDefaults(table); ------- 1
initSystemColorDefaults(table); --2
initComponentDefaults(table); --3
1。主要定义了组建于UI的对应关系,
final String basicPackageName = "javax.swing.plaf.basic.";
Object[] uiDefaults = {
"ButtonUI", basicPackageName + "BasicButtonUI",
。。。
};
table.putDefaults(uiDefaults);
这里面定义了ButtonUI对应的UI显示组件显示,这样定义了以后再组件中的updateUI的时候会根据UIManager.get(getUIClassID())就可以直接取出这个地方定义的UI,其中UI才是真正显示的内容,所以需要定义一些列的组件的UI。
2。定义组件系统定义颜色
protected void initSystemColorDefaults(UIDefaults table)
{
String[] defaultSystemColors = {
"desktop", "#005C5C", /* Color of the desktop background */
。。。
};
loadSystemColors(table, defaultSystemColors, isNativeLookAndFeel());
}
其中的颜色一定要采用后面的loadSystemColors方法将颜色加载起来后面可以UIManager.getColor取得制定标志的颜色值,这个可以在UI中使用
3。 定义组件的缺省属性。比如可以在此处定义组件的字体等。
其实定义laf主要讲这几个方法进行自定义,基本上就可以改变laf的内容,laf主要是显示风格的变化,有时候为了体现产品的能力,可以可以让用户自定义颜色,如果每一种颜色都需要一个laf的话,那就天麻烦了,laf主要是显示的风格,可以自定义的laf中关联一些skin或者theme等用来保存颜色值,这样就可以动态修改颜色值了,创建个性化十足的系统。