在 JavaFX 中添加或更新记录后 TableView 未更新

问题描述 投票:0回答:1

我正在开发一个带有 TableView 的 JavaFX 应用程序,用于管理员工记录。我有一个 EmployeeRepository 类用于处理 CRUD 操作,它与“CsvHandler”类通信以将数据保存在 csv 中,还有一个 EmployeeManagementController 用于与 TableView 交互。

我面临的问题是,当我通过 EmployeeDetailsController 启动的对话框添加或更新员工记录时,EmployeeManagementController 中的 TableView 不会更新以反映这些更改。

以下是相关代码的简要概述:

  1. EmployeeRepository:管理 CRUD 操作并维护 TableView 应绑定到的 ObservableList

  2. EmployeeManagementController:用employeeObservableList初始化TableView,当添加或更新记录时,它应该被更新。

  3. EmployeeDetailsController:处理添加或更新记录的对话框,并调用 EmployeeRepository 中的方法来保存数据。

尽管在操作后更新了 EmployeeRepository 中的 ObservableList,但 EmployeeManagementController 中的 TableView 并未反映这些更改。

这是 EmployeeRepository 类:

public class EmployeeRepository {

    private final CsvHandler csvHandler;
    private final String EMPLOYEE_DATA_FILE = "Data/employeeData.csv";
    private final List<String[]> employeeData;
    private final ObservableList<Employee> employeeList;
    private final String[] HEADERS;

    public EmployeeRepository() {
        csvHandler = new CsvHandler(EMPLOYEE_DATA_FILE);
        employeeData = csvHandler.retrieveCsvData(true);
        employeeList = FXCollections.observableArrayList(getAllEmployees());
        HEADERS = csvHandler.retrieveFieldNames();
    }

    public Employee convertArrayToEmployee(String[] employeeData) {
        return new Employee(
                Integer.parseInt(employeeData[0]),
                employeeData[1],
                employeeData[2],
                employeeData[3],
                employeeData[4],
                employeeData[5],
                employeeData[6],
                employeeData[7],
                employeeData[8],
                employeeData[9],
                employeeData[10],
                employeeData[11],
                employeeData[12],
                employeeData[13],
                employeeData[14],
                Double.parseDouble(employeeData[15]),
                Double.parseDouble(employeeData[16]),
                Double.parseDouble(employeeData[17]),
                Double.parseDouble(employeeData[18]),
                Double.parseDouble(employeeData[19]),
                Double.parseDouble(employeeData[20])
        );
    }

    public List<Employee> getAllEmployees() {
        List<Employee> employees = new ArrayList<>();

        for (String[] row : employeeData) {
            employees.add(convertArrayToEmployee(row));
        }
        return employees;
    }

    public ObservableList<Employee> getEmployeeList() {
        return employeeList;
    }

    public boolean recordExists(String[] record, int currentEmpId) {
        for (String[] row : employeeData) {
            if (Integer.parseInt(row[0]) != currentEmpId && // EmployeeID
                    (record[4].equals(row[4]) || // address
                            record[5].equals(row[5]) || // phone number
                            record[7].equals(row[7]) || // SSS
                            record[8].equals(row[8]) || // PhilHealth
                            record[9].equals(row[9]) || // TIN
                            record[10].equals(row[10]))) { // Pag-IBIG
                return true;
            }
        }
        return false;
    }

    public void addEmployeeRecord(String[] record) {

        if (recordExists(record, -1)) {
            AlertUtil.showDuplicateRecordExists();
            return;
        }

        employeeData.add(record);
        employeeList.add(convertArrayToEmployee(record));

        csvHandler.writeDataToCsv(employeeData, HEADERS);

        employeeList.clear();
        employeeList.addAll(getAllEmployees());

        AlertUtil.showRecordSavedAlert();
        System.out.println("Record saved");
    }

    public int getNewEmployeeID() {
        return Integer.parseInt(employeeData.getLast()[0]) + 1;
    }

    public void updateEmployeeRecord(String[] record) {

        if (recordExists(record, Integer.parseInt(record[0]))) {
            AlertUtil.showDuplicateRecordExists();
            return;
        }

        for (int i = 0; i < employeeData.size(); i++) {
            String[] row = employeeData.get(i);
            if (row[0].equals(record[0])) {
                employeeData.set(i, record);
                employeeList.set(i, convertArrayToEmployee(record));
                break;
            }
        }
        csvHandler.writeDataToCsv(employeeData, HEADERS);

        employeeList.clear();
        employeeList.addAll(getAllEmployees());

        AlertUtil.showRecordUpdatedAlert();
        System.out.println("Record Updated");
    }

    public void deleteEmployeeRecord(int employeeId) {

        employeeData.removeIf(row -> row[0].equals(String.valueOf(employeeId)));

        csvHandler.writeDataToCsv(employeeData, HEADERS);

        employeeList.clear();
        employeeList.addAll(getAllEmployees());

        AlertUtil.showRecordDeletedAlert();
        System.out.println("Record deleted");
    }
}

这是 EmployeeManagementController:


public class EmployeeManagementController {

    private final EmployeeRepository empDataService;

    private final ObservableList<Employee> employeeObservableList;

    @FXML
    private TableView<Employee> employeeTable;

