JavaFX中的ChoiceBox中绑定复合对象的操作

时间:2022-12-24 16:59:49
由于地域关系,csdn一直处理不能打开,今天发现竟然是可以打开了,刚好有问题,所以记录一下,希望对其它小伙伴有用
ChoiceBox的官方示例中都是绑定了一个字符串类型的数组,但在实际的开发中多数会绑定一个复合对象到Choicebox中去,
就类似于HTML中的<select>标签一样,Choicebox控件中的选择项中显示的是复合对象的name值(便于识记) ,而我们需要的是id值,实际上choicebox本身的定义就是ChoiceBox<T>,所以允许我们使用复杂对像,只不过这时需要规定此控件中选择项列表的字符串应该以绑定复合对象中的哪一个属性值为作为显示项,这时就需要设置StringConverter<T>对象,同时需要重写toString()方法来设置,代码示例如下:
第一步,代码方式或fxml文件的方式来生产一个ChoiceBox对象(以下使用fxml方式)
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
      <children>
          <ChoiceBox fx:id="ledChoiceBox" prefWidth="150.0" value="请选择LED">
          </ChoiceBox>
          <Button fx:id="sendButton" layoutX="150.0" mnemonicParsing="false" onAction="#sendNormalInfo" text="发送" />
      </children>
</AnchorPane>
第二步,在fxml对应的controller类中先得到此控件并设置对应的converterProperty对象
/**
 * @author 沈旭升
 * @date 2017-12-08 03:02
 */
public class MainPanelController  implements Initializable{
    @FXML
    private AnchorPane prentAnchorPanel;

    @FXML
    private MenuBar menuBar;

    @FXML
    private TextArea normalInfoTextArea;

    @FXML
    private ChoiceBox<Led> ledChoiceBox;


    @FXML
    private MenuItem dataSync;

    @FXML
    private  MenuItem dataImport;

    @FXML
    private MenuItem led;

    private LedServers ledServers = new LedServers();


    public MenuBar getMenuBar() {
        return menuBar;
    }

    public void setMenuBar(MenuBar menuBar) {
        this.menuBar = menuBar;
    }

    @FXML
    public void dataSync(){

        WorkerServers workerServers = new WorkerServers();
        Worker worker= workerServers.getWorkerByCardId("62272619840129****");
        System.out.println(worker.getName());

        Dialog dialog = new ChoiceDialog();
        Alert name = new Alert(Alert.AlertType.INFORMATION);
        name.initOwner(prentAnchorPanel.getScene().getWindow());
        name.initModality(Modality.WINDOW_MODAL);
        name.setTitle("提示信息");
        name.setContentText("姓名:" + worker.getName());
        name.show();

    }
    @FXML
    public void dataImport(){
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("选择工人名单文件");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("All File", "*.*"),
                new FileChooser.ExtensionFilter("xlx", "*.xlx"),
                new FileChooser.ExtensionFilter("xlxs", "*.xlxs")
        );

        fileChooser.showOpenDialog(new Stage());
    }

    /**
     * desc:led设备管理界面
     */
    @FXML
    public void ledManage(){
        try {
            Parent ledManageRoot = FXMLLoader.load(getClass().getResource("../view/LedManagePanel.fxml"));
            Stage ledManageStage = new Stage();
            ledManageStage.setTitle("LED设备管理");
            ledManageStage.setScene(new Scene(ledManageRoot,600,400));
            //ledManageStage.setMaximized(true);
            //ledManageStage.initStyle(StageStyle.TRANSPARENT);

            AnchorPane ledAnchorPane = (AnchorPane)ledManageRoot.lookup("#ledAnchorPane");
            TabPane deviceTabPane = (TabPane)ledManageRoot.lookup("#deviceTabPane");
            TableView ledTableView = (TableView) ledManageRoot.lookup("#ledTableView");

            deviceTabPane.prefWidthProperty().bind(ledManageStage.widthProperty());
            ledTableView.prefWidthProperty().bind(ledManageStage.widthProperty());

            //设置模态窗口属性
            ledManageStage.initOwner(prentAnchorPanel.getScene().getWindow());
            ledManageStage.initModality(Modality.WINDOW_MODAL);
            ledManageStage.show();
        }catch (Exception ex){
            ex.printStackTrace();
        }
    }

    /**
     * desc:ic卡考期机管理
     */
    @FXML
    public void icAttendanceManage(){


    }

    /**
     * desc:图像识别考勤机管理
     */
    @FXML
    public void imageDiscernAttendanceManage(){

    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        ledChoiceBox.getItems().addAll(ledServers.getAllLed());
        ledChoiceBox.converterProperty().set(new StringConverter<Led>() {
            @Override
            public String toString(Led object) {
                return object.getName();
            }

            @Override
            public Led fromString(String string) {
                return null;
            }
        });
    }

    @FXML
    public void sendNormalInfo(){
            Alert alert = new Alert(Alert.AlertType.INFORMATION,ledChoiceBox.getValue().getId());
            alert.show();
    }
}
上段代码中主要是如下代码:
//先把需要绑定的对象放入ChoiceBox对象的集合中去
ledChoiceBox.getItems().addAll(ledServers.getAllLed());
//再设置ChoiceBox对象的converterProperty属性,使用匿名内部类生成一个StringConverter对象
//重写tostring方法
ledChoiceBox.converterProperty().set(new StringConverter<Led>() {
    @Override
    public String toString(Led object) {
        return object.getName();
    }

    @Override
    public Led fromString(String string) {
        return null;
    }
});
第三步:在要使用ChoiceBox的地方使用getValue()就可以得到一个复合对象,后面就可自己处理了
//通过控件对象的getValue()就会拿到控件中被选择的是那个绑定的对象,然后自行处理
Led value = ledChoiceBox.getValue();
Alert alert = new Alert(Alert.AlertType.INFORMATION,value.getId());
alert.show();                                        
效果如下:
JavaFX中的ChoiceBox中绑定复合对象的操作

这可能是一个很平常的问题,但由于我自己很菜,所以才说了这么多"废话"