下拉框只有在單擊時纔會彈出全部選項的下拉列表,這當然節省了有限的界面空間,但有時候又須要把全部選項都固定展現到窗口上。像這種平鋪的列表控件,Swing給出的控件名稱是ListBox,而JavaFX提供了列表視圖ListView。在具體編碼運用上,ListView的用法幾乎跟ComboBox如出一轍,兩者的列表項擁有相同的數據來源,一樣調用setStyle方法來設置各項字體,並且列表項的選擇監聽器也保持一致,惟一的區別即是控件名稱由ComboBox改爲了ListView。
既然ListView的用法與ComboBox雷同,這裏就再也不羅嗦了,仍舊以快餐列表爲例,且看下面的ListView使用代碼片斷:html
// 獲取列表的界面 private void getListView(BorderPane borderPane) { VBox vbox = new VBox(); // 建立一個垂直箱子 // 初始化快餐列表 List<String> snackList = Arrays.asList("魚香肉絲飯", "香菇滑雞飯", "黑椒牛排飯", "梅菜扣肉飯", "糖醋里脊飯", "紅燒排骨飯", "臺式滷肉飯"); // 把清單對象轉換爲JavaFX控件可以識別的數據對象 ObservableList<String> obList = FXCollections.observableArrayList(snackList); ListView<String> listView = new ListView<String>(obList); // 依據指定數據建立列表視圖 //listView.setItems(obList); // 設置列表視圖的數據來源 listView.setPrefSize(400, 180); // 設置列表視圖的推薦寬高 Label label = new Label("這裏查看點餐結果"); // 建立一個標籤 label.setWrapText(true); // 設置標籤文本是否支持自動換行 vbox.getChildren().addAll(listView, label); // 把列表和標籤一塊兒加到垂直箱子上 // 設置列表視圖的選擇監聽器 listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() { @Override public void changed(ObservableValue<? extends String> arg0, String old_str, String new_str) { // getSelectedIndex方法可得到選中項的序號,getSelectedItem方法可得到選中項的對象 String desc = String.format("您點了第%d項,快餐名稱是%s", listView.getSelectionModel().getSelectedIndex(), listView.getSelectionModel().getSelectedItem().toString()); label.setText(desc); // 在標籤上顯示當前選中的文本項 } }); borderPane.setCenter(vbox); // 把垂直箱子放到邊界窗格的中央 }
運行包含以上代碼的測試程序,在彈出的窗口中單擊按鈕「顯示列表」,界面中央展現了平鋪直敘的快餐列表視圖,正以下面左圖所示。單擊列表中的某種快餐,窗口下方會顯示當前的選擇結果,此時界面效果以下面右圖所示。數據結構
儘管ListView可以將全部選項羅列在界面上,但是每行僅僅顯示當前選項的文本,沒法展示更豐富的組合信息。好比餐廳的點餐窗口,除了快餐名稱,還應展現快餐價格,如此一來,整個快餐列表更像是一份表格,不但分行並且分列,才顯得井井有理。爲此JavaFX提供了對應的表格控件名叫TableView,不過由於表格內嵌告終構化信息,因此表格內容須要特製的數據實體。就快餐的數據結構而言,假設它由序號、快餐名稱、快餐價格這三個字段組成,則要預先定義以下所示的快餐信息類:ide
//定義快餐類 public class Snack { private SimpleStringProperty xuhao; // 序號 private SimpleStringProperty name; // 快餐名稱 private SimpleStringProperty price; // 快餐價格 public Snack(String xuhao, String name, String price) { this.xuhao = new SimpleStringProperty(xuhao); this.name = new SimpleStringProperty(name); this.price = new SimpleStringProperty(price); } public String getXuhao() { // 獲取序號 return xuhao.get(); } public void setXuhao(String xuhao) { // 設置序號 this.xuhao.set(xuhao); } public String getName() { // 獲取快餐名稱 return name.get(); } public void setName(String name) { // 設置快餐名稱 this.name.set(name); } public String getPrice() { // 獲取快餐價格 return price.get(); } public void setPrice(String price) { // 設置快餐價格 this.price.set(price); } }
注意上面定義的快餐各字段屬性,它們的數據類型爲表格專用的SimpleStringProperty,只有該類型的數據纔會自動填充到表格單元中。測試
定義好了快餐信息類,接下來再操做表格控件TableView,使用該控件主要包括下列兩個步驟:
一、指定表格視圖的數據來源
首先建立快餐列表的清單對象,並將其轉換爲JavaFX可以識別的ObservableList對象,而後依據這個數據對象建立表格視圖,相應的代碼片斷示例以下:字體
// 建立表格的內容清單 List<Snack> snackList = Arrays.asList( new Snack("1", "魚香肉絲飯", "16"), new Snack("2", "香菇滑雞飯", "18"), new Snack("3", "黑椒牛排飯", "20"), new Snack("4", "梅菜扣肉飯", "17"), new Snack("5", "糖醋里脊飯", "19"), new Snack("6", "紅燒排骨飯", "17"), new Snack("7", "臺式滷肉飯", "15")); // 把清單對象轉換爲JavaFX控件可以識別的數據對象 ObservableList<Snack> obList = FXCollections.observableArrayList(snackList); TableView<Snack> tableView = new TableView<Snack>(obList); // 依據指定數據建立表格視圖
二、建立各列的表頭,以及各列關聯的對象屬性
前一步的數據來源只包含表格的單元內容,不包括表頭的標題行。標題行須要另外經過TableColumn聲明,表格有多少列,就得聲明多少個TableColumn對象,該對象不但規定了當列的標題文字,還規定了當列的內容取自哪一個屬性,屬性名稱與第一步數據對象的字段名稱保持一致。以快餐信息爲例,快餐對象擁有序號、快餐名稱、快餐價格三個字段,則要給快餐表格分配三個列,且這三列的單元值分別取自Snack類的三個字段(xuhao、name、price)。因而編寫表頭及其關聯屬性的代碼例子以下:this
TableColumn firstColumn = new TableColumn("序號"); // 建立一個表格列 firstColumn.setMinWidth(100); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處序號列要展現Snack元素的xuhao屬性值 firstColumn.setCellValueFactory(new PropertyValueFactory<>("xuhao")); TableColumn secondColumn = new TableColumn("快餐名稱"); // 建立一個表格列 secondColumn.setMinWidth(200); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處名稱列要展現Snack元素的name屬性值 secondColumn.setCellValueFactory(new PropertyValueFactory<>("name")); TableColumn thirdColumn = new TableColumn("快餐價格"); // 建立一個表格列 thirdColumn.setMinWidth(110); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處價格列要展現Snack元素的price屬性值 thirdColumn.setCellValueFactory(new PropertyValueFactory<>("price")); // 把幾個標題列一齊添加到表格視圖 tableView.getColumns().addAll(firstColumn, secondColumn, thirdColumn);
把上述兩個步驟加以整合,造成完整的表格操做過程,合併後的表格視圖調用代碼以下所示:編碼
// 獲取表格的界面 private void getTableView(BorderPane borderPane) { VBox vbox = new VBox(); // 建立一個垂直箱子 // 建立表格的內容清單 List<Snack> snackList = Arrays.asList( new Snack("1", "魚香肉絲飯", "16"), new Snack("2", "香菇滑雞飯", "18"), new Snack("3", "黑椒牛排飯", "20"), new Snack("4", "梅菜扣肉飯", "17"), new Snack("5", "糖醋里脊飯", "19"), new Snack("6", "紅燒排骨飯", "17"), new Snack("7", "臺式滷肉飯", "15")); // 把清單對象轉換爲JavaFX控件可以識別的數據對象 ObservableList<Snack> obList = FXCollections.observableArrayList(snackList); TableView<Snack> tableView = new TableView<Snack>(obList); // 依據指定數據建立表格視圖 //tableView.setItems(obList); // 設置表格視圖的數據來源 tableView.setPrefSize(400, 210); // 設置表格視圖的推薦寬高 TableColumn firstColumn = new TableColumn("序號"); // 建立一個表格列 firstColumn.setMinWidth(100); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處序號列要展現Snack元素的xuhao屬性值 firstColumn.setCellValueFactory(new PropertyValueFactory<>("xuhao")); TableColumn secondColumn = new TableColumn("快餐名稱"); // 建立一個表格列 secondColumn.setMinWidth(200); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處名稱列要展現Snack元素的name屬性值 secondColumn.setCellValueFactory(new PropertyValueFactory<>("name")); TableColumn thirdColumn = new TableColumn("快餐價格"); // 建立一個表格列 thirdColumn.setMinWidth(110); // 設置列的最小寬度 // 設置該列取值對應的屬性名稱。此處價格列要展現Snack元素的price屬性值 thirdColumn.setCellValueFactory(new PropertyValueFactory<>("price")); // 把幾個標題列一齊添加到表格視圖 tableView.getColumns().addAll(firstColumn, secondColumn, thirdColumn); vbox.getChildren().add(tableView); // 把表格加到垂直箱子上 borderPane.setCenter(vbox); // 把垂直箱子放到邊界窗格的中央 }
運行包含以上代碼的測試程序,在彈出的窗口中單擊按鈕「顯示錶格」,界面上呈現了一個內容豐富的快餐表格,具體效果以下圖所示。spa
更多Java技術文章參見《Java開發筆記(序)章節目錄》3d