如何从TableView(JavaFX)在新对话窗口中填充控件

时间:2018-06-10 13:45:49

标签: java javafx

我是Java和编程的新手,我正在尝试为学校项目构建一个带有数据库的小型桌面应用程序。 我有一个主窗口,其中有一个从MySql数据库填充的TableView,我添加了几个按钮来添加编辑和删除条目。单击“添加”按钮时,会弹出一个新窗口以插入数据(使用TextField控件)。它工作正常,表更新。但是,我无法对“编辑”按钮执行相同操作。我想从TableView中获取所选项目,当我按下编辑按钮时,我希望新窗口中的TextFields填充所选项目中的数据。我不知道如何做这项工作。我将衷心感谢您的帮助。我几乎在Google上尝试过每一件事。

主Java:

package proiect;

import javafx.beans.property.SimpleStringProperty;


public class Languages {
    int langId;
    SimpleStringProperty langName;
    SimpleStringProperty langCode;
    SimpleStringProperty cName;


    public Languages(int langId, String langName, String langCode, String cName) {
        this.langId = langId;
        this.langName = new SimpleStringProperty (langName);
        this.langCode = new SimpleStringProperty (langCode);
        this.cName = new SimpleStringProperty (cName);

    }

}

主控制器:

package proiect;

 import java.io.IOException;  import java.net.URL;  import java.sql.Connection;  import java.sql.DriverManager;  import java.sql.ResultSet;  import java.sql.SQLException;  import java.sql.Statement;  import java.util.ResourceBundle;  import java.util.logging.Level;  import java.util.logging.Logger;  import javafx.event.ActionEvent;  import javafx.fxml.FXML;  import javafx.fxml.FXMLLoader;  import javafx.scene.Scene;  import javafx.scene.control.TableColumn;  import javafx.scene.control.TableView;  import javafx.scene.control.TextField;  import javafx.scene.layout.BorderPane;  import javafx.stage.Modality;  import javafx.stage.Stage;

public class Tab1Controller {

    Connection cnx;

    Stage addLang;
    AddlangController ctrlAdd;

    Stage editLang;
    EditlangController ctrlEdit;

    int indexSelect;


    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    TableView<Languages> tlanguages;

    @FXML
    private TableColumn<Languages, Integer> langId;

    @FXML
    private TableColumn<Languages, String> langName;

    @FXML
    private TableColumn<Languages, String> langCode;

    @FXML
    private TableColumn<Languages, String> cName;

    @FXML
    private TextField searchlang;

    @FXML
    void add(ActionEvent event) {
        addLang.showAndWait();
    }

