这些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