# 合成例

> 原文： [https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synthExample.html](https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synthExample.html)

在标题为 [A GroupLayout 示例](../../uiswing/layout/groupExample.html)的课程中，`GroupLayout`用于创建名为“查找”的搜索对话框。创建对话框的程序`Find.java`使用跨平台（“金属”）外观和“海洋”主题：

<center>![Find.](img/db1be508be14afcae7ce7be90da36315.jpg)</center>

本课程使用外部 XML 文件创建与 Synth 相同的对话框。这是 [``SynthDialog.java``](../examples/lookandfeel/SynthDialogProject/src/lookandfeel/SynthDialog.java)文件的列表。

除了`initLookAndFeel()`方法之外，`SynthDialog.java`与`Find.java`完全相同，`initLookAndFeel()`方法已更改为使用名为`synthDemo.xml`的外部文件的 Synth 外观。这是新的`initLookAndFeel()`方法：

```
private static void initLookAndFeel() {
   SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

   // SynthLookAndFeel load() method throws a checked exception
   // (java.text.ParseException) so it must be handled
   try {
      lookAndFeel.load(SynthDialog.class.getResourceAsStream("synthDemo.xml"),
                                                               SynthDialog.class);
      UIManager.setLookAndFeel(lookAndFeel);
   } 

   catch (ParseException e) {
      System.err.println("Couldn't get specified look and feel ("
                                   + lookAndFeel
                                    + "), for some reason.");
      System.err.println("Using the default look and feel.");
      e.printStackTrace();
   }
}

```

## XML 文件

XML 文件`synthDemo.xml`以绑定到所有区域的样式开头。最好这样做是为了确保没有绑定样式的区域包含某些内容。此样式使所有区域以不透明的颜色绘制其背景。它还设置默认字体和默认颜色。

```
  <!-- Style that all regions will use -->
  <style id="backingStyle">
    <!-- Make all the regions opaque-->
    <opaque value="TRUE"/>
    <font name="Dialog" size="14"/>
    <state>
      <color value="#D8D987" type="BACKGROUND"/>
      <color value="RED" type="FOREGROUND"/>
    </state>
  </style>
  <bind style="backingStyle" type="region" key=".*"/>

```

* * *

**Notes:** 

1.颜色定义必须在&lt; state&gt;内。元件。这允许根据状态改变颜色。 &lt; state&gt; `backingStyle`中的元素没有属性，因此适用于所有区域，无论其状态如何。如果某个区域具有其他状态，则会合并状态，并优先使用稍后出现在文件中的状态定义。

2.字体定义不在&lt; state&gt;内。元素因为当状态发生变化时字体 _ 而不是 _ 会发生变化（许多组件的大小取决于它们的字体，而字体的变化可能会导致组件无意中改变大小）。

* * *

下一个&lt; style&gt;定义的元素用于文本字段，使用图像绘制。

```
  <style id="textfield">
    <insets top="4" left="6" bottom="4" right="6"/>
    <state>
       <font name="Verdana" size="14"/>
       <color value="#D2DFF2" type="BACKGROUND"/>
       <color value="#000000" type="TEXT_FOREGROUND"/>
    </state>
    <imagePainter method="textFieldBorder" path="images/textfield.png"
                  sourceInsets="4 6 4 6" paintCenter="false"/>
  </style>
  <bind style="textfield" type="region" key="TextField"/>

```

* * *

**Notes:** 

1.字体和颜色定义覆盖`backingStyle`中的定义。

2\. `insets`和`sourceInsets`给出相同的值，这只是巧合，因为它们彼此无关。

3.背景颜色＃D2DFF2 是淡蓝色 - 与图像中的背景相同的颜色`textfield.png`。

4\. `paintCenter`为`false`，以便您可以看到背景颜色。

* * *

下一个&lt; style&gt; element 用于绘制不同图像的按钮，具体取决于按钮状态。当鼠标经过按钮时，其外观会发生变化。单击（按下）时，图像会再次更改。