    @FXML
    void deleteLang(ActionEvent event) {
        try {

            int poz = (int) tlanguages.getSelectionModel().getSelectedIndex();
            Languages lang = tlanguages.getItems().get(poz);
            int id = lang.langId;
            String cda = "delete from languages where langId = " + id;
            Statement stm = cnx.createStatement();
            stm.executeUpdate(cda);
            stm.close();
            load();
        } catch (SQLException ex) {

            Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE,
                    null, ex);
        }
    }

    @FXML
    void editLang(ActionEvent event) {
        editLang.showAndWait();

    }

    @FXML
    void cancelLang(ActionEvent event) {

    }

    public void load() {
        tlanguages.getItems().clear();
        String cda = "select * from languages order by langname";

        ResultSet rs;
        try {
            Statement stmt;
            stmt = cnx.createStatement();
            rs = stmt.executeQuery(cda);
            while (rs.next()) {

                int langId = rs.getInt("langId");
                String langName = rs.getString("langName");
                String langCode = rs.getString("langCode");
                String cName = rs.getString("cName");

                Languages lang;
                lang = new Languages(langId, langName, langCode, cName);
                tlanguages.getItems().add(lang);
            }
            stmt.close();
        } catch (SQLException ex) {
            Logger.getLogger(Tab1Controller.class
                    .getName()).log(Level.SEVERE, null, ex);
        }

    }

    @FXML
    void initialize() {
        langName.setCellValueFactory(cellData -> cellData.getValue().langName);
        langCode.setCellValueFactory(cellData -> cellData.getValue().langCode);
        cName.setCellValueFactory(cellData -> cellData.getValue().cName);

        try {

            Class.forName("com.mysql.jdbc.Driver");
            cnx = DriverManager.getConnection("jdbc:mysql://localhost/Proiect?characterEncoding=utf8", "root", "");
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        load();

        //Get the window for "Add languages"
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Addlang.fxml"));
            BorderPane container = (BorderPane) loader.load();
            ctrlAdd = loader.getController();
            addLang = new Stage();
            addLang.setTitle("Add languages");
            addLang.initModality(Modality.APPLICATION_MODAL);
            Scene scena = new Scene(container);
            addLang.setScene(scena);
            ctrlAdd.ctrl = this;
        } catch (IOException ex) {
            Logger.getLogger(Tab1Controller.class.getName()).log(Level.SEVERE, null, ex);
        }

        // Get the window Edit Languages
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("Editlang.fxml"));
            BorderPane container = (BorderPane) loader.load();
            ctrlEdit = loader.getController();
            editLang = new Stage();
            editLang.setTitle("Edit languages");
            editLang.initModality(Modality.APPLICATION_MODAL);
            Scene scena = new Scene(container);
            editLang.setScene(scena);
            ctrlEdit.ctrl = this;

            tlanguages.getSelectionModel().selectedIndexProperty().addListener((object, oldValue, newValue) -> {
                indexSelect = (int) newValue;


            });

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

    } }

编辑控制器:

package proiect;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

public class EditlangController {

    Tab1Controller ctrl;

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
     TextField lName;

    @FXML
     TextField lCode;

    @FXML
     TextField country;

     @FXML
    TableView<Languages> tlanguages;

    @FXML
    void cancel(ActionEvent event) {
        ((Node) (event.getSource())).getScene().getWindow().hide();

    }

    private String apostrof(String s) {
        return "'" + s + "'";
    }

    @FXML
    void editLang(ActionEvent event) {

    }

        public void populate() {


 }

    @FXML
    void initialize() {


    }
}

1 个答案:

答案 0 :(得分:0)

您的代码示例未完整,因此我从头开始构建了一个快速应用程序,演示了如何执行此操作。

基本上,您需要在创建时将所选项目从TableView传递到新控制器。

以下是演示此示例程序的示例程序的完整列表(6个文件):

