Класс javafx.scene.control.TableView<S> предназначен для создания табличных представлений. С помощью параметра S в угловых скобках определяется тип данных, которые будут отображаться в таблице.
Для создания TableView можно принять один из двух конструкторов класса:
Для начала нам надо определить данные, которые будут выводиться в таблице. Для этого создадим новый файл Person.java, в котором определим следующий класс Person
import javafx.beans.property.*; public class Person{ private SimpleStringProperty name; private SimpleIntegerProperty age; Person(String name, int age){ this.name = new SimpleStringProperty(name); this.age = new SimpleIntegerProperty(age); } public String getName(){ return name.get();} public void setName(String value){ name.set(value);} public int getAge(){ return age.get();} public void setAge(int value){ age.set(value);} }
Основну класса Person составляют свойства name и age, которые имеют тип SimpleStringProperty и SimpleIntegerProperty соответственно. Фактически эти типы представляю надстройку над стандартными типами String и Integer. В целом пакет javafx.beans.property еще ряд типов, которые можно использовать для определения свойств в зависимости от типа данных, которые мы хотим сохранить:
SimpleBooleanProperty
SimpleIntegerProperty
SimpleDoubleProperty
SimpleFloatProperty
SimpleLongProperty
SimpleStringProperty
SimpleMapProperty<K, V>
SimpleListProperty<E>
SimpleSetProperty<E>
SimpleObjectProperty<T>
Каждый подобный тип определяет метод get(), который возвращает хранимые данные, и метод set(), которые устанавливает данные.
При этом методы доступа - геттеры и аксессоры определять необязательно.
Любая таблица представляет набор ячеек, которые образуют на пересечении строк и столбцов. Каждая строка в таблице отображает отдельный элемент из коллекции ObservableList, которая передается через конструктор в TableView. В нашем случае каждая отдельная строка будет представлять отдельные объкт класс Person.
Для определения столбцов в TableView применяется класс TableColumn<S, T>. Объект TableColumn типизируется двумя типами: параметр S представляе тот же тип, которым тизирован объект TableView (тип отображаемых в таблице данных), а параметр T передает тип данных в рамках данного столбца.
С помощью конструктора TableColumn можно определить заголовок столбца:
TableColumn<S, T>(String header)
После определения столбца для него надо установить фабрику генерации значения с помощью метода setCellValueProperty(). Фабрика определяет, как ячейка будет получать значение.
В данном случае можно использовать встроенный класс javafx.scene.control.cell.PropertyValueFactory, который позволяет установить привязку столбца к определенному свойству данных с помощью конструктора:
PropertyValueFactory(String propertyName)
После этого столбец надо добавить в коллекцию столбцов TableView.
Отобразим данные класса Person в таблице:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.scene.control.Label; import javafx.scene.control.TableView; import javafx.scene.control.TableColumn; import javafx.collections.ObservableList; import javafx.collections.FXCollections; import javafx.scene.control.cell.PropertyValueFactory; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) throws Exception { // создаем список объектов ObservableList<Person> people = FXCollections.observableArrayList( new Person("Tom", 34), new Person("Bob", 22), new Person("Sam", 28), new Person("Alice", 29) ); // определяем таблицу и устанавливаем данные TableView<Person> table = new TableView<Person>(people); table.setPrefWidth(250); table.setPrefHeight(200); // столбец для вывода имени TableColumn<Person, String> nameColumn = new TableColumn<Person, String>("Name"); // определяем фабрику для столбца с привязкой к свойству name nameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("name")); // добавляем столбец table.getColumns().add(nameColumn); // столбец для вывода возраста TableColumn<Person, Integer> ageColumn = new TableColumn<Person, Integer>("Age"); ageColumn.setCellValueFactory(new PropertyValueFactory<Person, Integer>("age")); table.getColumns().add(ageColumn); FlowPane root = new FlowPane(10, 10, table); Scene scene = new Scene(root, 300, 250); stage.setScene(scene); stage.setTitle("TableView in JavaFX"); stage.show(); } }
Скомпилируем оба класса (Person и Main) и запустим программу:
Для получения выделенных в TableView строк используется класс TableView.TableViewSelectionModel<S>. Для получения объекта этого класса у TableView вызывается метод getSelectionModel(). Например, выведем выделенный в таблице объект Person:
import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.FlowPane; import javafx.scene.control.Label; import javafx.scene.control.TableView; import javafx.scene.control.TableColumn; import javafx.collections.ObservableList; import javafx.collections.FXCollections; import javafx.scene.control.cell.PropertyValueFactory; import javafx.geometry.Orientation; import javafx.beans.value.ObservableValue; import javafx.beans.value.ChangeListener; public class Main extends Application{ public static void main(String[] args) { Application.launch(args); } @Override public void start(Stage stage) throws Exception { // создаем список объектов ObservableList<Person> people = FXCollections.observableArrayList( new Person("Tom", 34), new Person("Bob", 22), new Person("Sam", 28), new Person("Alice", 29) ); Label lbl = new Label(); TableView<Person> table = new TableView<Person>(people); table.setPrefWidth(250); table.setPrefHeight(200); // столбец для вывода имени TableColumn<Person, String> nameColumn = new TableColumn<Person, String>("Name"); nameColumn.setCellValueFactory(new PropertyValueFactory<Person, String>("name")); table.getColumns().add(nameColumn); // столбец для вывода возраста TableColumn<Person, Integer> ageColumn = new TableColumn<Person, Integer>("Age"); ageColumn.setCellValueFactory(new PropertyValueFactory<Person, Integer>("age")); table.getColumns().add(ageColumn); TableView.TableViewSelectionModel<Person> selectionModel = table.getSelectionModel(); selectionModel.selectedItemProperty().addListener(new ChangeListener<Person>(){ public void changed(ObservableValue<? extends Person& val, Person oldVal, Person newVal){ if(newVal != null) lbl.setText("Selected: " + newVal.getName()); } }); FlowPane root = new FlowPane(Orientation.VERTICAL, 10, 10, lbl, table); Scene scene = new Scene(root, 300, 250); stage.setScene(scene); stage.setTitle("TableView in JavaFX"); stage.show(); } }
В данном случае информация о выделенной строке выводится в элементе Label. Для этого у TableView.TableViewSelectionModel вызывается
метод selectedItemProperty()
, который возвращает объект ReadOnlyObjectProperty и предоставляет доступ к выбранному в таблице элементу.
Для прослушивания изменений выделенного элемента у ReadOnlyObjectProperty вызывается метод addListener()
, который устанавливает слушателя изменений.
Слушатель представляет реализацию интерфейса ChangeListener. Интерфейс также типизируется типом Person - типом объектов в таблице. В методе changed этого интерфейса с помощью параметра newVal мы можем получить новый выбранный объект Person.