Java開發筆記(一百四十)JavaFX的選擇框

與Swing同樣,JavaFX依然提供了三種選擇框,它們是複選框CheckBox、單選按鈕RadioButton、下拉框ComboBox,分別說明以下:css

1、複選框CheckBox
複選框容許同時勾選多個,已勾選的時候在方框內部打個勾,未勾選的時候顯示空心方框。查看CheckBox的源碼,發現它與Button控件都派生自抽象類ButtonBase,於是CheckBox擁有和Button一樣的set***/get***方法。不一樣之處主要有如下兩點:
一、關於勾選狀態的設置與判斷:調用setSelected方法能夠設置複選框的勾選狀態,調用isSelected方法能夠判斷複選框是否被勾選了。
二、關於勾選監聽器的設置:先調用selectedProperty方法得到複選框的屬性對象,再調用屬性對象的addListener方法設置該複選框的勾選監聽器。下面是給複選框設置單擊監聽器的代碼例子:html

		CheckBox ck = new CheckBox("滿意"); // 建立一個複選框
		ck.selectedProperty().addListener(new ChangeListener<Boolean>() { // 設置複選框的勾選監聽器
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
				// 單擊複選框會觸發這裏的changed方法
			}
		});

 

接下來舉個具體的案例,餐廳的點餐系統要在界面上羅列各類菜餚,以便顧客勾選準備下單的菜品。簡單起見先列出三道菜餚,對應三個複選框,編寫完成的界面代碼示例以下:數組

	// 獲取複選框的界面
	private void getCheckBox(BorderPane borderPane) {
		VBox vbox = new VBox(); // 建立一個垂直箱子
		HBox hbox = new HBox(); // 建立一個水平箱子
		CheckBox ck1 = new CheckBox("麻婆豆腐"); // 建立一個複選框
		CheckBox ck3 = new CheckBox("清蒸桂花魚"); // 建立一個複選框
		CheckBox ck2 = new CheckBox("香辣小龍蝦"); // 建立一個複選框
		hbox.getChildren().addAll(ck1, ck2, ck3); // 把三個複選框一塊兒加到水平箱子上
		CheckBox[] boxArray = new CheckBox[]{ck1, ck2, ck3}; // 構建複選框數組
		Label label = new Label("這裏查看菜單詳情"); // 建立一個標籤
		label.setWrapText(true); // 設置標籤文本是否支持自動換行
		vbox.getChildren().addAll(hbox, label); // 把水平箱子和標籤一塊兒加到垂直箱子上
		ck1.selectedProperty().addListener(new ChangeListener<Boolean>() { // 設置複選框的勾選監聽器
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
				// 拼接並顯示當前的勾選結果,以及已經勾選的菜餚
				label.setText(String.format("您%s了%s。當前已點菜餚包括:%s",
						(ck1.isSelected() ? "點" : "取消"), ck1.getText(), getCheckedItem(boxArray)));
			}
		});
		ck2.selectedProperty().addListener(new ChangeListener<Boolean>() { // 設置複選框的勾選監聽器
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) {
				// 拼接並顯示當前的勾選結果,以及已經勾選的菜餚
				label.setText(String.format("您%s了%s。當前已點菜餚包括:%s",
						(ck2.isSelected() ? "點" : "取消"), ck2.getText(), getCheckedItem(boxArray)));
			}
		});
		ck3.selectedProperty().addListener(new ChangeListener<Boolean>() { // 設置複選框的勾選監聽器
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0, Boolean old_value, Boolean new_value) {
				// 拼接並顯示當前的勾選結果,以及已經勾選的菜餚
				label.setText(String.format("您%s了%s。當前已點菜餚包括:%s",
						(ck3.isSelected() ? "點" : "取消"), ck3.getText(), getCheckedItem(boxArray)));
			}
		});
		borderPane.setCenter(vbox); // 把垂直箱子放到邊界窗格的中央
	}

 

上面代碼用到了新方法getCheckedItem,該方法用來獲取已經選中的全部菜餚,它的代碼定義以下所示:ide

	// 獲取已經選定的菜單
	private String getCheckedItem(CheckBox[] boxArray) {
		String itemDesc = "";
		for (CheckBox box : boxArray) { // 遍歷複選框數組
			if (box.isSelected() == true) { // 複選框被選中了
				if (itemDesc.length() > 0) {
					itemDesc = itemDesc + "、";
				}
				itemDesc = itemDesc + box.getText(); // 菜單添加選定的菜餚
			}
		}
		return itemDesc;
	}

 

運行包含以上代碼的點餐程序,彈出的窗口初始界面以下圖所示。字體


從左往右依次單擊三個複選框,界面上的點餐結果分別以下列三張圖所示。spa

 

