java - 单击另一个页面上的按钮时如何将数据添加到 TableView ?

标签 java javafx tableview fxml

我正在 JavaFX 中执行此程序,该程序将从 Microsoft Access 创建的数据库中获取数据并将其放置在 TableView 中。另外,我在 TableView 内创建了按钮(添加、删除),当单击添加按钮时,它将打开一个新的 FXML 页面。在此页面中有 5 个 TextFiled 和两个按钮(添加和取消),当单击添加按钮时,它会获取 TextFiled 中的所有数据并将其添加到我的 TableView 中。但我实际上做不到。我希望这里有人知道我如何实现这一目标。

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

最佳答案

传递消费者

创建弹出窗口时,向其传递一个回调方法,以保留数据并刷新表。单击“添加”按钮时,弹出窗口应调用消费者。这是加载弹出窗口的示例:

// 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 和 Controller :

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

}

关于java - 单击另一个页面上的按钮时如何将数据添加到 TableView ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44660241/

相关文章:

JavaFX - 如何清除 anchorPane 中的所有节点

iphone - 无法在 TableView Swift 上显示任何内容

json - Swift 4 将数据从 json 保存到数组以在 TableView 中显示

javafx - 如何将 javafx - tableview 大小修复为当前窗口大小

java - 如何将 setText 设置为所有 SeekBar 进度值的总和?

java - 为什么没有整数输出

java - tomcat不显示图像

java - 如何在过程中附加查询的一部分?

java - 用SwingX的ImageView进行CollorAdjust?

java - 在 NetBeans 上运行 JavaFX 应用程序时出现 "URI is not hierarchical"