文件格式

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

id
样式的唯一标识符。
clone
复制并用于新样式的先前定义样式的标识符。这提供了一种仅重写现有样式的一部分的便捷机制。

样式元素对应于 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
字体大小,以像素为单位

定义当前 statestyle 的字体。您必须指定 idrefnamesize

下面的示例创建一个字体为 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.allowsAbsolutePositioningOptionPane.minimumSizeScrollPane.viewportBorderInsetsTree.rowHeightforeground ,其值为 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 提供给 UIManagerUIDefaults 表中的属性。下面将 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

idref
先前定义的 SynthGraphicsUtils 对象的标识符,该对象将用作当前 style 的 SynthGraphicsUtils。

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>
  

用于特定方法和状态的绘制器按如下方式确定:

  1. 为当前状态、方法和方向指定的绘制器。
  2. 为当前状态和方法指定的绘制器。
  3. 为当前状态指定的绘制器。
  4. 绘制器指定的风格、方法和方向。
  5. 绘制器指定的风格和方法。
  6. 为样式指定的绘制器。

考虑以下:

<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 方法:

SynthPainter 方法的绘制器
索引 State Method Painter
1 SELECTED paintButtonBackground stateButtonBackgroundPainter
2 SELECTED 除了 paintButtonBackground stateFallbackPainter
3 除了选择 paintButtonBackground 样式按钮背景绘制器
4 除了选择 除了 paintButtonBackground fallbackPainter

当声明了几个相同的绘制器时,他们会聚合成一个。如果两个绘制器的 directionmethod 属性值相等,则他们是相同的。考虑以下:

<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 元素

<!ELEMENT imageIcon EMPTY>
<!ATTLIST imageIcon
     id          ID       #REQUIRED
     path         CDATA     #REQUIRED
>

Attribute definitions

id
imageIcon 的唯一标识符。
path
图片的路径。这使用类方法 getResource 解析路径,并将类提供给 SynthLookAndFeel.load。

ImageIcon 用于分配将图像包装到唯一标识符的图标实现。这通常用于带有图标的属性。以下示例将 ImageIcon 绑定到属性 RadioButton.icon。

<style id="test">
 <imageIcon id="icon" path="resources/myImage.png"/>
 <property key="RadioButton.icon" value="icon"/>
</style>
  

不透明元素

<!ELEMENT opaque EMPTY>
<!ATTLIST opaque
     value       (true|false)  "true"
>

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>