<强> Main.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        try {
            FXMLLoader loader = new FXMLLoader(Main.class.getResource("MainLayout.fxml"));

            primaryStage.setTitle("TableView Sample");
            primaryStage.setScene(new Scene(loader.load()));
            primaryStage.show();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

<强> MainController.java

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.io.IOException;


public class MainController {

    // Define the FXML controls
    @FXML
    private TableView<Data> tblDataView;
    @FXML
    private TableColumn<Data, String> colName;
    @FXML
    private TableColumn<Data, String> colEmail;
    @FXML
    private Button btnDoThings;

    @FXML
    private void initialize() {

        // Create sample Data objects for the TableView
        ObservableList<Data> dataList = FXCollections.observableArrayList();
        dataList.add(new Data("Bob", "bob@email.com"));
        dataList.add(new Data("Harley", "harley@coolspot.com"));
        dataList.add(new Data("Jane", "jane@email.com"));
        dataList.add(new Data("Moby", "mobyboy@toocool.com"));

        // Setup the TableView columns to display the correct data
        colName.setCellValueFactory(new PropertyValueFactory<>("name"));
        colEmail.setCellValueFactory(new PropertyValueFactory<>("email"));

        // Bind the list of sample data to the TableView
        tblDataView.setItems(dataList);

        // Set the action for the button
        btnDoThings.setOnAction(event -> doThings());

    }

    private void doThings() {
        // If no item has been selected from the table, do nothing
        if (tblDataView.getSelectionModel().getSelectedItem() == null) return;

        // Load the new window
        try {
            FXMLLoader loader = new FXMLLoader(Main.class.getResource("EditorLayout.fxml"));

            // Create the new controller and pass the currently selected data item to it
            EditorController controller = new EditorController(tblDataView.getSelectionModel().getSelectedItem());

            // Set the controller to the loader
            loader.setController(controller);

            Stage editorStage = new Stage();
            editorStage.setTitle("Edit Item");

            // Centers the editor window over the current window
            editorStage.initOwner(tblDataView.getScene().getWindow());

            // Ensures the new window needs to be closed before the current window can be used again
            editorStage.initModality(Modality.APPLICATION_MODAL);

            editorStage.setScene(new Scene(loader.load()));
            editorStage.showAndWait();

        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

在这里,您将看到doThings()方法。您将看到创建了一个新的EditorController对象并将其添加到loader。您可以使用该控制器的构造函数(下一个代码列表)来传递当前所选项目的引用以进行编辑。

您也可以重复使用相同的EditorController将新条目添加到列表中,方法是将new Data(null, null)传递给控制器​​。当然,您还需要将其添加到TableView的基础列表中。

<强> EditorController.java

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class EditorController {

    @FXML
    private TextField txtName;
    @FXML
    private TextField txtEmail;
    @FXML
    private Button btnSave;

    private Data data;

    // Constructor to accept the object to be edited
    public EditorController(Data data) {
        this.data = data;
    }

    @FXML
    private void initialize() {

        // Bind the data to the textfields
        txtName.textProperty().bindBidirectional(data.nameProperty());
        txtEmail.textProperty().bindBidirectional(data.emailProperty());

        btnSave.setOnAction(e -> handleSave());

    }

    private void handleSave() {
        // Just close the stage
        ((Stage) txtEmail.getScene().getWindow()).close();
    }
}

这个简单的控制器从MainController接收选定的行项,然后将其数据绑定到文本字段。此处对数据所做的任何更改也会自动更新回主窗口。

在这里你可以实现更多的能力,例如允许取消更改等等。但这应该让你开始朝着正确的方向开始,至少让数据可以操作。

<强> MainLayout.fxml

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="sample.tableViewSample.MainController">
    <children>
        <VBox alignment="CENTER" spacing="10.0">
            <children>
                <TableView fx:id="tblDataView">
                    <columns>
                        <TableColumn fx:id="colName" prefWidth="75.0" text="Name"/>
                        <TableColumn fx:id="colEmail" prefWidth="200.0" text="Email"/>
                    </columns>
                </TableView>
                <Button fx:id="btnDoThings" mnemonicParsing="false" text="Do Things!"/>
            </children>
            <padding>
                <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
            </padding>
        </VBox>
    </children>
</AnchorPane>

<强> EditorLayout.fxml

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <VBox spacing="10.0">
            <children>
                <GridPane hgap="10.0" vgap="5.0">
                    <columnConstraints>
                        <ColumnConstraints hgrow="SOMETIMES" minWidth="-Infinity"/>
                        <ColumnConstraints hgrow="ALWAYS" minWidth="10.0"/>
                    </columnConstraints>
                    <rowConstraints>
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES"/>
                    </rowConstraints>
                    <children>
                        <Label text="Name:"/>
                        <Label text="Email:" GridPane.rowIndex="1"/>
                        <TextField fx:id="txtName" GridPane.columnIndex="1"/>
                        <TextField fx:id="txtEmail" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
                    </children>
                </GridPane>
                <HBox alignment="CENTER" spacing="10.0" VBox.vgrow="NEVER">
                    <children>
                        <Button fx:id="btnSave" defaultButton="true" mnemonicParsing="false" text="Save Changes"/>
                    </children>
                </HBox>
            </children>
            <padding>
                <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
            </padding>
        </VBox>
    </children>
</AnchorPane>