FXML Enhancements Made in JavaFX 2.1 and 2.2
JavaFX 2.1和2.2版本中,增加了如下改进:
* 提供前置反斜杠作为转意字符
JavaFX 2.0使用连续的操作字符作为转意字符,比如$$,%%,@@。在JavaFX 2.1中增加反斜杠作为转意字符,比如\$,\%,\@。这使转意字符再接近统一表达式语言(UEL), 并且开发人员更熟悉。JavaFX 2.0中的转意字符在JavaFX 2.1中被弃用。
* 控制文档命名空间的隐藏(implicit)变量
有一个特性双向绑定控件和UI。双向绑定在JavaFX 2.1中被抛弃,但这个特性被保留。
* 简化构建FXMLLoader类
FXMLLoader类增加了一些新的简单易用的构造函数。
* 可定制控件实例化
//以待日后补充
* 简化使用样式表(style sheets)
在JavaFX 2.0中,在FXML中应用样式表并不容易。但在JavaFX 2.1中,已经变得很简单。样式表可以作为属性被特别写到根元素<Scene>:
<Scene stylesheets="/com/foo/stylesheet1.css, /com/foo/stylesheet2.css"></Scene>
单个节点可以这样使用样式类型:
<Label styleClass="heading, firstPage" text="First Page Heading"/>
* 调用具体的无参数(Caller-specified no-arg)控件方法作为事件handler
在JavaFx 2.0,控件基础事件handler必须接收一个继承自Event类的参数,并返回void。在JavaFX 2.1,参数的限制被取消,我们可以写一个无参数的控件事件handler。
* <fx:constant>标签
我们可以在FXML中添加<fx:constant>标签来查找常量。比如,我们定义了名为NEGATIVE_INFINITY的Double类,现在引用它:
<Double fx:constant="NEGATIVE_INFINITY"/>
* FXML中方便访问子控件
在JavaFX 2.1及之前的版本,从根控件访问子控件并不是一件容易的事。
JavaFX 2.2映射被嵌套的控件作为成员变量,使用它可以更方便与嵌套控件相互作用。
<VBox fx:controller="com.foo.MainController">
...
<fx:include fx:id="dialog" source="dialog.fxml"/>
...
</VBox>
public class MainController extends Controller {
@FXML private Window dialog;
@FXML private DialogController dialogController;
...
}
Creating an Address Book with FXML
我们接下来创建一个包含名字和邮箱地址的表。并在表中填入数据,在启动时对数据排序,数据在单元格里自动对齐,增加新数据到表中。
在开始这个例子前,一些基础知识我们应该了解:
* FXML工程的基本结构(.java, .fxml, 和controller文件)
* 如何创建并运行FXML工程
* 基本的layout和UI控件
先来看看我们将要实现的工程运行结果是什么样子的
创建启动类----TableViewMain.java
public class TableViewMain extends Application{
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("FXML TableView Example");
Pane myPane = FXMLLoader.load(getClass().getResource("tableview.fxml"));
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
public static void main(String args[]){
launch(args);
}
}
建立layout并加入标签和表<GridPane alignment="CENTER" hgap="10.0" vgap="10.0"
xmlns:fx="http://javafx.com/fxml"
fx:controller="example.fxml.tableview.TableViewController">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<Label style="-fx-font: NORMAL 20 Tahoma;" text="Address Book" GridPane.columnIndex="0" GridPane.rowIndex="0">
</Label>
<TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">
<columns>
<TableColumn text="First Name"></TableColumn>
<TableColumn text="Last Name"></TableColumn>
<TableColumn text="Email Address"></TableColumn>
</columns>
</TableView>
</GridPane>
定义数据模型public class Person {
private final SimpleStringProperty firstName = new SimpleStringProperty("");
private final SimpleStringProperty lastName = new SimpleStringProperty("");
private final SimpleStringProperty email = new SimpleStringProperty("");
public Person() {
this("", "", "");
}
public Person(String firstName, String lastName, String email) {
setFirstName(firstName);
setLastName(lastName);
setEmail(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lName) {
lastName.set(lName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String e) {
email.set(e);
}
}
将数据 与表关联起来创建ObservableList数组
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<Person firstName="Jacob" lastName="Smith" email="jacob.smith@aa.com"/>
<Person firstName="Isabella" lastName="Johnson" email="isabella.johnson@aa.com"/>
<Person firstName="Ethan" lastName="Williams" email="ethan.williams@aa.com"/>
</FXCollections>
</items>
</TableView>
为每一殒指定一个单元格工厂将数据关联起来
<columns>
<TableColumn text="First Name">
<cellValueFactory>
<PropertyValueFactory property="firstName"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Last Name">
<cellValueFactory>
<PropertyValueFactory property="lastName"/>
</cellValueFactory>
</TableColumn>
<TableColumn text="Email Address">
<cellValueFactory>
<PropertyValueFactory property="email"/>
</cellValueFactory>
</TableColumn>
</columns>
引入所需的包<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.collections.*?>
<?import example.fxml.tableview.*?>
设定启动时排序
Add an ID to the First Name column:
<TableColumn fx:id="firstNameColumn" text="First Name">
Specify the sort order</items>
<sortOrder>
<fx:reference source="firstNameColumn"/>
</sortOrder>
</TableView>
定义列宽度<TableColumn fx:id="firstNameColumn" text="First Name" prefWidth="100">