JavaFX Textfield 数据到不同 Stage 中的 TableView

JavaFX Textfield data to TableView in different Stage

我正在尝试将新 window 中的 TextField 中的用户数据输入到主 window 中的 TableView 中。但它没有填充 table,而且我没有收到任何异常。在按钮上单击新 window 刚刚关闭。我正在创建非常简单的应用程序,只是为了弄清楚如何在控制器之间正确通信。

package sample;

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

public class Main extends Application {
    static Stage primaryStage;
    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        this.primaryStage= primaryStage;
        this.primaryStage.setTitle("Hello World");
        this.primaryStage.setScene(new Scene(root));
        this.primaryStage.show();
    }

    public  void closeStage(){
        primaryStage.close();
    }

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

主 window 的控制器 class 其中 table 和用于打开新 Stage 的按钮:

package sample;

import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;


public class Controller implements Initializable {
    @FXML TableView<radnici> tabela;
    @FXML TableColumn<radnici, String> kolona;
    @FXML Button dodajRadnikaDugme;
    @FXML Button closeDugme;

    Main main = new Main();
    static Stage stage = new Stage();
    Scene scene;
    BorderPane borderPane;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        kolona.setCellValueFactory(new PropertyValueFactory<radnici, String>("ime"));
    }

    public  TableView<radnici> getTabela() {
        return tabela;
    }

    public TableColumn<radnici, String> getKolona() {
        return kolona;
    }

    //Opening new Stage on button clicked
    public void dodajRadnikaDugemKlik() throws IOException {
        FXMLLoader loader = new FXMLLoader();
        borderPane = new BorderPane();
        loader.setLocation(getClass().getResource("dodajRadnika.fxml"));
        borderPane = loader.load();
        scene = new Scene(borderPane);
        stage.setTitle("Dodaj Radnika");
        stage.setScene(scene);
        stage.showAndWait();
    }

    //Closing main window
    public void closeDugmeKlik(){
        main.closeStage();
    }

    //Method for closing new window
    public  void CloseStage(){
        stage.close();
    }
}

新 Window 的控制器 class 其中只有 TextField 和按钮:

package sample;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import java.io.IOException;

public class dodajRadnikaKontroler {
    @FXML TextField upišiRadnika;
    @FXML Button dodajRadnika;

    BorderPane borderPane;

    public void initialize(){
        System.out.println("učitavanje podataka...");
    }

    //Method for adding data on button clicked from TextField into table in main window
    @FXML public void dodajRadnikaKlik() throws IOException {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("sample.fxml"));
        borderPane = new BorderPane();
        borderPane = loader.load();
        Controller controller = loader.getController();
        ObservableList<radnici> lista = FXCollections.observableArrayList();
        lista.add(new radnici(upišiRadnika.getText()));
        controller.tabela.setItems(lista);
        upišiRadnika.clear();
        controller.CloseStage();
    }
}

工人模型 Class ("radnici"):

package sample;

public class radnici {
    private String ime;

    public radnici(String ime) {
        this.ime = ime;
    }

    public String getIme() {
        return ime;
    }

    public void setIme(String ime) {
        this.ime = ime;
    }
}

请有人帮助我,这样我才能最终正确地做到这一点。

注意:请使用proper naming conventions。我更改了 类 的一些名称,以便它们遵循标准约定。

您看不到 table 的更改,因为您正在从 FXML 文件加载一个全新的 UI 结构,包括一个新的 TableView,然后您在新 table 视图中设置项目。

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("sample.fxml"));
borderPane = new BorderPane();

// load a new UI from the FXML file:
borderPane = loader.load();
// get the controller for the new UI:
Controller controller = loader.getController();
ObservableList<radnici> lista = FXCollections.observableArrayList();
lista.add(new radnici(upišiRadnika.getText()));
// set the table items in the new UI:
controller.tabela.setItems(lista);
upišiRadnika.clear();
controller.CloseStage();

由于您甚至没有显示这个新 UI,因此您看不到 table 中的项目。

大概您真正想要做的是更新现有 table 中的项目。为此,您所需要的只是对 table 支持列表的引用。您需要将其传递给第二个 FXML 文件的控制器。添加字段和方法到 DodajRadnikaKontroler:

public class DodajRadnikaKontroler {

    // Existing code omitted:

    private ObservableList<Radnici> items ;

    public void setItems(ObservableList<Radnici> items) {
        this.itmes = items ;
    }
}

然后在加载 FMXL 文件时将 table 的列表传递给新控制器:

//Opening new Stage on button clicked
public void dodajRadnikaDugemKlik() throws IOException {
    FXMLLoader loader = new FXMLLoader();
    borderPane = new BorderPane();
    loader.setLocation(getClass().getResource("dodajRadnika.fxml"));
    borderPane = loader.load();

    DodajRadnikaKontroler controller = loader.getController();
    controller.setItems(tabela.getItems());

    scene = new Scene(borderPane);
    stage.setTitle("Dodaj Radnika");
    stage.setScene(scene);
    stage.showAndWait();
}

现在在 dodajRadnikaKlik() 方法中您只需更新列表:

@FXML public void dodajRadnikaKlik() throws IOException {

    // if you want to add an item:
    items.add(new radnici(upišiRadnika.getText()));

    // if you want to replace all items with the new one:
    // items.setAll(new radnici(upišiRadnika.getText()));

    upišiRadnika.clear();
    controller.CloseStage();
}