Java開發筆記(一百四十一)JavaFX的列表與表格

下拉框只有在單擊時纔會彈出全部選項的下拉列表,這當然節省了有限的界面空間,但有時候又須要把全部選項都固定展現到窗口上。像這種平鋪的列表控件,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

相關文章
相關標籤/搜索