Javafx tableview在循环中添加布尔值

时间:2021-06-06 17:01:37

I'm trying to populate a tableview with a boolean value as false in a for loop for checkbox in the table. My goal is to load a csv file in to tableview with first column as "checkbox", so user can select rows for further task.

我正在尝试在表的复选框的for循环中填充一个boolean值为false的tableview。我的目标是将csv文件加载到tableview,第一列为“checkbox”,因此用户可以选择行以进行进一步的任务。

When i define the same data inside observableArrayList, it works.

当我在observableArrayList中定义相同的数据时,它可以工作。

public void addPredfined_Data_to_Tableview() {

    studentData_Predefined = FXCollections.observableArrayList(
            new StudentTableModel(false, "James", "Atlanta"),
            new StudentTableModel(false, "Karen", "New York"),
            new StudentTableModel(false, "Robert", "Texas")
            );
    tableView.setItems(studentData_Predefined);
}

The problem is when i try to update the tableview inside a for loop, it doesn't work. The error i get is IndexOutOfBoundsException: Index: 0, Size: 0

问题是当我尝试在for循环中更新tableview时,它不起作用。我得到的错误是IndexOutOfBoundsException:索引:0,大小:0

public void load_CSV_file_to_Tableview() {

    for (int i = 0; i < 3; i++) {
        studentData_fromCSV = FXCollections.observableArrayList(
                new StudentTableModel(Boolean.FALSE, "James", "Atlanta")
                );
    }
    tableView.setItems(studentData_fromCSV);
}

Here is my table model class.

这是我的表模型类。

package application;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;

public class StudentTableModel {

    private final BooleanProperty chekboxStudentRow;
    private final SimpleStringProperty studentName;
    private final SimpleStringProperty studentLocation;
    public StudentTableModel(Boolean chekboxStudentRow, String studentName, String studentLocation) {
        super();
        this.chekboxStudentRow = new SimpleBooleanProperty(chekboxStudentRow);
        this.studentName = new SimpleStringProperty(studentName);
        this.studentLocation = new SimpleStringProperty(studentLocation);
    }

    public String getStudentName() {
        return studentName.get();
    }

    public String getStudentLocation() {
        return studentLocation.get();
    }

    public final BooleanProperty chekboxStudentRowProperty() {
        return this.chekboxStudentRow;
    }

    public final boolean isChekboxStudentRow() {
        return this.chekboxStudentRowProperty().get();
    }

    public final void setChekboxStudentRow(final boolean chekboxStudentRow) {
        this.chekboxStudentRowProperty().set(chekboxStudentRow);
    }

}

And he is my controller class.

他是我的控制班。

package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.util.Callback;

public class MainWindowController implements Initializable{

    @FXML public Button btn_addPredefined_data;
    @FXML public Button btn_load_csv_file;

    @FXML public TableView<StudentTableModel> tableView;
    @FXML public TableColumn<StudentTableModel, Boolean> col_CheckBox;
    @FXML public TableColumn<StudentTableModel, String> col_StudentName;
    @FXML public TableColumn<StudentTableModel, String> col_StudentLocation;

    public ObservableList<StudentTableModel> studentData_Predefined = FXCollections.observableArrayList();
    public ObservableList<StudentTableModel> studentData_fromCSV = FXCollections.observableArrayList();

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // TODO Auto-generated method stub

        col_CheckBox.setCellFactory(CheckBoxTableCell.forTableColumn(new Callback<Integer, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(Integer param) {
                // TODO Auto-generated method stub
                return studentData_Predefined.get(param).chekboxStudentRowProperty();
            }
        }));

        col_StudentName.setCellValueFactory(new PropertyValueFactory<StudentTableModel, String>("studentName"));
        col_StudentLocation.setCellValueFactory(new PropertyValueFactory<StudentTableModel, String>("studentLocation"));

        tableView.setEditable(true);

        btn_addPredefined_data.setOnAction(e -> addPredfined_Data_to_Tableview());
        btn_load_csv_file.setOnAction(e -> load_CSV_file_to_Tableview());

    }

    public void addPredfined_Data_to_Tableview() {

        studentData_Predefined = FXCollections.observableArrayList(
                new StudentTableModel(false, "James", "Atlanta"),
                new StudentTableModel(false, "Karen", "New York"),
                new StudentTableModel(false, "Robert", "Texas")
                );
        tableView.setItems(studentData_Predefined);
    }

    public void load_CSV_file_to_Tableview() {

        for (int i = 0; i < 3; i++) {
            studentData_fromCSV = FXCollections.observableArrayList(
                    new StudentTableModel(Boolean.FALSE, "James", "Atlanta")
                    );
        }
        tableView.setItems(studentData_fromCSV);
    }


}

