Reputation: 335
Actually I have a problem in my JavaFX app using TableView. I don't no why but, when I load data to TableView during runtime, the JavaFX is not rendering some rows, as you can see in the picture bellow:
But, when I resize the column, the data is displayed:
Bellow follow the source code used:
public void loadData()
{
// Define the TableView columns using Reflection defined by ResultSetMetadata
ArrayList<TableColumn> gridColumns = defineGridColumns(data.get(0));
this.tableView.getColumns().clear();
this.tableView.getColumns().addAll(gridColumns);
// Load data to TableView
this.tableView.setItems(FXCollections.observableArrayList(data));
}
private void defineGridColumns(Object singleData)
{
ArrayList<TableColumn> gridColumns = new ArrayList<>();
Field[] fields = singleData.getClass().getFields();
for (int i = 0; i < fields.length; i++)
{
TableColumn column = createTableColumn(fields[i].getName());
this.gridColumns.add(column);
}
return gridColumns;
}
private TableColumn createTableColumn(String columnName)
{
TableColumn column = new TableColumn(columnName);
column.setCellValueFactory(new PropertyValueFactory(columnName));
column.setPrefWidth(columnName.length() * 20);
HBox box = new HBox();
box.setAlignment(Pos.CENTER);
box.prefWidthProperty().bind(column.widthProperty().subtract(5));
box.setSpacing(10.0);
box.getChildren().addAll(new Label(column.getText()));
column.setGraphic(box);
// Align the cell content in center
column.setCellFactory(new Callback<TableColumn, TableCell>()
{
@Override
public TableCell call(TableColumn param)
{
TableCell cell = new TableCell()
{
@Override
public void updateItem(Object item, boolean empty)
{
if (item != null)
{
setText(item.toString());
}
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
return column;
}
Well, what I'm doing wrong? I already update my Java to the lastest version (JDK 1.8.11).
Thanks to everybody!
As resizing column width triggers JavaFX to display the data, I did a method that changes all columns sizes after the data is loaded:
public void loadData()
{
// Define the TableView columns using Reflection defined by ResultSetMetadata
ArrayList<TableColumn> gridColumns = defineGridColumns(data.get(0));
this.tableView.getColumns().clear();
this.tableView.getColumns().addAll(gridColumns);
// Load data to TableView
this.tableView.setItems(FXCollections.observableArrayList(data));
// HACK to force JavaFX display all data
final TrendAnalysisTabController thisController = this;
Platform.runLater(new Runnable()
{
@Override
public void run()
{
thisController.adjustAllColumnWidths();
}
});
}
private void adjustAllColumnWidths()
{
TableViewSkin<?> skin = (TableViewSkin<?>) this.tableView.getSkin();
TableHeaderRow headerRow = skin.getTableHeaderRow();
NestedTableColumnHeader rootHeader = headerRow.getRootHeader();
for (TableColumnHeader columnHeader : rootHeader.getColumnHeaders())
{
try
{
TableColumn<?, ?> column = (TableColumn<?, ?>) columnHeader.getTableColumn();
if (column != null)
{
// Changes the width column and rollback it
double prefWidth = column.getPrefWidth();
column.setPrefWidth(prefWidth + 0.01);
column.setPrefWidth(prefWidth);
}
}
catch (Throwable e)
{
log.log(Level.SEVERE, "Error adjusting columns widths: " + e.getMessage(), e);
}
}
}
Upvotes: 1
Views: 2705
Reputation: 165
because TableCells are reused, you need to explicitly "clear" them in your updateItem method:
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else{
setText(item.toString());
}
}
Upvotes: 5
Reputation: 209684
I'm not sure if this fixes your problem, but when creating a TableCell
implementation, your updateItem(...)
method must call super.updateItem(...)
:
column.setCellFactory(new Callback<TableColumn, TableCell>()
{
@Override
public TableCell call(TableColumn param)
{
TableCell cell = new TableCell()
{
@Override
public void updateItem(Object item, boolean empty)
{
// Don't omit this:
super.updateItem(item, empty);
if (item != null)
{
setText(item.toString());
}
}
};
cell.setAlignment(Pos.CENTER);
return cell;
}
});
Upvotes: 1