    @FXML
    private TableColumn<Employee, Integer> employeeIdColumn;

    @FXML
    private TableColumn<Employee, String> firstNameColumn, lastNameColumn, tinNoColumn, sssNoColumn, philhealthNoColumn, pagibigNoColumn;

    public EmployeeManagementController() {
        empDataService = new EmployeeRepository();
        employeeObservableList = empDataService.getEmployeeList();
    }

    @FXML
    public void initialize() {
        initializeTableColumns();
        loadEmployeeData();
        handleViewEmployeeDetails();
    }

    @FXML
    private void handleAddNewRecord() {
        new EmployeeDetailsController().displayEmployeeDialog(false, null, false);
    }

    @FXML
    private void handleUpdateRecord() {    Employee selectedEmployee = selectedEmployee();
        if (selectedEmployee != null) {
             new EmployeeDetailsController().displayEmployeeDialog(true, selectedEmployee, false);
        } else {
            AlertUtil.showNoSelectionAlert("Please select an employee record to update");
        }
    }

    @FXML
    public void handleDeleteRecord() {
        Employee selectedEmployee = selectedEmployee();
        if (selectedEmployee == null) {
            AlertUtil.showNoSelectionAlert("Please select an employee record to delete");
            return;
        }

        boolean confirmed = AlertUtil.showConfirmationAlert("Confirm Deletion", "Are you sure you want to delete this employee record? This action cannot be undone.");
        if (confirmed) {

            empDataService.deleteEmployeeRecord(selectedEmployee.getEmployeeID());
        }
    }

    private void handleViewEmployeeDetails() {
        employeeTable.setOnMouseClicked((MouseEvent event) -> {
            if (event.getClickCount() == 2) {
                new EmployeeDetailsController().displayEmployeeDialog(false, selectedEmployee(), true);
            }
        });
    }


    private void initializeTableColumns() {

        employeeIdColumn.setCellValueFactory(new PropertyValueFactory<>("employeeID"));
        firstNameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName"));
        lastNameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));
        tinNoColumn.setCellValueFactory(new PropertyValueFactory<>("tinNumber"));
        sssNoColumn.setCellValueFactory(new PropertyValueFactory<>("sssNumber"));
        philhealthNoColumn.setCellValueFactory(new PropertyValueFactory<>("philhealthNumber"));
        pagibigNoColumn.setCellValueFactory(new PropertyValueFactory<>("pagibigNumber"));

        bindTableColumnsToTableViewWidth();
    }


    private void loadEmployeeData() {
        employeeTable.setItems(employeeObservableList);
    }

    private Employee selectedEmployee() {
        return employeeTable.getSelectionModel().getSelectedItem();
    }

}

这是 EmployeeDetailsController:

public class EmployeeDetailsController {

    private final EmployeeRepository empRepository = new EmployeeRepository();
    private Employee employee;
    private boolean updateMode = false;


    public void setEmployee(Employee employee) {
        this.employee = employee;
        updateMode = true;
        populateFields();
    }


    @FXML
    public void handleSaveRecord() {
        if (!validateFields()) {
            AlertUtil.showIncompleteDataAlert();
            return;
        }

        try {
            if (AlertUtil.confirmDetails()) {
                String[] record = retrieveInputAsStringArray();

                if (updateMode) {
                    handleUpdateMode(record);
                } else {
                    handleAddMode(record);
                }
            }
        } catch (NumberFormatException e) {
            AlertUtil.showAlert(Alert.AlertType.ERROR, "Invalid Number Format", "Please enter a valid number.");
        }
    }

    private void handleAddMode(String[] record) {
        empRepository.addEmployeeRecord(record);
    }

    private void handleUpdateMode(String[] record) {
        empRepository.updateEmployeeRecord(record);
    }

    public void displayEmployeeDialog(boolean updateMode, Employee employee, boolean showOnly) {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/View/EmployeeDetails.fxml"));
            DialogPane empDetailsDialogPane = loader.load();

            EmployeeDetailsController controller = loader.getController();

            if (updateMode) {
                controller.setEmployee(employee);
            } else if (employee != null) {
                controller.setEmployee(employee);
                controller.disableTextFields();
            }

            Dialog<ButtonType> dialog = new Dialog<>();
            dialog.setDialogPane(empDetailsDialogPane);

            if (showOnly) {
                empDetailsDialogPane.lookupButton(ButtonType.OK).setVisible(false);
                empDetailsDialogPane.lookupButton(ButtonType.CANCEL).setVisible(false);
            }

            Optional<ButtonType> clickedButton = dialog.showAndWait();
            if (clickedButton.isPresent() && clickedButton.get() == ButtonType.OK && !showOnly) {
                controller.handleSaveRecord();
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void disableTextFields() {
        for (TextField textField : textFields) {
            textField.setEditable(false);
        }
    }
}
java javafx tableview
1个回答
0
投票

您可以显式地尝试刷新表视图以反映可观察列表的底层更改。

/**
 * Refresh the table contents when the underlying observable list tracked by
 * table gets updated
 */

public void refresh() {
    employeeTable.getColumns().get(0).setVisible(false);
    employeeTable.getColumns().get(0).setVisible(true);
}
© www.soinside.com 2019 - 2024. All rights reserved.