Search code examples
javajavafxtableviewfxml

how to add data to table view when click on button on another page?


I'm doing this program in JavaFX that will take data from a database created on Microsoft access and place it on a table view. Also, I created button inside the table view (Add,Delete) when clicking on add button it will open a new FXML page. In this page there are 5 TextFiled and two button (Add and Cancel) when clicking on add button it suppose to take all the data in the TextFiled and add it to my table view. But i actually could not do that. I hope that someone here have an idea of how i can accomplish this.

FXMLDocumentController.java

enter image description here

package db;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import java.sql.Connection;
import java.sql.ResultSet;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 *
 * @author pc
 */
public class FXMLDocumentController implements Initializable {

    @FXML
    public Statement st;
    public  TableView<ObservableList> table;
    public   ObservableList<ObservableList> data; 
    private Button btnNew = new Button("New Record");

   public void buildData(){


          data = FXCollections.observableArrayList();

          try{

            Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
            Connection con = DriverManager.getConnection("jdbc:ucanaccess://D:\\GUI\\Library.accdb","","");
            System.out.println("connected...");
            st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

            //SQL FOR SELECTING ALL OF BOOK

            String SQL = "SELECT * from BookDB";

            //ResultSet

            ResultSet rs = con.createStatement().executeQuery(SQL);

            /**********************************
             * TABLE COLUMN ADDED DYNAMICALLY *
             **********************************/

            for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){

                //We are using non property style for making dynamic table

                final int j = i;               

                TableColumn col = new TableColumn(rs.getMetaData().getColumnName(i+1));

                col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){                   

                    public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {                                                                                             

                        return new SimpleStringProperty(param.getValue().get(j).toString());                       

                    }                   

                });

                table.getColumns().addAll(col);

