I've tried to make a helper class for creating a JavaFX TableView containing some records:
public record Product(String id, String manufacturer, String model, String price, String quantity, String remarks) {
public SimpleStringProperty getIdProperty() { return new SimpleStringProperty(id); }
public SimpleStringProperty getManufacturerProperty() { return new SimpleStringProperty(manufacturer); }
public SimpleStringProperty getModelProperty() { return new SimpleStringProperty(model); }
public SimpleStringProperty getPriceProperty() { return new SimpleStringProperty(price); }
public SimpleStringProperty getQuantityProperty() { return new SimpleStringProperty(quantity); }
public SimpleStringProperty getRemarksProperty() { return new SimpleStringProperty(remarks); }
}
public class TableItems {
private static boolean isReturnTypeSimpleStringProperty(Method method) {
return method.getReturnType() == SimpleStringProperty.class;
}
private static <T> TableColumn<T, String> createTableColumn(Method method, String label) {
TableColumn<T, String> column = new TableColumn<>(label);
column.setCellValueFactory(cellData -> {
try {
return (SimpleStringProperty) method.invoke(cellData.getValue());
} catch (Exception e) {
return null;
}
});
return column;
}
public static <T> TableView<T> getTableView(ObservableList<T> itemList, String... labels) {
TableView<T> table = new TableView<>(itemList);
Class<?> itemClass = (itemList.isEmpty()) ? Object.class : itemList.get(0).getClass();
Method[] methods = itemClass.getMethods();
int labelIdx = 0;
for (Method method : methods) {
if (isReturnTypeSimpleStringProperty(method)) {
TableColumn<T, String> column = createTableColumn(method, labels[labelIdx]);
table.getColumns().add(column);
labelIdx++;
}
}
return table;
}
@SafeVarargs
public static <T> ObservableList<T> getObservableList(T...items) {
return FXCollections.observableArrayList(List.of(items));
}
}
But when I try to insert some sample data:
ObservableList<Product> list = TableItems.getObservableList(
new Product("1", "Samsung", "Oddysey", "1000", "30", null),
new Product("2", "Samsung", "Oddysey", "1000", "30", null),
new Product("3", "Samsung", "Oddysey", "1000", "30", null),
new Product("4", "Samsung", "Oddysey", "1000", "30", null),
new Product("5", "Samsung", "Oddysey", "1000", "30", null)
);
TableView<Product> tableView = TableItems.getTableView(list, "ID", "Manufacturer", "Model", "Price", "Quantity", "Remarks");
...
Each time I run the program, the columns get sorted in a random order and the headings don't match the data anymore, for example:
I couldn't really find a problem similar to this, so is there a thing which I miss?


getXXXProperty(). This is going to completely mess up the listeners that the cells register with those properties. You should instantiate each property once and return it from those methods.PropertyValueFactory, including all its flaws. It's not much harder to write aprivate static <T> TableColumn<T, String> createTableColumn(String label, Function<T, Property<String>> property) { ... }method which avoids those problems.getMethods(): "The elements in the returned array are not sorted and are not in any particular order.". Your code assumes they are magically in the same order as the labels you provide.