JavaFX Label 类支持HTML内容。使用Label您可以使用HTML和CSS创建样式文本和图像,非常类似于典型的Web应用。此外,通过使用JavaFX嵌入表达式,您可以在Swing应用中象Web页面作者使用类似 JSTL 或 Velocity 工具一样创建动态的HTML内容。
考虑以下虚拟购物车示例:
import javafx.ui.*;
class
Item
{
attribute id:
String
; attribute productId:
String
; attribute description:
String
; attribute inStock:
Boolean
; attribute quantity:
Number
; attribute listPrice:
Number
; attribute totalCost:
Number
;
}
attribute Item.
totalCost
= bind quantity*listPrice;
class
Cart
{
attribute items: Item*; attribute subTotal:
Number
;
}
operation sumItems
(
itemList:Item*
)
{
var result =
0.00
;
for
(
item in itemList
)
{
result += item.
totalCost
;
}
return
result;
}
attribute Cart.
subTotal
= bind sumItems
(
items
)
; var cart = Cart
{
items:
[
Item
{
id:
"UGLY"
productId:
"D100"
description:
"BullDog"
inStock:
true
quantity:
1
listPrice:
97.50
}
, Item
{
id:
"BITES"
productId:
"D101"
description:
"Pit Bull"
inStock:
true
quantity:
1
listPrice:
127.50
}
]
}
;
Frame
{
content:
Label
{
text: bind
"<html> <h2 align='center'>Shopping Cart</h2> <table align='center' border='0' bgcolor='#008800' cellspacing='2' cellpadding='5'> <tr bgcolor='#cccccc'> <td><b>Item ID</b></td> <td><b>Product ID</b></td> <td><b>Description</b></td> <td><b>In Stock?</b></td> <td><b>Quantity</b></td> <td><b>List Price</b></td> <td><b>Total Cost</b></td> <td> </td> </tr> { if (sizeof cart.items == 0) then "
<tr bgcolor=
'#FFFF88'
><td colspan=
'8'
><b>Your cart is empty.</b></td></tr>
" else foreach (item in cart.items) "
<tr bgcolor=
'#FFFF88'
> <td>
{
item.
id
}
</td> <td>
{
item.
productId
}
</td> <td>
{
item.
description
}
</td> <td>
{
if
item.
inStock
then
"Yes"
else
"No"
}
</td> <td>
{
item.
quantity
}
</td> <td align=
'right'
>
{
item.
listPrice
}
</td> <td align=
'right'
>
{
item.
totalCost
}
</td> <td> </td> </tr>
" } <tr bgcolor='#FFFF88'> <td colspan='7' align='right'> <b>Sub Total: ${cart.subTotal}</b> </td> <td> </td> </tr> </table> </html>"
}
visible:
true
}
运行以上程序,显示如下:
如果您编程删除购物车内容:
delete cart.
items
;
您将看到如下内容:
在以上示例中,内嵌的JavaFX表达式(粗体显示)动态创建HTML表格列和表格单元的内容。当这些表达式依赖的对象有变化时,Label的HTML内容将自动更新。
以上示例还非常有趣,因为其演示了使用表达式定义属性值的用法。Item类的totalCost属性和Cart类的subTotal属性被绑定为表达式以计算它们的值。任何时候这些表达式的依赖对象发生变化,属性值将被自动重新计算并更新。考虑在电子表格中,某些单元格包含指向其他单元格的表达式,当您在这些其他单元格输入数据,包含依赖它们的表达式的单元格值也被自动更新了。
HTML中的图像
JavaFX Label类实际上封装了一个特殊的JEditPane,该 JEditorPane 使用一个支持用Java类转载器从JAR文件中载入图像的共享图像缓存。因此,您可以就像普通的文件URL一样使用HTML的<img>元素引用您的应用的图像资源包。
超链接
Label类同样支持HTML超链接,内嵌一个特殊的URL给HTML<a>元素的href属性。
这样的URL使用JavaFX #操作符创建,该操作符生成一个字符串化对象引用(Stringified Object Reference)指向后续可以被JavaFX复引用的操作对象。?操作符,例如:
var a =
20
;var b = #a;
assert
b
instanceof
String
;
// 通过
var c =
(
Number
)
?b;
assert
a == c;
// 通过
Label类的HTML显示器认识诸如HTML的<a href=url>这样的URL,使用URL来响应元素的鼠标点击,并且如果URL值指向一个函数或操作的话,它可以调用该函数或操作。
例如,以下是使用带超链接标签代替按钮的前面按钮点击示例的重写版本:
import javafx.ui.*;
import java.lang.System;
class
ButtonClickModel
{
attribute numClicks:
Number
;
}
var model =
new
ButtonClickModel
(
)
; var win =
Frame
{
width:
300
height:
200
menubar:
MenuBar
{
menus:
Menu
{
text:
"File"
mnemonic: F items:
MenuItem
{
text:
"Exit"
mnemonic: X accelerator:
{
modifier: ALT keyStroke: F4
}
action: operation
(
)
{
System
.
exit
(
0
)
;
}
}
}
}
content: GridPanel
{
border:
EmptyBorder
{
top:
30
left:
30
bottom:
30
right:
30
}
rows:
2
columns:
1
vgap:
10
cells:
[
Label
{
text: bind
"<html> <a href='{#(operation() {model.numClicks++;})}'> I'm a hyperlink! </a> </html>"
}
,
Label
{
text: bind
"Number of button clicks: {model.numClicks}"
}
]
}
visible:
true
}
;
以上示例中粗体的表达式创建一个新的递增model的numClicks属性的操作。使用#操作符生成后续将被键入到HTML标记中的指向该操作的URL。
运行该程序,显示如下:
点击超链接两次后,显示如下:

