无法为TableView工作制作“全选”CheckBox(JavaFX)

时间:2015-10-08 12:48:43

标签: java user-interface checkbox javafx tableview

这是我目前的代码(从我的项目复制到它自己的“程序”)

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.stage.Stage;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;

public class Table extends Application {

    private static ObservableList<Item> items = FXCollections.observableArrayList();

        public static void updateItems() {

        }
        public static void initTable(Stage stage) {
            //Create table and columns
            TableView<Item> table_items = new TableView<>();
            TableColumn<Item, Boolean> column_selected = new TableColumn<>();
            TableColumn<Item, String> column_name = new TableColumn<>("Name");
            TableColumn<Item, Integer> column_quantity = new TableColumn<>("Quantity");
            TableColumn<Item, Double> column_price = new TableColumn<>("Price");
            //Create checkbox
            CheckBox select_all = new CheckBox();
            //Create scene
            Scene scene = new Scene(table_items);

            //Add items to ObservableList
            items.addAll(new Item("Knife", 10, 20),
                    new Item("Fork", 10, 25),
                    new Item("Pork", 3, 100));

            //Make table editable
            table_items.setEditable(true);

            //Make one column use checkboxes instead of text
            column_selected.setCellFactory(CheckBoxTableCell.forTableColumn(column_selected));

            //Change ValueFactory for each column
            column_selected.setCellValueFactory(new PropertyValueFactory<>("selected"));
            column_price.setCellValueFactory(new PropertyValueFactory<>("averagePrice"));
            column_quantity.setCellValueFactory(new PropertyValueFactory<>("volume"));
            column_name.setCellValueFactory(new PropertyValueFactory<>("name"));

            //Use box as column header
            column_selected.setGraphic(select_all);

            //Select all checkboxes when checkbox in header is pressed
            select_all.setOnAction(e -> selectAllBoxes(e));

            //Add columns to the table
            table_items.getColumns().addAll(column_selected, column_name, column_quantity, column_price);

            table_items.setItems(items);
            stage.setScene(scene);


        }

        public static void selectAllBoxes(ActionEvent e) {

            //Iterate through all items in ObservableList
            for (Item item : items) {
                //And change "selected" boolean
                item.setSelected(((CheckBox) e.getSource()).isSelected());
            }

        }

    @Override
    public void start(Stage primaryStage) throws Exception {
        initTable(primaryStage);
        primaryStage.show();
    }

    public static class Item {
            public BooleanProperty selected = new SimpleBooleanProperty(false);
            final private String name;
            final private double averagePrice;
            final private int volume;

            Item(String name, double averagePrice, int volume) {

                this.name = name;
                this.averagePrice = averagePrice;
                this.volume = volume;
            }

            public BooleanProperty isChecked() {
                return selected;
            }

            public void setSelected(boolean selected) {
                this.selected.set(selected);
            }

            public String getName() {
                return name;
            }

            public double getAveragePrice() {
                return averagePrice;
            }

            public int getVolume() {
                return volume;
            }

        }
}

它确实更改了列表中的selected BooleanProperty,但表中的复选框不会更新。起初我使用了原始布尔值,它没有用。然后我尝试了BooleanProperty,它仍然无法工作(我希望是什么?)。我认为只使用TableView#setItems就可以了,但肯定没有。

1 个答案:

答案 0 :(得分:4)

您的模型类Item的定义方式不能与PropertyValueFactory一起使用(文档解释了它所需的结构)。

所以你需要

public static class Item {
        private BooleanProperty selected = new SimpleBooleanProperty(false);
        final private String name;
        final private double averagePrice;
        final private int volume;

        Item(String name, double averagePrice, int volume) {

            this.name = name;
            this.averagePrice = averagePrice;
            this.volume = volume;
        }

        public BooleanProperty selectedProperty() {
            return selected;
        }

        public void setSelected(boolean selected) {
            this.selected.set(selected);
        }

        public boolean isSelected() {
            return selected.get();
        }

        public String getName() {
            return name;
        }

        public double getAveragePrice() {
            return averagePrice;
        }

        public int getVolume() {
            return volume;
        }

}

这将允许CheckBoxTableCell正确观察其项目的selectedProperty(),因此它会在属性更改时更新。