Как я могу заполнить элементы управления в новом диалоговом окне из TableView (JavaFX) - PullRequest
0 голосов
/ 10 июня 2018

Я очень плохо знаком с Java и программированием и пытаюсь создать небольшое настольное приложение с базой данных для школьного проекта.У меня есть главное окно с TableView, заполненным из базы данных MySql, и я добавил несколько кнопок, чтобы добавить записи редактирования и удаления.При нажатии на кнопку «Добавить» открывается новое окно для вставки данных (с элементами управления TextField).Это работает просто отлично, и таблица обновляется.Однако я не могу сделать то же самое для кнопки «Изменить».Я хочу получить выбранный элемент из TableView, и когда я нажимаю кнопку «Редактировать», я хочу, чтобы текстовые поля в новом окне заполнялись данными из выбранного элемента.Я понятия не имею, как заставить это работать.Буду очень признателен за вашу помощь.Я попробовал почти все в 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 голосов
/ 10 июня 2018

Ваш пример кода не был завершен, поэтому я с нуля создал быстрое приложение, которое демонстрирует, как это сделать.

По сути, вам нужно будет передать выбранный элемент из 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...