Reputation: 147
I'm trying to input user data from TextField
in new window into TableView
in the main window. But it is not populating table, and I'm not getting any Exception. On button clicked new window just closes. I'm creating very simple app just to figure out how to communicate properly between controllers.
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);
}
}
Controller class for main window where are table and button for opening new 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();
}
}
Controller class for the new Window where are just TextField
and Button:
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();
}
}
Model Class for workers ("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;
}
}
Please can someone help me so that I can finally do this properly.
Upvotes: 0
Views: 1784
Reputation: 209235
Note: please use proper naming conventions. I have changed some names of classes so that they follow standard conventions.
You don't see the changes to your table, because you are loading a entire new UI structure from the FXML file, including a new TableView
, and then you set the items in that new table view.
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();
Since you don't even display this new UI, you don't see the items in the table.
Presumably what you actually want to do is update the items in the existing table. All you need for this is a reference to the table's backing list. You need to pass that to the controller for the second FXML file. Add a field and method to DodajRadnikaKontroler
:
public class DodajRadnikaKontroler {
// Existing code omitted:
private ObservableList<Radnici> items ;
public void setItems(ObservableList<Radnici> items) {
this.itmes = items ;
}
}
and then pass the table's list to the new controller when you load the FMXL file:
//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();
}
and now in the dodajRadnikaKlik()
method you just update the list:
@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();
}
Upvotes: 1