Here is the complete stack trace..

这是完整的堆栈跟踪..

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
    at application.MainWindowController$1.call(MainWindowController.java:43)
    at application.MainWindowController$1.call(MainWindowController.java:1)
    at javafx.scene.control.cell.CheckBoxTableCell.getSelectedProperty(CheckBoxTableCell.java:391)
    at javafx.scene.control.cell.CheckBoxTableCell.updateItem(CheckBoxTableCell.java:362)
    at javafx.scene.control.TableCell.updateItem(TableCell.java:663)
    at javafx.scene.control.TableCell.indexChanged(TableCell.java:468)
    at javafx.scene.control.IndexedCell.updateIndex(IndexedCell.java:116)
    at com.sun.javafx.scene.control.skin.TableRowSkinBase.updateCells(TableRowSkinBase.java:533)
    at com.sun.javafx.scene.control.skin.TableRowSkinBase.init(TableRowSkinBase.java:147)
    at com.sun.javafx.scene.control.skin.TableRowSkin.<init>(TableRowSkin.java:64)
    at javafx.scene.control.TableRow.createDefaultSkin(TableRow.java:212)
    at javafx.scene.control.Control.impl_processCSS(Control.java:872)
    at javafx.scene.Node.processCSS(Node.java:9056)
    at javafx.scene.Node.applyCss(Node.java:9153)
    at com.sun.javafx.scene.control.skin.VirtualFlow.setCellIndex(VirtualFlow.java:1964)
    at com.sun.javafx.scene.control.skin.VirtualFlow.getCell(VirtualFlow.java:1797)
    at com.sun.javafx.scene.control.skin.VirtualFlow.getCellLength(VirtualFlow.java:1879)
    at com.sun.javafx.scene.control.skin.VirtualFlow.computeViewportOffset(VirtualFlow.java:2528)
    at com.sun.javafx.scene.control.skin.VirtualFlow.layoutChildren(VirtualFlow.java:1189)
    at javafx.scene.Parent.layout(Parent.java:1087)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Parent.layout(Parent.java:1093)
    at javafx.scene.Scene.doLayoutPass(Scene.java:552)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397)
    at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
    at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)

1 个解决方案

#1


1  

If the load_CSV_file_to_Tableview() is invoked, the table's data is set to studentData_fromCSV (and presumably studentData_Predefined is never populated).

如果调用了load_CSV_file_to_Tableview(),则表的数据将设置为studentData_fromCSV(并且可能永远不会填充studentData_Predefined)。

However, your CheckBoxTableCell uses studentData_Predefined in all cases, so it will try to reference elements in an empty list if studentData_Predefined is empty and there is data in the table.

但是,CheckBoxTableCell在所有情况下都使用studentData_Predefined,因此如果studentData_Predefined为空并且表中有数据,它将尝试引用空列表中的元素。

Just reference the table data directly:

只需直接引用表数据:

    col_CheckBox.setCellFactory(CheckBoxTableCell.forTableColumn(new Callback<Integer, ObservableValue<Boolean>>() {
        @Override
        public ObservableValue<Boolean> call(Integer param) {
            // TODO Auto-generated method stub
            return tableView.getItems().get(param).chekboxStudentRowProperty();
        }
    }));

#1


1  

If the load_CSV_file_to_Tableview() is invoked, the table's data is set to studentData_fromCSV (and presumably studentData_Predefined is never populated).

如果调用了load_CSV_file_to_Tableview(),则表的数据将设置为studentData_fromCSV(并且可能永远不会填充studentData_Predefined)。

However, your CheckBoxTableCell uses studentData_Predefined in all cases, so it will try to reference elements in an empty list if studentData_Predefined is empty and there is data in the table.

但是,CheckBoxTableCell在所有情况下都使用studentData_Predefined,因此如果studentData_Predefined为空并且表中有数据,它将尝试引用空列表中的元素。

Just reference the table data directly:

只需直接引用表数据:

    col_CheckBox.setCellFactory(CheckBoxTableCell.forTableColumn(new Callback<Integer, ObservableValue<Boolean>>() {
        @Override
        public ObservableValue<Boolean> call(Integer param) {
            // TODO Auto-generated method stub
            return tableView.getItems().get(param).chekboxStudentRowProperty();
        }
    }));