文档

Java™ 教程
隐藏目录
Synth示例
路径: 使用Swing创建GUI
教程: 修改外观和感觉
章节: Synth外观和感觉

一个Synth示例

在名为A GroupLayout Example的教程中,使用了GroupLayout来创建一个名为"Find"的搜索对话框。创建对话框的程序Find.java使用了跨平台("Metal")的外观,并使用了"Ocean"主题:

Find.

本教程使用Synth来创建相同的对话框,使用了一个外部的XML文件。以下是SynthDialog.java文件的代码清单:

SynthDialog.javaFind.java完全相同,只是initLookAndFeel()方法有所改变,使用了名为synthDemo.xml的外部文件来使用Synth外观。以下是新的initLookAndFeel()方法:

private static void initLookAndFeel() {
   SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();
       
   // SynthLookAndFeel的load()方法抛出一个受检异常(java.text.ParseException),所以必须处理该异常
   try {
      lookAndFeel.load(SynthDialog.class.getResourceAsStream("synthDemo.xml"),
                                                               SynthDialog.class);
      UIManager.setLookAndFeel(lookAndFeel);
   } 
            
   catch (ParseException e) {
      System.err.println("由于某种原因无法获取指定的外观("
                                   + lookAndFeel
                                    + ").");
      System.err.println("使用默认的外观.");
      e.printStackTrace();
   }
}

XML文件

XML文件synthDemo.xml从一个绑定到所有区域的样式开始。这是一个良好的实践,以确保没有绑定样式的区域也能包含一些内容。该样式使所有区域使用不透明的背景色绘制。它还设置了默认的字体和默认的颜色。

  <!-- 所有区域都将使用的样式 -->
  <style id="backingStyle">
    <!-- 使所有区域不透明-->
    <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=".*"/>

注: 

1. 颜色定义必须在<state>元素内部。这样可以根据状态改变颜色。在backingStyle中的<state>元素没有属性,因此适用于所有区域,无论其状态如何。如果一个区域有其他状态,这些状态将与文件中后出现的状态定义合并,优先级更高。

2. 字体定义不在<state>元素内,因为字体在状态改变时应该不会改变(许多组件的大小取决于它们的字体,而字体的改变可能会导致组件的大小意外改变)。


下一个定义的<style>元素是用于文本字段,使用图像进行绘制。

  <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"/>

注意事项: 

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

2. insetssourceInsets被赋予了相同的值,这只是一个巧合,因为它们之间没有关联。

3. 背景颜色的定义,即#D2DFF2,是一种淡蓝色,与图像textfield.png的背景颜色相同。

4. paintCenter被设置为false,以便您可以看到背景颜色。


下一个<style>元素是用于按钮的,根据按钮的状态绘制不同的图像。当鼠标经过按钮时,其外观会改变。当按钮被点击(按下)时,图像再次改变。

 <style id="button">
        <!-- 当按下按钮时,将文本向下偏移一个像素 -->
    <property key="Button.textShiftOffset" type="integer" value="1"/>
    <!-- 设置按钮的大小 -->
    <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"/>

注意事项: 

1. <state>元素内部没有属性的字体和颜色定义适用于所有按钮状态。这是因为适用的所有状态的定义(而<state>元素没有属性的情况就是其中之一)将合并,没有其他可能优先的字体和颜色定义。

2. sourceInsets的值足够大,以使按钮图像的圆角不会被拉伸。

3. PRESSEDMOUSE_OVER状态的顺序很重要。由于鼠标在按下按钮时始终在按钮上方,两个状态都将应用于按下的按钮,而首先定义的状态(PRESSED)将应用。当鼠标在按钮上方但未按下时,只有MOUSE_OVER状态适用。如果颠倒PRESSEDMOUSE_OVER状态的顺序,PRESSED状态的图像将永远不会被使用。


下一个<style>元素用于根据复选框的状态绘制不同的图标。

  <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"/>    

注意: 

1. 必须使用<imageIcon>元素来定义要使用的任何图标。

2. 由于图标以其固定大小呈现且不被拉伸,因此不使用<insets>元素和sourceInsets属性。

3. 用于绘制复选框的图标是在CheckBox.icon属性中命名的图标(请参阅javax/swing/plaf/synth/doc-files/componentProperties.html),除非复选框状态为SELECTED


synthDemo.xml文件由上面介绍的样式组成,包裹在<synth></synth>标签中。您可以通过点击synthDemo.xml打开完成的文件。


试一试: 

点击"Launch"按钮使用Java™ Web Start运行SynthDialog示例(下载JDK 7或更高版本)。或者,要自己编译和运行示例,请参考示例索引</ a>。

启动SynthDialog示例


上一页: Synth外观
下一页: Nimbus外观