```
 <style id="button">
        <!-- Shift the text one pixel when pressed -->
    <property key="Button.textShiftOffset" type="integer" value="1"/>
    <!-- set size of buttons -->
    <insets top="15" left="20" bottom="15" right="20"/>
    <state>
      <imagePainter method="buttonBackground" path="images/button.png"
                           sourceInsets="10 10 10 10" />
      <font name="Dialog" size="16"/>
      <color type="TEXT_FOREGROUND" value="#FFFFFF"/>
    </state>

    <state value="PRESSED"> 
      <imagePainter method="buttonBackground"
          path="images/button_press.png"
                   sourceInsets="10 10 10 10" />
    </state>

    <state value="MOUSE_OVER">    
      <imagePainter method="buttonBackground"
          path="images/button_over.png"
                 sourceInsets="10 10 10 10" />
    </state>
  </style>
  <bind style="button" type="region" key="Button"/>

```

* * *

**Notes:** 

1.&lt; state&gt;内的字体和颜色定义。没有属性的元素适用于所有按钮状态。这是因为所有适用的状态（以及没有属性的&lt; state&gt;元素就是其中之一）的定义将合并，并且没有其他可能优先的字体和颜色定义。

2\. `sourceInsets`值足够大，按钮图像的弯角不会被拉伸。

3\. `PRESSED`和`MOUSE_OVER`状态的顺序很重要。由于鼠标在按下时总是会在按钮上方，因此两个状态都将应用于按下的按钮，并且将应用定义的第一个状态（`PRESSED`）。当鼠标悬停在按钮上但未按下时，仅适用`MOUSE_OVER`状态。如果反转`PRESSED`和`MOUSE_OVER`状态的顺序，则永远不会使用`PRESSED`状态图像。

* * *

下一个&lt; style&gt; element 用于绘制有不同图标的复选框，具体取决于复选框状态。

```
  <style id="checkbox">
    <imageIcon id="check_off" path="images/checkbox_off.png"/>
    <imageIcon id="check_on" path="images/checkbox_on.png"/>
    <property key="CheckBox.icon" value="check_off"/>
    <state value="SELECTED">   
      <property key="CheckBox.icon" value="check_on"/>
    </state>
  </style>
  <bind style="checkbox" type="region" key="Checkbox"/>    

```

* * *

**Notes:** 

1.您必须使用&lt; imageIcon&gt;元素，用于定义要使用的任何图标。

2.&lt; insets&gt;元素和`sourceInsets`属性不与图标一起使用，因为它们以固定大小呈现并且未拉伸。

3.用于呈现复选框的图标是`CheckBox.icon`属性中指定的图标。 （参见 [`javax/swing/plaf/synth/doc-files/componentProperties.html`](https://docs.oracle.com/javase/8/docs/api/javax/swing/plaf/synth/doc-files/componentProperties.html) ），这是 id =“check_off”的图标，除非复选框状态为`SELECTED`。

* * *

`synthDemo.xml`文件由上面显示的样式构成，包含在&lt; synth&gt;&lt; / synth&gt;中。标签。您可以通过单击 [``synthDemo.xml``](../examples/lookandfeel/SynthDialogProject/src/lookandfeel/synthDemo.xml)打开完成的文件。

* * *

**Try this:** 

单击“启动”按钮以使用 [Java™Web Start](http://www.oracle.com/technetwork/java/javase/javawebstart/index.html) （[下载 JDK 7 或更高版本](http://www.oracle.com/technetwork/java/javase/downloads/index.html)）运行 SynthDialog 示例。或者，要自己编译并运行示例，请参阅[示例索引&lt; / a&gt;。](../examples/lookandfeel/index.html#SynthDialog)

[![Launches the SynthDialog example](img/4707a69a17729d71c56b2bdbbb4cc61c.jpg)](https://docs.oracle.com/javase/tutorialJWS/samples/uiswing/SynthDialogProject/SynthDialog.jnlp)

* * *