文件格式
Synth 的文件格式 (dtd) 允许指定创建您自己的外观所需的所有部分。通过 SynthLookAndFeel.load(InputStream, Class) 或 SynthLookAndFeel.load(URL) 方法加载合成文件。以下示例使用 load 方法配置一个 SynthLookAndFeel 并将其设置为当前外观:
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(MyClass.class.getResourceAsStream("laf.xml"), MyClass.class);
UIManager.setLookAndFeel(laf);
此示例使用指定的类作为资源基础来解析路径,从输入流加载外观。也可以从任意 URL 加载外观,如下例所示。
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(new URL("file:///C:/java/synth/laf/laf.xml"));
UIManager.setLookAndFeel(laf);
例如,方法 SynthLookAndFeel.load(URL) 可用于从以下任何一项加载外观:
- 文件,例如
file:///C:/java/synth/laf/laf.xml - Web 服务,例如
http://host/laf.xml - JAR 文件,例如
jar:file:///C:/synth-laf.jar!/laf.xml - 远程 JAR 文件,例如
jar:http://host/synth-laf.jar!/laf.xml
虽然指定了 synth 的 DTD,但解析器并未进行验证。仅当未指定必要属性或类型错误时,解析才会失败。
合成元素
<!ELEMENT synth ((%beansPersistance;) | style | bind | font | color | imagePainter | imageIcon | defaultsProperty)*> <!ATTLIST synth version CDATA #IMPLIED >
Attribute definitions
- version
- 文件格式版本,应为 1
synth 元素包含构成 SynthLookAndFeel 定义的所有其他元素。
样式元素
<!ELEMENT style (property | defaultsProperty | state | font | graphicsUtils | insets | painter | imagePainter | opaque | (%beansPersistance;) | imageIcon)*> <!ATTLIST style id ID #IMPLIED clone IDREF #IMPLIED >
Attribute definitions
样式元素对应于 SynthStyle ,子元素指定适用于所有状态的属性或包含特定状态特定属性的状态元素。以下示例创建了一个不透明样式,其 ID 为 button,insets为 4, 4, 4, 4,字体为 Dialog 12。
<style id="button"> <opaque value="true"/> <insets top="4" left="4" right="4" bottom="4"/> <font name="Dialog" size="12"/> </style>
以下示例创建了一个 ID 为 clonedButton 的新样式,该样式是 ID 为 button 的样式的副本,字体为 Dialog, 14。生成的样式将是不透明的,具有 4、4、4、4 和 a 的insetsDialog 14 的字体。
<style id="clonedButton" clone="button"> <font name="Dialog" size="14"/> </style>
状态元素
<!ELEMENT state (color | font | painter | imagePainter | (%beansPersistance;) | property | imageIcon)*> <!ATTLIST state id ID #IMPLIED clone IDREF #IMPLIED value CDATA #IMPLIED idref IDREF #IMPLIED >
Attribute definitions
- id
- 状态的唯一标识符。
- clone
- 复制并用于新状态的先前定义状态的标识符。
- value
- 标识要应用属性的组件的状态。这是一个列表:ENABLED、MOUSE_OVER、PRESSED、DISABLED、FOCUSED、SELECTED 或 DEFAULT。多个状态应该用“和”分隔。如果不指定值,则内容适用于所有状态。
- idref
- 指示此状态应与先前定义的状态相同。这对于希望为特定状态共享相同视觉属性的多种样式很有用。
state 元素指定要用于组件特定状态的视觉属性。例如,您可以指定启用组件时的背景颜色应与禁用组件时的背景颜色不同。并非所有组件都支持所有状态。例如,Panel 仅支持状态 ENABLED 和 DISABLED。
以下示例创建了一个红色背景的状态,当组件处于选中和按下状态时将使用该状态:
<state value="SELECTED AND PRESSED"> <color value="RED" type="BACKGROUND"/> </state>
将选择具有最多个人匹配项的州。例如,下面定义了两种状态:
<state value="SELECTED and PRESSED" id="one"> <color value="RED" type="BACKGROUND"/> </state> <state value="SELECTED" id="two"> <color value="RED" type="BACKGROUND"/> </state>
当选择并按下组件时使用状态 one,当选择组件时使用状态 two。如果 Component 的状态至少包含 SELECTED 和 PRESSED,则选择状态 one,否则如果状态为 SELECTED,但不包含 PRESSED,则使用状态 two。
字体元素
<!ELEMENT font EMPTY> <!ATTLIST font id ID #IMPLIED clone IDREF #IMPLIED name CDATA #IMPLIED style CDATA #IMPLIED size CDATA #IMPLIED >
Attribute definitions
- id
- 字体的唯一标识符。
- idref
- 先前定义的字体的标识符。
- name
- 字体名称。
- style
- 字体的样式。这是由空格分隔的字体定义的样式列表:PLAIN、BOLD 或 ITALIC。如果使用未指定的 PLAIN。
- size
- 字体大小,以像素为单位
定义当前 state 或 style 的字体。您必须指定 idref 或 name 和 size。
下面的示例创建一个字体为 Dialog 12 Bold 的样式。
<style id="test"> <font name="DIALOG" size="12" style="BOLD"/> </style>
以下示例创建了一个字体为 Dialog 12 Bold 的样式,如果组件已启用,将使用该字体,否则将使用 Dialog 12 Italic。
<style id="test"> <font name="DIALOG" size="12" style="ITALIC"/> <state value="ENABLED"> <font name="DIALOG" size="12" style="BOLD"/> </state> </style>
虽然您可以为每个状态提供不同的字体,但通常小部件不会在状态更改时重新生效,因此如果您尝试为不同的状态使用具有明显不同大小的字体,您可能会遇到大小调整问题。
颜色元素
<!ELEMENT color EMPTY> <!ATTLIST color id ID #IMPLIED idref IDREF #IMPLIED type CDATA #IMPLIED value CDATA #IMPLIED >
Attribute definitions
- id
- 颜色的唯一标识符。
- idref
- 先前定义的颜色的标识符。
- type
- 描述应在何处使用此颜色。这通常是由 ColorType 定义的常量之一:FOREGROUND、BACKGROUND、TEXT_FOREGROUND、TEXT_BACKGROUND 或 FOCUS。或者,您可以指定类和字段的完整路径,例如 javax.swing.plaf.synth.ColorType.FOREGROUND,这对于定义其他颜色类型的 synth 子类很有用。
- value
-
颜色的值。这接受以下形式。
Color类中常量的名称,例如RED。#RRGGBB形式的十六进制值,其中RR给出红色组件,GG给出绿色组件,BB给出蓝色组件。您无需指定所有颜色组件。例如,#123等同于#000123。#ARRGGBB或#AARRGGBB形式的十六进制值。这对于0xFF以外的 alpha 值很有用。形式#ARRGGBB等同于#0ARRGGBB。
Color 定义了一种颜色以及它应该应用于组件的哪个部分。以下示例将在启用组件时使用红色背景色。
<state value="ENABLED"> <color value="RED" type="BACKGROUND"/> </state>
当启用组件时,以下示例将具有红色背景,否则为蓝色。
<style id="test"> <state value="ENABLED"> <color value="RED" type="BACKGROUND"/> </state> <state> <color value="#00FF00" type="BACKGROUND"/> </state> </style>
属性元素
<!ELEMENT property EMPTY> <!ATTLIST property key CDATA #REQUIRED type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED >
Attribute definitions
- key
- 财产的名称。
- type
- 指示属性的类型。
- value
- 财产的值。对于布尔属性,这将是 true 或 false,对于整数属性,这将是一个有效整数,对于维度,这将是宽度和高度,由空格分隔,对于 insets 属性,这将是顶部、左侧、底部和右侧分隔通过空格和 idref 属性,这将是先前定义的对象的唯一 ID。
属性 元素用于将键值对添加到可以通过 get 方法访问的 SynthStyle。许多 Component 使用键值对来配置它们的视觉外观。有关每个 Component 支持的属性列表,请参阅 属性表。以下代码创建属性 ScrollBar.allowsAbsolutePositioning 、 OptionPane.minimumSize 、 ScrollPane.viewportBorderInsets 、 Tree.rowHeight 和 foreground ,其值为 false,尺寸为 262x90,insets为 5、5、5、5,整数 20 和类 ArrowButtonPainter 的实例。
<style id="test"> <property key="ScrollBar.allowsAbsolutePositioning" type="boolean" value="false"/> <property key="OptionPane.minimumSize" type="dimension" value="262 90"/> <property key="ScrollPane.viewportBorderInsets" type="insets" value="5 5 5 5"/> <property key="Tree.rowHeight" type="integer" value="20"/> <object class="ArrowButtonPainter" id="ArrowButtonPainter"/> <property key="foreground" type="idref" value="ArrowButtonPainter"/> </style>
您还可以指定要应用于特定状态的属性。每个状态是否访问属性取决于属性的使用方式。例如,以下指定了一个默认图标和一个当鼠标悬停在组件上时要使用的图标。
<style id="test"> <imageIcon id="defaultIcon" path="resources/myImage.png"/> <property key="RadioButton.icon" value="defaultIcon"/> <state value="MOUSE_OVER"> <imageIcon id="mouseOverIcon" path="resources/myMouseOverImage.png"/> <property key="RadioButton.icon" value="mouseOverIcon"/> </state> </style>
<!ELEMENT defaultsProperty EMPTY> <!ATTLIST defaultsProperty key CDATA #REQUIRED type (idref|boolean|dimension|insets|integer|string) "idref" value CDATA #REQUIRED >
Attribute definitions
- key
- 财产的名称。
- type
- 指示属性的类型。
- value
- 财产的值。对于布尔属性,这将是 true 或 false,对于整数属性,这将是一个有效整数,对于维度,这将是宽度和高度,由空格分隔,对于 insets 属性,这将是顶部、左侧、底部和右侧,由空格分隔一个空格,对于 idref 属性,这将是先前定义的对象的唯一 ID。
DefaultsProperty 元素用于定义将放置在 SynthLookAndFeel 提供给 UIManager 的 UIDefaults 表中的属性。下面将 Color red 赋值给 Table.focusCellForeground。
<style id="test"> <object class="javax.swing.plaf.ColorUIResource" id="color"> <int>255</int> <int>0</int> <int>0</int> </object> <defaultsProperty key="Table.focusCellForeground" type="idref" value="color"/> </style>
然后可以通过 UIManager.get("Table.focusCellForeground") 询问该值。
graphicsUtils 元素
<!ELEMENT graphicsUtils EMPTY> <!ATTLIST graphicsUtils idref IDREF #REQUIRED >
Attribute definitions
GraphicsUtils 元素用于定义当前 style 将使用的 SynthGraphicsUtils。以下示例使用 SynthGraphicsUtils 的 CustomGraphicsUtils 实例创建样式。
<style id="test"> <object class="CustomGraphicsUtils" id="graphics"/> <graphicsUtils idref="graphics"/> </style>
插入元素
<!ELEMENT insets EMPTY> <!ATTLIST insets id ID #IMPLIED idref IDREF #IMPLIED top CDATA #IMPLIED bottom CDATA #IMPLIED left CDATA #IMPLIED right CDATA #IMPLIED >
Attribute definitions
- id
- insets的唯一标识符。
- idref
- 先前定义的 Insets 的标识符。
- top
- insets的顶部组件。
- bottom
- insets的底部组件。
- left
- insets的左侧组件。
- right
- Insets 的右侧组件。
Insets 元素用于定义当前 style 的insets。insets将设置在与 style 关联的任何组件上。下面的示例创建了一个样式,其 insets 为 1、2、3、0。
<style id="test"> <insets top="1" bottom="2" left="3"/> </style>
绑定元素
<!ELEMENT bind EMPTY> <!ATTLIST bind style IDREF #REQUIRED type (name|region) #REQUIRED key CDATA #REQUIRED >
Attribute definitions
- style
- 先前定义的样式的唯一标识符。
- type
- 名称或区域之一。对于类型名称,使用 component.getName() ,否则使用区域的名称。
- key
- 应用于组件名称或区域名称的正则表达式,具体取决于 type 的值。
Bind 元素指定样式要用于哪些区域。以下示例将 style 测试应用于名称以 test 开头的任何组件。
<style id="test"> <insets top="1" bottom="2" left="3"/> </style> <bind style="test" type="name" key="test.*"/>
许多样式可能适用于一个区域,在这种情况下,每个匹配样式都被合并到使用的结果样式中。优先考虑文件中稍后定义的样式。例如,下面定义了两种样式 a 和 b。样式 a 应用于名称以 test 开头的任何组件,样式 b 用于按钮区域。
<style id="a"> <font name="DIALOG" size="12" style="ITALIC"/> <insets top="1" bottom="2" left="3"/> </style> <bind style="a" type="name" key="test.*"/> <style id="b"> <font name="DIALOG" size="12" style="BOLD"/> </style> <bind style="b" type="region" key="button"/>
对于名称为 test 的按钮,这相当于:
<style> <font name="DIALOG" size="12" style="BOLD"/> <insets top="1" bottom="2" left="3"/> </style>
合并也会发生在样式状态中。
<style id="a"> <font name="DIALOG" size="12" style="ITALIC"/> <insets top="1" bottom="2" left="3"/> <state value="ENABLED"> <object id="customPainter" class="CustomPainter"/> <painter idref="customPainter"/> </state> </style> <bind style="a" type="name" key="test.*"/> <style id="b"> <font name="DIALOG" size="12" style="BOLD"/> <state value="ENABLED"> <font name="Lucida" size="12" style="ITALIC"/> </state> </style> <bind style="b" type="region" key="button"/>
对于名称为 test 的按钮,这相当于:
<style> <font name="DIALOG" size="12" style="BOLD"/> <insets top="1" bottom="2" left="3"/> <state value="ENABLED"> <object id="customPainter" class="CustomPainter"/> <painter idref="customPainter"/> <font name="Lucida" size="12" style="ITALIC"/> </state> </style>
绘制器元素
<!ELEMENT painter EMPTY> <!ATTLIST painter idref IDREF #IMPLIED method CDATA #IMPLIED direction (north|south|east|west|top|left|bottom|right|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED >
Attribute definitions
- idref
- 先前定义的 SynthPainter 的标识符。
- method
- 标识要使用的 SynthPainter 方法。该名称对应于 SynthPainter 中绘画方法的方法名称,去掉了绘画前缀,其余部分不区分大小写(使用 latin1 大小写折叠规则)。例如 SynthPainter.paintButtonBackground 由“buttonBackground”或“buttonbackground”标识。如果未指定,绘制器将用于所有没有特定绘制器的方法。
- direction
- 标识此绘制器要用于的方向或方位。这仅对采用方向或方向的 SynthPainter 方法有用。如果未指定,绘制器将用于所有方向。
Painter为当前样式或当前样式的状态定义了一个SynthPainter。以下示例将类 MyPainter 的实例绑定到样式 test ,它必须是 SynthPainter。
<style id="test"> <object class="MyPainter" id="MyPainter"/> <painter idref="MyPainter"/> </style>
用于特定方法和状态的绘制器按如下方式确定:
- 为当前状态、方法和方向指定的绘制器。
- 为当前状态和方法指定的绘制器。
- 为当前状态指定的绘制器。
- 绘制器指定的风格、方法和方向。
- 绘制器指定的风格和方法。
- 为样式指定的绘制器。
考虑以下:
<style id="test"> <painter idref="fallbackPainter"/> <painter idref="styleButtonBackgroundPainter" method="buttonBackground"/> <state value="SELECTED"> <painter idref="stateFallbackPainter"/> <painter idref="stateButtonBackgroundPainter" method="buttonBackground"/> </state> </style>
以下概述了哪种绘制器将用于哪种 SynthPainter 方法:
| 索引 | State | Method | Painter |
|---|---|---|---|
| 1 | SELECTED | paintButtonBackground | stateButtonBackgroundPainter |
| 2 | SELECTED | 除了 paintButtonBackground | stateFallbackPainter |
| 3 | 除了选择 | paintButtonBackground | 样式按钮背景绘制器 |
| 4 | 除了选择 | 除了 paintButtonBackground | fallbackPainter |
当声明了几个相同的绘制器时,他们会聚合成一个。如果两个绘制器的 direction 和 method 属性值相等,则他们是相同的。考虑以下:
<style id="panelStyle">
<imagePainter method="panelBackground" path="red.png" />
<imagePainter method="panelBackground" path="green.png" />
<imagePainter method="panelBackground" path="blue.png" />
</style>
这三个绘制器是相同的,因为他们使用相同的方法和相同的方向(默认所有方向)。 Synth 将这些 painters 聚合在一起以创建一个单一的 painters,它将按照声明的顺序绘制其子 painters。因此,Synth 将首先绘制红色图片,然后绘制绿色图片,最后绘制蓝色图片。每个子绘制器都可以看作是聚合绘制器的一层。
Painter 聚合或多层对于重用元素非常有用。假设您想对按钮和选定的菜单项使用高亮效果。使用绘制器聚合,您只需创建一个单独的突出显示绘制器,而不是让按钮和菜单项绘制器处理它。
imagePainter 元素
<!ELEMENT imagePainter EMPTY> <!ATTLIST imagePainter id ID #IMPLIED method CDATA #IMPLIED direction (north|south|east|west|top|left|bottom|right|horizontal|vertical|horizontal_split|vertical_split) #IMPLIED path CDATA #REQUIRED sourceInsets CDATA #IMPLIED destinationInsets CDATA #IMPLIED paintCenter (true|false) "true" stretch (true|false) "true" center (true|false) "false" >
Attribute definitions
- id
- imagePainter 的唯一标识符。
- method
- 标识要使用的 SynthPainter 方法。该名称对应于 SynthPainter 中绘画方法的方法名称,去掉了绘画前缀,其余部分不区分大小写(使用 latin1 大小写折叠规则)。例如 SynthPainter.paintButtonBackground 由“buttonBackground”或“buttonbackground”标识。如果未指定,绘制器将用于所有没有特定绘制器的方法。
- direction
- 标识此图像要用于的方向或方位。这仅对采用方向或方向的 SynthPainter 方法有用。如果未指定,图像将用于所有方向。
- path
- 图片的路径。如果向 SynthLookAndFeel.load 传递一个类,这将使用类方法 getResource(将类提供给加载方法)。如果 load 传递了一个 URL,这将使用 URL 构造函数 URL(context, path) 来解析路径。
- sourceInsets
- 在源图像上插入。这是顶部、左侧、底部、右侧,每个组件由一个空格分隔。
- destinationInsets
- 目标图像的insets。这是顶部、左侧、底部、右侧,每个组件由一个空格分隔。如果未指定,则使用 sourceInsets。
- paintCenter
- 是否绘制图像的中心。
- stretch
- 结果图像的北、南、东、西组件是否应该缩放或平铺。
- 中心
- 图片是否居中。
ImagePainter 元素为将使用指定图像呈现的当前样式或状态定义绘制器。 ImagePainter 提供两种不同的渲染模式。第一种模式用于将图像置于所提供空间的中心。这通常用于在小部件顶部渲染装饰,例如,使用中心模式为滚动按钮指定箭头。以下示例说明了这一点:
<style id="test"> <imagePainter path="resources/myImage.png" center="true"/> </style>
第二种模式用于缩放图像以适应提供的空间。在此模式下,sourceInsets 用于指定图像周围的边框,其中边框的北边、南边、东边和西边被拉伸或平铺(拉伸属性),边框的四个角绘制到位,中心是伸展。在此模式下,您必须指定 sourceInsets。以下示例说明了一个 ImagePainter,它一直使用图像 MyImage.png 和 2 的insets:
<style id="test">
<imagePainter path="resources/myImage.png"
sourceInsets="2 2 2 2"/>
</style>
请参阅 painter 元素的描述,了解有关选择绘制器的优先级的详细信息,并了解如何处理相同的绘制器。
imageIcon 元素
Attribute definitions
ImageIcon 用于分配将图像包装到唯一标识符的图标实现。这通常用于带有图标的属性。以下示例将 ImageIcon 绑定到属性 RadioButton.icon。
<style id="test"> <imageIcon id="icon" path="resources/myImage.png"/> <property key="RadioButton.icon" value="icon"/> </style>
不透明元素
Attribute definitions
- id
- 样式是否应该是不透明的,如果未指定,则样式是不透明的。
不透明 元素指示是否将样式关联的任何组件设置为不透明。无论关联组件的不透明度如何,都会要求绘制器进行绘画。以下示例创建了一个非不透明的样式。
<style id="test"> <opaque value="FALSE"> <painter idref="painter"/> </style>
beansPersistance 实体
Beans 持久性可用于嵌入任何对象。这通常用于嵌入您自己的 Painters,但也可用于其他任意对象。有关 bean 持久性的详细信息,请参阅 http://www.oracle.com/technetwork/java/persistence3-139471.html。
背衬风格
在创建 Synth 文件时,最好创建一个所有组件都使用的背景样式。这将确保任何不匹配特定样式的组件都将具有默认字体、前景、背景和不透明度。以下示例说明了这一点:
<synth> <style id="backingStyle"> <opaque value="true"/> <font name="Dialog" size="12"/> <state> <color value="BLACK" type="BACKGROUND"/> <color value="WHITE" type="FOREGROUND"/> </state> </style> <bind style="backingStyle" type="region" key=".*"/> </synth>