與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開發筆記(序)章節目錄》