I've a scene where I can create a data, now I want to put it into my TableView "TV_currency".
But this one is into another scene who's already open and I don't want to close and reopen this one.
Can you take a look to it ?
ControllerOptions.java (TV_currency is here) :
public class ControllerOptions implements Initializable{
//VARIABLES
@FXML private TableView<Currency> TV_currency;
@FXML private TableColumn<Currency, String> TC_name;
@FXML private TableColumn<Currency, Double> TC_value;
private ObservableList<Currency> currencies = FXCollections.observableArrayList();
//FUNCTIONS
@Override
public void initialize(URL location, ResourceBundle rb){
//initialisation Table Currencies
for (Currency currency : Datas.getInstance().getCurrencies()) {
currencies.add(currency);
}
TC_name.setCellValueFactory(new PropertyValueFactory<Currency, String>("name"));
TC_value.setCellValueFactory(new PropertyValueFactory<Currency, Double>("value"));
TV_currency.setItems(currencies); //TODO Corriger setItems() de la TableView
}
@FXML void add_currency(MouseEvent event) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("options/currency_add.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.setTitle("Add new currency");
stage.setScene(new Scene(root1));
stage.setFullScreen(true);
stage.show();
}
@FXML void open_options(ActionEvent event) throws IOException {
Group actor = new Group();
actor.getChildren().add(FXMLLoader.load(getClass().getResource("options.fxml")));
com.courieux.wheresmymoney.Main.setScene(actor, "Where's My Money");
}
}
ControllerCurrencyAdd.java (where I want to edit TV_currency):
public class ControllerCurrencyAdd {
@FXML private TextField TF_name;
@FXML private TextField TF_value;
@FXML private TextField TF_acronym;
@FXML
void add(ActionEvent event) {
Currency currency = new Currency(TF_name.getText(), Double.valueOf(TF_value.getText()));
Datas.getInstance().addCurrency(currency);
//==> HERE I NEED TO EDIT VARIABLES BELOW <==
//currencies.setAll(Datas.getInstance().getCurrencies());
//TV_currency.setItems(currencies);
}
}
Datas.java :
public class Datas {
//SINGLETON PATTERN
private Datas() {}
private static Datas INSTANCE = new Datas();
public static Datas getInstance(){
return INSTANCE;
}
//END SINGLETON PATTERN
//VARS
private List<Currency> currencies = new ArrayList<>();
//FUNCTIONS - Add/Edit/Delete
public void addCurrency(Currency currency){
currencies.add(currency);
}
//FUNCTIONS - getter/setters
public List<Currency> getCurrencies() {
return currencies;
}
public void setCurrencies(List<Currency> currencies) {
this.currencies = currencies;
}
}
Currency.java :
public class Currency {
//VARS
private String name;
private double value;
//FUNCTIONS - constructors
public Currency(String name, double value) {
setName(name);
setValue(value);
}
//FUNCTIONS
public boolean equals(Currency currency){
if(this.name == currency.getName()
&& this.value == currency.getValue()){
return true;
} else {
return false;
}
}
//FUNCTIONS - getters/setters
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setValue(double value) {
this.value = value;
}
public double getValue() {
return value;
}
}
Then I want to put new data into the ObservableList "currencies" and set TV_currency with it.
Thanks in advance !
The simplest change you can make to your code is to let your singleton class hold an ObservableList
instead of a List
. Then you can use that directly in the table view, and update it directly in other controllers. Since the table view observes its backing list, changes to the observable list will immediately be reflected in the table.
I.e.
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Datas {
// SINGLETON PATTERN
private Datas() {
}
private static Datas INSTANCE = new Datas();
public static Datas getInstance() {
return INSTANCE;
}
// END SINGLETON PATTERN
// VARS
private ObservableList<Currency> currencies = FXCollections.observableArrayList();
// FUNCTIONS - Add/Edit/Delete
public void addCurrency(Currency currency) {
currencies.add(currency);
}
// FUNCTIONS - getter/setters
public ObservableList<Currency> getCurrencies() {
return currencies;
}
}
and then
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class ControllerOptions implements Initializable {
// VARIABLES
@FXML
private TableView<Currency> TV_currency;
@FXML
private TableColumn<Currency, String> TC_name;
@FXML
private TableColumn<Currency, Double> TC_value;
private ObservableList<Currency> currencies = FXCollections.observableArrayList();
// FUNCTIONS
@Override
public void initialize(URL location, ResourceBundle rb) {
// initialisation Table Currencies
TC_name.setCellValueFactory(new PropertyValueFactory<Currency, String>("name"));
TC_value.setCellValueFactory(new PropertyValueFactory<Currency, Double>("value"));
// Note how the list from Datas is used directly in the table:
TV_currency.setItems(Datas.getInstance().getCurrencies());
}
@FXML
void add_currency(MouseEvent event) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("options/currency_add.fxml"));
Parent root1 = (Parent) fxmlLoader.load();
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.setTitle("Add new currency");
stage.setScene(new Scene(root1));
stage.setFullScreen(true);
stage.show();
}
@FXML
void open_options(ActionEvent event) throws IOException {
Group actor = new Group();
actor.getChildren().add(FXMLLoader.load(getClass().getResource("options.fxml")));
Main.setScene(actor, "Where's My Money");
}
}
and
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.TextField;
public class ControllerCurrencyAdd {
@FXML
private TextField TF_name;
@FXML
private TextField TF_value;
@FXML
private TextField TF_acronym;
@FXML
void add(ActionEvent event) {
Currency currency = new Currency(TF_name.getText(), Double.valueOf(TF_value.getText()));
// since we update the list used as the table's backing list, the table will automatically update:
Datas.getInstance().addCurrency(currency);
}
}
Your Datas
class is considered to be a "model" in the MVC (and related) design patterns. Typically making this a singleton can restrict you a bit in terms of modifying the application later (many programmers believe this to be an anti-pattern). You might consider making this a regular class and using dependency-injection techniques to give each controller access to the same instance.