Why your code doesn't work
The cellValueFactory is a function that maps the item representing each row to the value that should be displayed in the cell for that row and that column. This function is represented as a Callback. PropertyValueFactory is a convenience implementation that is equivalent either to
cellData -> cellData.getValue().xxxProperty()
or
cellData -> new ReadOnlyObjectWrapper(cellData.getValue().getXxx())
where xxx is the name specified in the PropertyValueFactory and cellData is a CellDataFeatures.
Improving your code (for clarity as to what is happening and to help fix it)
Your code would be much improved if you didn't use raw types. I.e. you should do
TableView<ObservableList<String>> table = new TableView<>();
private static ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();
TableColumn<ObservableList<String>, String> firstNameCol = new TableColumn<>("Username");
Here you actually specify the types represented by the TableView and TableColumn. Each row is represented by an ObservableList<String> and the value in each cell in the column is represented by a String.
Now it should be clear why your code doesn't work. The PropertyValueFactory gets the value for a row, in effect
ObservableList<String> row = ... ;
and tries to call either
row.UsernameProperty()
or
row.getUsername()
to get the value for the column. Neither of those methods exist.
Fixing the problem
So you should just set the cellValueFactory to something that looks up the first element of the list representing the row:
firstNameCol.setCellValueFactory(cellData -> {
ObservableList<String> rowValue = cellData.getValue();
String cellValue = rowValue.get(0);
return new ReadOnlyStringWrapper(cellValue);
});