Reputation: 1566
I'm trying to automatically include numbers on my table view.
I have 2 tables having a similar structure and the idea is to copy selected items from tableA to tableB on button click.
Total columns: 3
RowCol = supposed to show numbers automatically
TestCol = Test Name (coming from a Model class)
ModCol = Module (coming from a Model class)
I came across this question to solve auto-numbering for tableA.
auto numbered table rows (javafx)
Code:
tableARowCol.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<Number>(
tableA.getItems().indexOf(cellData.getValue()) + 1));
tableATestCol.setCellValueFactory(cellData -> cellData.getValue().testCaseNameProperty());
tableAModCol.setCellValueFactory(cellData -> cellData.getValue().moduleNameProperty());
This is working well for tableA and I use the same code for tableB but I get the following problem (The auto numbering is not updating properly when adding data on btn click):
In the image, the row numbers of tableB are showing as 1,2,3,3,3,2,7.
This was the output when I did the following:
I want to know what seems to be the problem and how can I fix it. To be honest I do not fully understand the line for auto numbering rows.
Flow of what is happening so far:
Worth mentioning:
Code for tableB row numbering:
tableBRowCol.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<Number>(
tableB.getItems().indexOf(cellData.getValue()) + 1));
tableBTestCol.setCellValueFactory(cellData -> cellData.getValue().testCaseNameProperty());
tableBModCol.setCellValueFactory(cellData -> cellData.getValue().moduleNameProperty());
Thanks in advance for the help!
Upvotes: 0
Views: 1619
Reputation: 82451
The problem is that you're using the items list from tableA
to determine the indices in tableB
.
But:
DON'T USE THAT APPROACH!
I know many users upvoted the answer you used, but it has some serious issues. If there are multiple items in the items
list that are equal or even (as in your case) identical, the index will always be the first one found in the List
.
Instead use the index
property that TableCell
provides, which will also get rid of the inefficient search for the item in the list which has a worst case running time of O(n)
where n
is the size of the items
list...
The following is a small variation on @jewelsea's answer:
public class NumberTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {
private final int startNumber;
public NumberTableCellFactory(@NamedArg("startNumber") int startNumber) {
this.startNumber = startNumber;
}
public NumberTableCellFactory() {
this(1);
}
public static class NumberTableCell<S, T> extends TableCell<S, T> {
private final int startNumber;
public NumberTableCell(int startNumber) {
this.startNumber = startNumber;
}
@Override
public void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
setText(empty ? "" : Integer.toString(startNumber + getIndex()));
}
}
@Override
public TableCell<S, T> call(TableColumn<S, T> param) {
return new NumberTableCell<>(startNumber);
}
public static <T> TableColumn<T, Void> createNumberColumn(String text, int startNumber) {
TableColumn<T, Void> column = new TableColumn<>(text);
column.setSortable(false);
column.setEditable(false);
column.setCellFactory(new NumberTableCellFactory<>(startNumber));
return column;
}
}
This can be used like this:
tableA.getColumns().add(NumberTableCellFactory.createNumberColumn("#", 1));
tableB.getColumns().add(NumberTableCellFactory.createNumberColumn("#", 1));
Upvotes: 1