Search code examples
javauser-interfacejavafxfxmljava-deployment-toolkit

JavaFX update table


I want to update a table view after that row has been updated in the database.

Product Controller :-

package Controllers;

import CustomObjects.Product;
import Models.ProductModel;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

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

public class ProductController implements Initializable {

    @FXML
    private TableView<Product> table;

    @FXML
    private Button addProductBtn;

    @FXML
    private Button editProductBtn;

    @FXML
    private Button deleteProductBtn;

    @FXML
    private TableColumn<Product, String> col_name;

    @FXML
    private TableColumn<Product, String> col_brand;

    @FXML
    private TableColumn<Product, String> col_type;
    @FXML
    private TableColumn<Product, Integer> col_price;

    public ObservableList<Product> productList = FXCollections.observableArrayList();



    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ProductModel productModel = new ProductModel();
        ArrayList<Product> products = productModel.getProducts();
        int size = products.size();

        for (Product product : products) {
            productList.add(product);
            System.out.println(product.getName());
        }
        col_name.setCellValueFactory(new PropertyValueFactory<>("name"));
        col_brand.setCellValueFactory(new PropertyValueFactory<>("brand"));
        col_price.setCellValueFactory(new PropertyValueFactory<>("price"));
        col_type.setCellValueFactory(new PropertyValueFactory<>("type"));
        table.setItems(productList);
    }

    public void addProduct() throws Exception {
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/addProduct.fxml"));
            Parent root = (Parent) fxmlLoader.load();
            Stage stage = new Stage();
            stage.setScene(new Scene(root));
            stage.setTitle("Add new Product");
            stage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public void editProduct() throws Exception {
        try {
            Product p = table.getSelectionModel().getSelectedItem();
            System.out.println(p.getProduct_id());
            FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/Views/editProduct.fxml"));
            Parent root = (Parent) fxmlLoader.load();
            Stage stage = new Stage();
            Scene scene = new Scene(root);
            stage.setScene(scene);
            EditProductController controller = fxmlLoader.<EditProductController>getController();
            controller.initData(p, scene , table);
            stage.setTitle("Edit product");
            stage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void modifyTableRow(){
        System.out.println("Method called !");
        ProductModel productModel = new ProductModel();
        ArrayList<Product> products = productModel.getProducts();
        int size = products.size();

        for (Product product : products) {
            productList.add(product);
            System.out.println(product.getName());
        }
        col_name.setCellValueFactory(new PropertyValueFactory<>("name"));
        col_brand.setCellValueFactory(new PropertyValueFactory<>("brand"));
        col_price.setCellValueFactory(new PropertyValueFactory<>("price"));
        col_type.setCellValueFactory(new PropertyValueFactory<>("type"));
        table.setItems(productList);

    }

    public void deleteProduct() throws Exception {
        Product p = table.getSelectionModel().getSelectedItem();
        if (p == null) {
            Alert q = new Alert(Alert.AlertType.WARNING);
            q.setTitle("Delete a product");
            q.setContentText("Select a product ");
            q.show();
        } else {

            Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
            alert.setTitle("Delete a product");
            alert.setContentText("Do you want to delete this product ?");

            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK) {
                table.getItems().remove(p);
                ProductModel model = new ProductModel();
                model.deleteProduct(p.getProduct_id());
            }
        }


    }
}

This controller pulls data from database and displays them in a table. After this editProductBtn clicked another a scene related to that pops in . It contains all the data related to the selected row in the table before the user click the edit product button.

EditProductController:-

package Controllers;

import CustomObjects.Product;
import Models.ProductModel;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

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

public class EditProductController implements Initializable {

    private int productId;
    private Scene currentScene;
    private TableView<Product> table;
    private Product product;

    @FXML
    private Button addProductBtn;

    @FXML
    private Button testBtn;

    @FXML
    private TextField nameTextBox;

    @FXML
    private TextField priceTextBox;

    @FXML
    private TextField typeTextBox;

    @FXML
    private TextField brandTextBox;

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

    }


    void initData(Product product, Scene scene, TableView<Product> table) {
        if (product == null) {
            Alert q = new Alert(Alert.AlertType.WARNING);
            q.setTitle("Delete a product");
            q.setContentText("Select a product ");
            q.show();
        } else {

            product = product;
            productId = product.getProduct_id();
            nameTextBox.setText(product.getName());
            priceTextBox.setText(String.valueOf(product.getPrice()));
            typeTextBox.setText(product.getType());
            brandTextBox.setText(product.getBrand());
            currentScene = scene;
        }
    }

    public void updateProduct() {

        String name = nameTextBox.getText();
        Integer price = Integer.valueOf(priceTextBox.getText());
        String brand = brandTextBox.getText();
        String type = typeTextBox.getText();
        ProductModel productModel = new ProductModel();
        productModel.updateProduct(productId, name, brand, type, price);

    }

    public void callMainMethod(){
        ProductController pc  = new ProductController();
        pc.modifyTableRow();
        table.refresh();
    }

}

This can change the data for the database but not in the table. I tried few tricks here and there but it gave me some error related to threads. I am a complete beginner of javaFx . I would be much thankfull to you if you please post some detailed answer Thank You !


Solution

  • You can use the Platform.runLater() method to avoid the thread problems

    and to update the table i can see two ways:

    you can modify the row in the table inside your updateProduct() method, since you are receiving the Table in your EditProductController class

    or you can load all the data from the database again