В вашем конструкторе PersonInputForm
class 'вы создаете FXMLLoader
для загрузки sample.fxml
. Затем вы передаете контроллер, полученный в результате этой нагрузки, - экземпляр Controller
- вашему экземпляру PersonInputFormController
, который вы создадите позже. Проблема в том, что экземпляр Controller
, который вызвал new PersonInputForm(event)
, не совпадает с экземпляром , который вы передаете PersonInputFormController
. Помните, что каждый раз, когда вы звоните FXMLLoader.load
, вы создаете новый граф сцены, подключенный к новому экземпляру контроллера.
Поскольку вы звоните new PersonInputForm(event)
из экземпляра Controller
, и именно в этом экземпляре Controller
вам нужно вызвать updateReceiverList()
on, самое простое решение - передать this
в PersonInputForm
как Что ж. Затем удалите код, отвечающий за загрузку sample.fxml
.
public PersonInputForm(ActionEvent event, Controller mainController) {
// code...
controller.setMainController(mainController);
}
Примечание. Такое поведение в конструкторе кажется неправильным.
Хотя вышесказанное решит вашу проблему (я полагаю), необходимость очищать и заменять элементы TableView
не идеальный подход. Взгляните на updateReceiverList()
:
public void updateReceiverList(){
// Copies Memory.receiverList into new ObservableList
final ObservableList<Person> data = FXCollections.observableArrayList(Memory.receiverList);
tableView.getItems().clear();
// Copies data into the TableView's items list
tableView.getItems().addAll(data);
}
Этот код копирует коллекцию в другую коллекцию дважды . Это может стать довольно дорогим, когда у вас есть большое количество элементов. Было бы лучше, если бы у вас была наблюдаемая модель, которую ваши контроллеры могли наблюдать и реагировать на нее.
Например, вы используете ArrayList
для хранения / публикации ваших Person
s, где вы могли бы использовать ObservableList
. Затем вы можете использовать tableView.setItems(Memory.receiverList)
, и любые обновления, сделанные вашим PersonInputFormController
в receiverList
, будут автоматически замечены TableView
. Поскольку вы, кажется, не используете многопоточность, эта настройка не должна вызывать никаких проблем. Когда или если вы начинаете использовать фоновые потоки, помните, что вы никогда не должны обновлять пользовательский интерфейс - прямо или косвенно - из фонового потока.
Однако использование глобального состояния (то есть общедоступных статических переменных) также не идеально. Я рекомендую ознакомиться с различными архитектурами приложений, такими как: Model-View-Controller (MVC), Model-View-Presenter (MVP), Model-View-ViewModel (MVVP) и т. Д. Затем попробуйте применить одну из них к вашему приложению. по мере необходимости.
Некоторые ссылки:
Я хотел бы отметить еще одну вещь в вашем коде. Вы используете много необработанных типов. Не используйте необработанные типы . Например, вы должны иметь:
@FXML private TableView<Person> tableView;
И
TableColumn<Person, String> mailColumn = new TableColumn<>("E-Mail");
// which lets you use the diamond operator here
mailColumn.setCellValueFactory(new PropertyValueFactory<>("mail"));
И
// You're missing the <> on the right hand side
public static ArrayList<Person> receiverList = new ArrayList<>();