这些Java教程是为JDK 8编写的。本页面中描述的示例和实践不利用后续版本引入的改进,可能使用已不再可用的技术。
请参阅Java语言更改以了解Java SE 9和后续版本中更新的语言特性的摘要。
请参阅JDK发行说明以获取有关所有JDK版本的新功能、增强功能以及已删除或弃用选项的信息。
在名为A GroupLayout Example的教程中,使用了GroupLayout
来创建一个名为"Find"的搜索对话框。创建对话框的程序Find.java
使用了跨平台("Metal")的外观,并使用了"Ocean"主题:
本教程使用Synth来创建相同的对话框,使用了一个外部的XML文件。以下是
文件的代码清单:SynthDialog.java
SynthDialog.java
与Find.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文件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. insets
和sourceInsets
被赋予了相同的值,这只是一个巧合,因为它们之间没有关联。
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. PRESSED
和MOUSE_OVER
状态的顺序很重要。由于鼠标在按下按钮时始终在按钮上方,两个状态都将应用于按下的按钮,而首先定义的状态(PRESSED
)将应用。当鼠标在按钮上方但未按下时,只有MOUSE_OVER
状态适用。如果颠倒PRESSED
和MOUSE_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