Вставка данных в таблицу TableView в момент выполнения программы (JavaFX)
Суть проблемы: создавал я значит интерфейс через SceneBuilder, там я сразу добавил таблицу TableView и присвоил ей id, сохранил все и добавил реализацию класса контроллера. Везде на все возможных руководствах по тому, как создавать таблицу показывают, что нужно сначала создать таблицу, потом добавить данные и ВРУЧНУЮ добавить в родительский узел для отображения на самом экране. Но в моем случае подразумевается добавление не изначальных данных, а по ходу выполнения. Т.е. когда у меня есть тот самые объект TableView я пытаюсь в момент выполнения программы добавлять новые столбцы, скажем, в обработчике события нажатия кнопки. И нечего абсолютно не добавляется, возможно это связанно с тем, что я пересоздаю объект перед тем, как что-то туда добавить, ибо необходимо передать в конструктор таблицы коллекцию с элементами для заполнения.
Мой код
package sample;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class Controller {
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private MenuItem addElement;
@FXML
private TableView<Person> table;
@FXML
void initialize() {
addElement.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
ArrayList<Person> per = new ArrayList<>();
per.add(new Person("Dima", 10));
per.add(new Person("Ivan", 10));
ObservableList<Person> collection = FXCollections.observableArrayList(per);
table = new TableView<Person>(collection);
TableColumn<Person, String> nameColumn = new TableColumn<>("Имена");
nameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("name"));
table.getColumns().add(nameColumn);
TableColumn<Person, Integer> ageColumn = new TableColumn<>("Возраст");
ageColumn.setCellValueFactory(new PropertyValueFactory<Person, Integer>("age"));
table.getColumns().add(ageColumn);
}
});
}
}
Из кода видно что я добавляю некого Person в таблицу, при этом необходимо создать новый объект для передачи элементов для отображения с коллекции типа Person. Тут еще один интересный момент, если мы не создаем при этом новый объект таблицы, то просто отобразится название колонок, а если создать новую таблицу с данными, то вообще нечего не отображается.
Код класа Person
package sample;
import javafx.beans.property.*;
public class Person {
private SimpleStringProperty name;
private SimpleIntegerProperty age;
public Person(String name, int age){
this.name = new SimpleStringProperty(name);
this.age = new SimpleIntegerProperty(age);
}
public String getName(){
return name.get();
}
public int getAge(){
return age.get();
}
public void setName(String name){
this.name.set(name);
}
public void setAge(int age){
this.age.set(age);
}
}
Ответы (1 шт):
Проблем в коде вижу несколько.
- Не надо пересоздавать tableView - это ни к чему. У вас уже есть таблица на гуе, используйте ее
- При нажатии кнопки addElement у вас не должны создаваться новые колонки (не вижу смысла в этом). Создайте колонки один раз и заполняйте содержимое таблицы.
Таким образом, ваше метод initialize будет выглядеть примерно так
@FXML
void initialize() {
//один раз создаем колонку Name и добавляем ее
TableColumn<Person, String> nameColumn = new TableColumn<>("Имена");
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
table.getColumns().add(nameColumn);
//один раз создаем колонку Age и добавляем ее
TableColumn<Person, Integer> ageColumn = new TableColumn<>("Возраст");
ageColumn.setCellValueFactory(new PropertyValueFactory<>("age"));
table.getColumns().add(ageColumn);
// на каждый клик создаем нового Person и добавляем в таблицу
addElement.setOnAction(actionEvent -> {
ArrayList<Person> persons = new ArrayList<>();
persons.add(new Person("Dima " + random.nextInt(1000), 10));
persons.add(new Person("Ivan " + random.nextInt(1000), 10));
table.getItems().addAll(persons);
});
}