2、單選按鈕RadioButton
在同一小組內的單選按鈕,最多隻能選擇其中一個,它被選中時在圓圈內部顯示一個圓點,未選中時只顯示空心圓圈。RadioButton也由ButtonBase派生而來,所以擁有與Button控件一樣的set***/get***方法。區別之處主要有下列兩點:
一、關於加入到一個單選小組:調用單選按鈕的setToggleGroup方法,便可加入到指定的按鈕小組,該小組的控件類型是ToggleGroup。
二、關於單選按鈕的選擇監聽器:JavaFX把這個監聽器改到小組上面了,先調用ToggleGroup對象的selectedToggleProperty方法得到單選組的屬性對象,再調用屬性對象的addListener方法設置該小組的單擊監聽器。
仍然以點餐系統爲例,此次準備讓顧客享用單點的快餐,小店剛開業暫時只提供三種快餐,對應三個單選按鈕,編寫完成的界面代碼示例以下:orm

	// 獲取單選按鈕的界面
	private void getRadioButton(BorderPane borderPane) {
		VBox vbox = new VBox(); // 建立一個垂直箱子
		HBox hbox = new HBox(); // 建立一個水平箱子
		RadioButton rb1 = new RadioButton("魚香肉絲飯"); // 建立一個單選按鈕
		rb1.setSelected(true); // 設置按鈕是否選中
		RadioButton rb2 = new RadioButton("香菇滑雞飯"); // 建立一個單選按鈕
		RadioButton rb3 = new RadioButton("黑椒牛排飯"); // 建立一個單選按鈕
		hbox.getChildren().addAll(rb1, rb2, rb3); // 把三個單選按鈕一塊兒加到水平箱子上
		ToggleGroup group = new ToggleGroup(); // 建立一個按鈕小組
		rb1.setToggleGroup(group); // 把單選按鈕1加入到按鈕小組
		rb2.setToggleGroup(group); // 把單選按鈕2加入到按鈕小組
		rb3.setToggleGroup(group); // 把單選按鈕3加入到按鈕小組
		Label label = new Label("這裏查看點餐結果"); // 建立一個標籤
		label.setWrapText(true); // 設置標籤文本是否支持自動換行
		vbox.getChildren().addAll(hbox, label); // 把水平箱子和標籤一塊兒加到垂直箱子上
		// 設置單選組合的單擊監聽器
		group.selectedToggleProperty().addListener(new ChangeListener<Toggle>() {
			@Override
			public void changed(ObservableValue<? extends Toggle> arg0, Toggle old_toggle, Toggle new_toggle) {
				// 在標籤上顯示當前選中的單選按鈕文本
				label.setText("您點了" + ((RadioButton)new_toggle).getText());
			}
		});
		borderPane.setCenter(vbox); // 把垂直箱子放到邊界窗格的中央
	}

 

運行包含以上代碼的點餐程序,彈出的窗口初始界面以下圖所示。htm


從圖示可見當前默認選中了第一個快餐「魚香肉絲飯」,此時前後單擊第二個快餐和第三個快餐,界面上的點餐結果分別以下列兩張圖所示。對象

 

3、下拉框ComboBox
若是單選小組裏面的選項有不少,所有羅列到窗口上勢必佔用大量界面空間,故而採用可伸縮的下拉框較爲合適。平時只顯示最近一次選中的文字,須要改變的話再單擊彈出下拉列表,在下拉列表中選完再恢復原狀。看起來JavaFX的下拉框跟Swing的功能差很少,不過JavaFX的ComboBox控件用起來頗爲怪異,有下面幾點須要特別注意:
一、關於選中某項以及獲取選中項:得先調用下拉框的getSelectionModel方法得到模型對象,再調用模型對象的相應方法完成指定功能。例如,調用模型對象的select方法能夠選中某項,調用getSelectedIndex方法能夠得到選中項的序號,調用getSelectedItem方法能夠得到選中項的對象。
二、關於設置下拉框的字體:ComboBox控件居然沒提供setFont方法,只能調用setStyle方法經過css樣式設置文本字體及其大小。
三、關於設置下拉框的選擇監聽器:這個操做更復雜,要先調用下拉框的getSelectionModel方法得到模型對象,再調用模型對象的selectedItemProperty方法得到該模型的屬性對象,接着調用屬性對象的addListener方法給下拉框添加選擇監聽器。
繼續以點餐系統爲例,原來那家快餐店的生意日趨紅火,快餐種類增長了很多,他們的點餐系統也將單選小組改形成了下拉框。改造完成的界面代碼示例以下:blog

	// 獲取下拉框的界面
	private void getComboBox(BorderPane borderPane) {
		VBox vbox = new VBox(); // 建立一個垂直箱子
		// 初始化快餐列表
		List<String> snackList = Arrays.asList("魚香肉絲飯", "香菇滑雞飯", "黑椒牛排飯",
				"梅菜扣肉飯", "糖醋里脊飯", "紅燒排骨飯", "臺式滷肉飯");
		// 把清單對象轉換爲JavaFX控件可以識別的數據對象
		ObservableList<String> obList = FXCollections.observableArrayList(snackList);
		ComboBox<String> comboBox = new ComboBox<String>(obList); // 依據指定數據建立下拉框
		//comboBox.setItems(obList); // 設置下拉框的數據來源
		comboBox.getSelectionModel().select(0); // 設置下拉框默認選中第1項
		Font font = Font.font("NSimSun", 16); // 建立一個字體對象
		comboBox.setStyle(String.format("-fx-font: %f \"%s\";", font.getSize(), font.getFamily())); // 設置下拉框的字體
		comboBox.setEditable(false); // 設置下拉框可否編輯。默認不容許編輯
		Label label = new Label("這裏查看點餐結果"); // 建立一個標籤
		label.setWrapText(true); // 設置標籤文本是否支持自動換行
		vbox.getChildren().addAll(comboBox, label); // 把水平箱子和標籤一塊兒加到垂直箱子上
		// 設置下拉框的選擇監聽器
		comboBox.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", 
						comboBox.getSelectionModel().getSelectedIndex(), 
						comboBox.getSelectionModel().getSelectedItem().toString());
				label.setText(desc); // 在標籤上顯示當前選中的文本項
			}
		});
		borderPane.setCenter(vbox); // 把垂直箱子放到邊界窗格的中央
	}

 

運行包含以上代碼的點餐程序,彈出的窗口初始界面以下圖所示。


單擊下拉框控件,下方彈出一個包含全部快餐的列表框,具體界面以下圖所示。


單擊下拉列表中的某一項,表示換成指定的快餐,此時下拉列表隱藏,下拉框的文字變成剛點的快餐名稱,點餐結果正以下圖所示。

 



更多Java技術文章參見《Java開發筆記(序)章節目錄

相關文章
相關標籤/搜索