                System.out.println("Column ["+i+"] ");

            }

            TableColumn col_action = new TableColumn<>("Action");
        col_action.setSortable(false);

        col_action.setCellValueFactory(
                new Callback<TableColumn.CellDataFeatures<ObservableList, Boolean>, 
                ObservableValue<Boolean>>() {

            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ObservableList, Boolean> p) {
                return new SimpleBooleanProperty(p.getValue() != null);
            }
        });

        col_action.setCellFactory(
                new Callback<TableColumn<ObservableList, Boolean>, TableCell<ObservableList, Boolean>>() {

            @Override
            public TableCell<ObservableList, Boolean> call(TableColumn<ObservableList, Boolean> p) {
                return new ButtonCell(table);
            }

        });

        table.getColumns().add(col_action);
        TableColumn col_Delete = new TableColumn<>("Delete");
        col_Delete.setSortable(false);

        col_Delete.setCellValueFactory(
                new Callback<TableColumn.CellDataFeatures<ObservableList, Boolean>, 
                ObservableValue<Boolean>>() {

            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<ObservableList, Boolean> p) {
                return new SimpleBooleanProperty(p.getValue() != null);
            }
        });

        col_Delete.setCellFactory(
                new Callback<TableColumn<ObservableList, Boolean>, TableCell<ObservableList, Boolean>>() {

            @Override
            public TableCell<ObservableList, Boolean> call(TableColumn<ObservableList, Boolean> p) {
                return new ButtonDelete(table);
            }

        });

        table.getColumns().add(col_Delete);
            /********************************
             * Data added to ObservableList *
             ********************************/

            while(rs.next()){

                //Iterate Row

                ObservableList<String> row = FXCollections.observableArrayList();

                for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++){

                    //Iterate Column

                    row.add(rs.getString(i));

                }

                System.out.println("Row [1] added "+row );

                data.add(row);

            }

            //FINALLY ADDED TO TableView

            table.setItems(data);

          }
          catch(Exception e){

              e.printStackTrace();

              System.out.println("Error on Building Data");            

          }

      }



    @Override
    public void initialize(URL url, ResourceBundle rb) {

        buildData();
        table.refresh();

    } 



    //Define the button cell
    private class ButtonCell extends TableCell<ObservableList, Boolean> {
        final Button cellButton = new Button("Add");

        ButtonCell(final TableView tblView){

            cellButton.setOnAction(new EventHandler<ActionEvent>(){

                @Override
                public void handle(ActionEvent t) {


                   try {
                        Second s=new Second();
                        s.start(new Stage());


                    } catch (Exception ex) {
                        Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            super.updateItem(t, empty);
            if(!empty){
                setGraphic(cellButton);
            }
        }
    }

    //Define the button cell
    private class ButtonDelete extends TableCell<ObservableList, Boolean> {
        final Button delButton = new Button("Delete");

        ButtonDelete(final TableView tblView){

            delButton.setOnAction(new EventHandler<ActionEvent>(){

                @Override
                public void handle(ActionEvent t) {
                  Stage myDialog = new Stage();
                    myDialog.initModality(Modality.WINDOW_MODAL);
                    myDialog.show();
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty) {
            super.updateItem(t, empty);
            if(!empty){
                setGraphic(delButton);
            }
        }
    } 


}

FXMLController.java

enter image description here

package db;


import java.net.URL;
import java.sql.Statement;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TextField;

/**
 * FXML Controller class
 *
 * @author pc
 */
public class FXMLController implements Initializable {

    @FXML
    public TextField t1,t2,t3,t4,t5;
    public Statement st;

    @FXML
    public void btnADD(ActionEvent e)
    { 
    }
    @FXML
    public void btnCANCEL(ActionEvent e)
    {
        System.exit(0);
    }
    @Override
    public void initialize(URL url, ResourceBundle rb) 
    {

}
}

Database Structure

enter image description here


Solution

  • my friend, base on your code, i have made some reconstruction of your code to make it working, but the code's structure is not good, if it is mine project, i won't use this structure, LOL, just for reference. As below.

    first, we need to create a TableView's generic type class, here we create Book.java for it.

    package db;
    public class Book{
      private String id;
      private String name;
      private String author;
      private String publisher;
      private String price;
    
      public String getId(){
        return this.id;
      }
      public void setId(String id){
        this.id = id;
      }
    
      public String getName(){
        return this.name;
      }
      public void setName(String name){
        this.name = name;
      }
    
      public String getAuthor(){
        return this.author;
      }
      public void setAuthor(String author){
        this.author = author;
      }
    
      public String getPublisher(){
        return this.publisher;
      }
      public void setPublisher(String publisher){
        this.publisher = publisher;
      }
    
      public String getPrice(){
        return this.price;
      }
      public void setPrice(String price){
        this.price = price;
      }
    
      @Override
      public int hashCode(){
        final int prime = 31;
        int result = 1;
        result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
        return result;
      }
    
      @Override
      public boolean equals(Object obj){
        if(this == obj)
          return true;
        if(obj == null)
          return false;
        if(getClass() != obj.getClass())
          return false;
        Book other = (Book) obj;
        if(this.id == null){
          if(other.id != null)
            return false;
        }else if(!this.id.equals(other.id))
          return false;
        return true;
      }
    
      public void setValue(String columnName, String colData){
        if(columnName.contentEquals("BookName")){
          setName(colData);
        }else if(columnName.contentEquals("Author")){
          setAuthor(colData);
        }else if(columnName.contentEquals("Publisher")){
          setPublisher(colData);
        }else if(columnName.contentEquals("Price")){
          setPrice(colData);
        }else{
          //BookId
          setId(colData);
        }
      }
    
      public String getValue(String columnName){
        String value = "";
        if(columnName.contentEquals("BookName")){
          value = getName();
        }else if(columnName.contentEquals("Author")){
          value = getAuthor();
        }else if(columnName.contentEquals("Publisher")){
          value = getPublisher();
        }else if(columnName.contentEquals("Price")){
          value = getPrice();
        }else{
          //BookId
          value = getId();
        }
        return value;
      }
    }
    

    then modified your FXMLDocumentController.java as below:

    package db;
    
    import java.io.IOException;
    import java.net.URL;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.ResourceBundle;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import javafx.beans.property.SimpleBooleanProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.value.ObservableValue;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.event.ActionEvent;
    import javafx.event.EventHandler;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableColumn.CellDataFeatures;
    import javafx.scene.control.TableView;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    /**
     *
     * @author pc
     */
    public class FXMLDocumentController implements Initializable{
    
      public Statement st;
      @FXML
      public TableView<Book> table;
      //public ObservableList<ObservableList> data;
      private ObservableList<Book> bookData;
      //private Button btnNew = new Button("New Record");
    
      public void buildData(){
        //data = FXCollections.observableArrayList();
        bookData = FXCollections.observableArrayList();
    
        try{
          Class.forName("net.ucanaccess.jdbc.UcanaccessDriver");
          Connection con = DriverManager.getConnection("jdbc:ucanaccess://D:\\GUI\\Library.accdb", "", "");
          System.out.println("connected...");
          st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
          // SQL FOR SELECTING ALL OF BOOK
          String SQL = "SELECT * from BookDB";
          // ResultSet
          ResultSet rs = con.createStatement().executeQuery(SQL);
          /**********************************
           * TABLE COLUMN ADDED DYNAMICALLY *
           **********************************/
          for(int i = 0; i < rs.getMetaData().getColumnCount(); i++){
            // We are using non property style for making dynamic table
            String columnName = rs.getMetaData().getColumnName(i + 1);
            TableColumn<Book, String> col = new TableColumn<>(columnName);
            col.setCellValueFactory(new Callback<CellDataFeatures<Book, String>, ObservableValue<String>>(){
              public ObservableValue<String> call(CellDataFeatures<Book, String> param){
                Book book = param.getValue();
                String cellData = book.getValue(columnName);
                return new SimpleStringProperty(cellData);
              }
            });
            table.getColumns().add(col);
            System.out.println("Column [" + i + "] ");
          }
    
          TableColumn<Book, Boolean> col_action = new TableColumn<>("Action");
          col_action.setSortable(false);
          col_action.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Book, Boolean>, ObservableValue<Boolean>>(){
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Book, Boolean> p){
              return new SimpleBooleanProperty(p.getValue() != null);
            }
          });
          col_action.setCellFactory(new Callback<TableColumn<Book, Boolean>, TableCell<Book, Boolean>>(){
            @Override
            public TableCell<Book, Boolean> call(TableColumn<Book, Boolean> p){
              return new ButtonCell(table);
            }
          });
          table.getColumns().add(col_action);
    
          TableColumn<Book, Boolean> col_Delete = new TableColumn<>("Delete");
          col_Delete.setSortable(false);
          col_Delete.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Book, Boolean>, ObservableValue<Boolean>>(){
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Book, Boolean> p){
              return new SimpleBooleanProperty(p.getValue() != null);
            }
          });
          col_Delete.setCellFactory(new Callback<TableColumn<Book, Boolean>, TableCell<Book, Boolean>>(){
            @Override
            public TableCell<Book, Boolean> call(TableColumn<Book, Boolean> p){
              return new ButtonDelete(table);
            }
          });
          table.getColumns().add(col_Delete);
    
          /********************************
           * Data added to ObservableList *
           ********************************/
          while(rs.next()){
            Book book = new Book();
            // Iterate Row
            for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++){
              // Iterate Column
              String columnName = rs.getMetaData().getColumnName(i);
              String columnData = rs.getString(i);
              book.setValue(columnName, columnData);
            }
            System.out.println("Row [1] added " + book.getName());
            bookData.add(book);
          }
          // FINALLY ADDED TO TableView
          table.setItems(bookData);
    
        }catch(Exception e){
          e.printStackTrace();
          System.out.println("Error on Building Data");
        }
      }
    
      @Override
      public void initialize(URL url, ResourceBundle rb){
        buildData();
        table.refresh();
      }
    
      // Define the button cell
      private class ButtonCell extends TableCell<Book, Boolean>{
        final Button cellButton = new Button("Add");
        ButtonCell(final TableView<Book> tblView) {
          cellButton.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent t){
              try{
                //Second s = new Second();
                //s.start(new Stage());
                openFXMLController();
              }catch(Exception ex){
                Logger.getLogger(FXMLDocumentController.class.getName()).log(Level.SEVERE, null, ex);
              }
            }
          });
        }
        // Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty){
          super.updateItem(t, empty);
          if(!empty){
            setGraphic(cellButton);
          }else{
            setGraphic(null);
            setText("");
          }
        }
      }
    
      private Stage fxmlControllerStage;
      private void openFXMLController(){
        if(fxmlControllerStage == null){
          FXMLLoader loader = new FXMLLoader(getClass().getResource("FXML.fxml"));
          try{
            Parent root = loader.load();
            fxmlControllerStage = new Stage();
            fxmlControllerStage.setScene(new Scene(root));
            if(loader.getController() instanceof FXMLController){
              FXMLController fxmlController = loader.getController();
              fxmlController.setStage(fxmlControllerStage);
              fxmlController.setTable(table);
            }
          }catch(IOException e){
            e.printStackTrace();
          }
        }
        fxmlControllerStage.show();
      }
    
      // Define the button cell
      private class ButtonDelete extends TableCell<Book, Boolean>{
        final Button delButton = new Button("Delete");
        ButtonDelete(final TableView<Book> tblView) {
          delButton.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent t){
              bookData.remove(getIndex());
            }
          });
        }
        // Display button if the row is not empty
        @Override
        protected void updateItem(Boolean t, boolean empty){
          super.updateItem(t, empty);
          if(!empty){
            setGraphic(delButton);
          }else{
            setGraphic(null);
            setText("");
          }
        }
      }
    }
    

    and the last one is your FXMLController.java. we modified it as below:

    package db;
    
    import java.net.URL;
    import java.sql.Statement;
    import java.util.ResourceBundle;
    
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.fxml.Initializable;
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.control.ButtonType;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;
    import javafx.stage.Stage;
    
    /**
     * FXML Controller class
     *
     * @author pc
     */
    public class FXMLController implements Initializable{
      @FXML
      public TextField t1;
      @FXML
      public TextField t2;
      @FXML
      public TextField t3;
      @FXML
      public TextField t4;
      @FXML
      public TextField t5;
    
      public Statement st;
    
      @FXML
      public void btnADD(ActionEvent e){
        Book book = new Book();
        try{
          Integer.valueOf(t1.getText());
        }catch(NumberFormatException exception){
          Alert alert = new Alert(AlertType.ERROR);
          alert.setContentText("BookID must be an integer");
          alert.showAndWait();
          return;
        }
        try{
          Double.valueOf(t5.getText());
        }catch(NumberFormatException exception){
          Alert alert = new Alert(AlertType.ERROR);
          alert.setContentText("Price must be an integer");
          alert.showAndWait();
          return;
        }
        book.setId(t1.getText());
        book.setName(t2.getText());
        book.setAuthor(t3.getText());
        book.setPublisher(t4.getText());
        book.setPrice(t5.getText());
    
        if(table != null){
          table.getItems().add(book);
          if(stage != null){
            t1.clear();
            t2.clear();
            t3.clear();
            t4.clear();
            t5.clear();
            stage.close();
          }
        }
    
      }
    
      @FXML
      public void btnCANCEL(ActionEvent e){
        Alert alert = new Alert(AlertType.CONFIRMATION);
        alert.setContentText("Close Window, Are you sure?");
        alert.showAndWait();
        ButtonType result = alert.getResult();
        if(result == ButtonType.OK){
          if(stage != null){
            stage.close();
          }
        }
        //System.exit(0);
      }
    
      @Override
      public void initialize(URL url, ResourceBundle rb){
    
      }
    
      private Stage stage;
      public void setStage(Stage stage){
        this.stage = stage;
      }
    
      private TableView<Book> table;
      public void setTable(TableView<Book> table){
        this.table = table;
      }
    }
    

    here we done. enter image description here

    we delete the Second.java, because it does nothing.