如何在单击另一页上的按钮时将数据添加到表视图?

时间:2017-06-20 18:12:07

标签: java javafx tableview fxml

我在JavaFX中执行此程序,该程序将从在Microsoft访问时创建的数据库中获取数据并将其放在表视图中。另外,我在表格视图中创建按钮(添加,删除),当点击添加按钮时,它将打开一个新的FXML页面。在这个页面中有5个TextFiled和两个按钮(添加和取消),当点击添加按钮时,它想要获取TextFiled中的所有数据并将其添加到我的表视图中。但实际上,我无法做到这一点。我希望这里的某个人能够知道如何实现这一目标。

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) 
    {

}
}

数据库结构

enter image description here

3 个答案:

答案 0 :(得分:2)

通过消费者

创建弹出窗口时,向其传递一个回调方法,该方法可以保留数据并刷新表格。弹出窗口应该在消费者添加&#39;单击按钮。以下是加载弹出窗口的示例:

// This method should be called with the table's 'Add' buttons are clicked
public void addButtonClicked() {
    try{
        // Load the popup
        FXMLLoader loader = new FXMLLoader(getClass().getResource("Popup.fxml"));
        loader.load();
        PopupController controller = loader.getController();
        Parent popup = loader.getRoot();

        // Give popup a callback method
        controller.setup(
            (value)->{data.add(value);table.refresh();}
        );

        // Display popup
        Stage stage = new Stage();
        stage.setScene(new Scene(popup));
        stage.show();
    } catch(IOException ex) {
        // ToDo: Handle failed popup
    }
}

enter image description here

来源

以下是主应用程序以及弹出式fxml和控制器的完整工作示例:

<强> JavaFxApplication.java

import java.io.IOException;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
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.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class JavaFXApplication20 extends Application {

    // Data for the table
    private ObservableList<String> data = FXCollections.observableArrayList(
                "Item 1","Object 2","Thing 3","Product 4"
        );

    // The table
    private TableView<String> table = new TableView<>(data);

    @Override
    public void start(Stage stage) throws Exception {
        // Content Column
        TableColumn<String,String> contentCol = new TableColumn<>("Content");
        contentCol.setCellValueFactory(p->new ReadOnlyObjectWrapper(p.getValue()));

        // Action Column
        TableColumn actionCol = new TableColumn("Action");
        actionCol.setCellFactory(param->  new TableCell<String, String>() {

                    final Button btn = new Button("Add");

                    @Override
                    public void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setGraphic(null);
                            setText(null);
                        } else {
                            // Make sure the column of 'Add' buttons 
                            // call the right method
                            btn.setOnAction(event->addButtonClicked());
                            setGraphic(btn);
                            setText(null);
                        }
                    }
        });

        // Display everything on the stage
        table.getColumns().addAll(contentCol,actionCol);
        Scene scene = new Scene(new VBox(table));
        stage.setScene(scene);
        stage.show();
    }

    public void addButtonClicked() {
        try{
            // Load the popup
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Popup.fxml"));
            loader.load();
            PopupController controller = loader.getController();
            Parent popup = loader.getRoot();

            // Give popup a callback method
            controller.setup(
                (value)->{data.add(value);table.refresh();}
            );

            // Display popup
            Stage stage = new Stage();
            stage.setScene(new Scene(popup));
            stage.show();
        } catch(IOException ex) {
            // ToDo: Handle failed popup
        }
    }

    public static void main(String[] args) {
        launch(args);
    }

}

<强> Popup.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:controller="javafxapplication20.PopupController">
    <children>
        <Button fx:id="button" layoutX="126" layoutY="90" onAction="#addButtonAction" text="Add" />
        <Label fx:id="label" layoutX="122.0" layoutY="62.0" minHeight="16" minWidth="69" text="Hello World" />
    </children>
</AnchorPane>

<强> PopupController.java

import java.net.URL;
import java.util.ResourceBundle;
import java.util.function.Consumer;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;

public class PopupController implements Initializable {

    @FXML
    private Label label;
    @FXML
    private Button button;

    private Consumer<String> callback;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // ToDo: Initialize something
    }    

    public void setup(Consumer<String> callback) {
        this.callback = callback;
    }

    @FXML
    private void addButtonAction(ActionEvent event) {
        callback.accept(label.getText());
    }

}

答案 1 :(得分:0)

我的朋友,基于你的代码,我已经对你的代码进行了一些重构以使其工作,但是代码的结构并不好,如果它是我的项目,我不会使用这个结构,LOL,只是为了参考。 如下所示。

首先,我们需要创建一个TableView的泛型类,在这里我们为它创建Book.java。

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;
  }
}

然后修改你的FXMLDocumentController.java,如下所示:

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("");
      }
    }
  }
}

,最后一个是你的FXMLController.java。我们修改如下:

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;
  }
}

我们在这里完成了。 enter image description here

我们删除了Second.java,因为它什么也没做。

答案 2 :(得分:0)

在Add上打开新的FXML页面(B)点击FXML的TableView页面(A) 保存在新B中输入的数据(在Add Clicked上),然后在新FXML(B)关闭时刷新A上的表格视图。