[英]How to refresh a TableView in window A from a Window B in javaFX? (Edit)
[英]How do I update a TableView in window 1 by an action of a button in window 2 with JavaFX
从昨天开始,我一直在搜索和思考这个问题。 现在大约10个小时。 我已经浏览了所有与我的问题有任何相似之处的现有线程,但没有一个对我有帮助。 我尝试过使用所谓的“回调”方法,但我仍然无法让它工作。
情况:
我如何做到这一点,以便在创建 TableView 的新条目后,该条目立即显示在 tableview 中。 如何在从第二个窗口(阶段)为其创建新条目时刷新 TableView? 基本上,我需要实现的是让一个 controller 由另一个不在同一个 window 中的 controller 触发的方法。
package main.JavaFX;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
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 main.classes.LectureHall;
import main.sqlite.DatabaseCommunicaton;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
public class LectureHallsTabController {
@FXML
private TableView<LectureHall> lectureHallsTableView;
@FXML
private Button addNewLectureHallButton;
@FXML
private Button deleteLectureHallButton;
private TableColumn<LectureHall, String> column1;
private TableColumn<LectureHall, Integer> column2;
ArrayList<LectureHall> lhlist = new ArrayList<>();
DatabaseCommunicaton dbcomm = new DatabaseCommunicaton();
public void initialize() throws SQLException {
column1 = new TableColumn<>("Hall code");
column2 = new TableColumn<>("Hall capacity");
column1.setCellValueFactory(new PropertyValueFactory<>("hallCode"));
column2.setCellValueFactory(new PropertyValueFactory<>("capacity"));
lectureHallsTableView.getColumns().add(0, column1);
lectureHallsTableView.getColumns().add(1, column2);
lhlist = dbcomm.queryLectureHalls();
lectureHallsTableView.getItems().addAll(lhlist);
/**
* Delete button functionality
*/
deleteLectureHallButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
LectureHall selectedItem = lectureHallsTableView.getSelectionModel().getSelectedItem();
try {
lhlist = dbcomm.deleteLectureHall(selectedItem.getId());
lectureHallsTableView.getItems().clear();
lectureHallsTableView.getItems().addAll(lhlist);
} catch (SQLException e) {
e.printStackTrace();
}
}
});
}
/**
* populates the tableView with all the existing database entries
*/
public void refreshLectureHalls() throws SQLException {
lhlist = dbcomm.queryLectureHalls();
}
public void openLectureHallInputWindow(ActionEvent actionEvent) {
Stage stage = new Stage();
Parent root = null;
try {
root = FXMLLoader.load(getClass().getResource("lectureHallInput.fxml"));
} catch (IOException e) {
e.printStackTrace();
}
stage.setTitle("Lecture Input");
stage.setScene(new Scene(root));
stage.setResizable(false);
// Serves the purpose of the new window being imposed over the other window
stage.initModality(Modality.APPLICATION_MODAL);
stage.show();
}
}
package main.JavaFX;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import main.sqlite.DatabaseCommunicaton;
import java.sql.SQLException;
public class LectureHallInputController {
@FXML
private Button confirmButton;
@FXML
private Button cancelButton;
@FXML
private TextField hallCodeField;
@FXML
private TextField hallCapacityField;
public void initialize() {
cancelButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
Stage stage = (Stage) cancelButton.getScene().getWindow();
stage.close();
}
});
confirmButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
String hallCode = hallCodeField.getText();
int hallCapacity = Integer.parseInt(hallCapacityField.getText());
DatabaseCommunicaton dbcomm = new DatabaseCommunicaton();
try {
dbcomm.addLectureHall(hallCode, hallCapacity);
} catch (SQLException e) {
e.printStackTrace();
}
Stage stage = (Stage) confirmButton.getScene().getWindow();
stage.close();
}
});
}
}
我已经实现了这个答案所详述的内容。 我所做的要点是,我创建了一个新的 class,其目的是“托管” ObservableList,然后我的两个窗口/阶段从中读取它们的数据。 由于可观察列表会自动通知我的 tableView 任何更改,通过在一个窗口/阶段对其进行更改(例如在我的情况下添加新条目),另一个 window 自动并立即显示更改在它的 tableView 中。
这是我创建的 class 这是我需要的
public class LectureHallData{
DatabaseCommunicaton dbcomm = new DatabaseCommunicaton();
public ObservableList<LectureHall> getLectureHallList() {
return lectureHallList;
}
public ObservableList<LectureHall> lectureHallList = FXCollections.observableArrayList(lectureHall -> new Observable[]{lectureHall.codeProperty(), lectureHall.capacityProperty()});
private ObjectProperty<LectureHall> currentLectureHall = new SimpleObjectProperty<>();
public ObservableList<LectureHall> loadLectureHalls() throws SQLException {
ObservableList<LectureHall> lectureHallObservableList = FXCollections.observableArrayList(dbcomm.queryLectureHalls());
this.lectureHallList = lectureHallObservableList;
return lectureHallObservableList;
}
public void refreshLectureHalls() throws SQLException {
this.lectureHallList.clear();
this.lectureHallList.addAll(FXCollections.observableArrayList(dbcomm.queryLectureHalls()));
}
public void addLectureHall(String hallCode, int hallCapacity) throws SQLException {
dbcomm.addLectureHall(hallCode, hallCapacity);
refreshLectureHalls();
}
}
这是 window 的 controller 产生第二个 window
public class LectureHallsTabController {
@FXML
private TableView<LectureHall> lectureHallsTableView;
@FXML
private Button addNewLectureHallButton;
@FXML
private Button deleteLectureHallButton;
private TableColumn<LectureHall, String> column1;
private TableColumn<LectureHall, Integer> column2;
ArrayList<LectureHall> lhlist = new ArrayList<>();
DatabaseCommunicaton dbcomm = new DatabaseCommunicaton();
private LectureHallData data;
public void initialize() throws SQLException {
initData();
}
public void openLectureHallInputWindow(ActionEvent actionEvent) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("lectureHallInput.fxml"));
Stage stage = new Stage();
Parent root = null;
try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
LectureHallInputController lectureHallInputController = loader.getController();
lectureHallInputController.initData(data);
stage.setTitle("Lecture Input");
stage.setScene(new Scene(root));
stage.setResizable(false);
// Serves the purpose of the new window being imposed over the other window
stage.initModality(Modality.APPLICATION_MODAL);
stage.show();
}
public void initData() throws SQLException {
// ensure data is only set once:
if (this.data != null) {
throw new IllegalStateException("Data can only be initialized once");
}
this.data=new LectureHallData();
column1 = new TableColumn<>("Hall code");
column2 = new TableColumn<>("Hall capacity");
column1.setCellValueFactory(new PropertyValueFactory<>("hallCode"));
column2.setCellValueFactory(new PropertyValueFactory<>("capacity"));
lectureHallsTableView.getColumns().add(0, column1);
lectureHallsTableView.getColumns().add(1, column2);
lectureHallsTableView.getItems().clear();
data.loadLectureHalls();
lectureHallsTableView.setItems(data.getLectureHallList());
}
}
这是第二个窗口的 controller
public class LectureHallInputController {
@FXML
private Button confirmButton;
...
private LectureHallData data;
public void initialize() {
...
confirmButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
String hallCode = hallCodeField.getText();
int hallCapacity = Integer.parseInt(hallCapacityField.getText());
try {
data.addLectureHall(hallCode, hallCapacity);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
Stage stage = (Stage) confirmButton.getScene().getWindow();
stage.close();
}
});
}
public void initData(LectureHallData data) {
this.data = data;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.