问题
I hit a wall when i retrieve data from database.I managed to get column names into my table which is ok and works as it shoud.
Bud when i try to add rows i find that no data has been added into my tableview,im trying to add rows from array of string which represent single row.I have no idea how many columns etc will user ask for with his query and how big table is so i cant create row object and all the properties which represent each column.
Question is how do i populate my tableview with rows that i have retrieved successfully from database in format of String[] each row.
private ObservableList<String[]> dataRows=FXCollections.observableArrayList();
Retrieve rows..(Works debug prints all data correct)
while (this.resultSet.next()) {
for (int i = 1; i < this.resultSetMd.getColumnCount() + 1; i++) {
rows.add(resultSet.getString(i));
}
dataRows.add(rows.toArray(new String[rows.size()]));
rows.removeAll(rows);
//TODO DELETE row debugger debug
dataRows.forEach((r)->{
System.out.println("Row---------");
for(String s:r){
System.out.println("Debug row value- "+s);
}
});
Adding into table
private void populateTable() {
dpcontroller.tableView.getColumns().addAll(columns); //columns work
dpcontroller.tableView.setItems(dataRows); //no data entered
}
EDIT- WORKING CODE AFTER ANSWER
Working code for people who will encounter same problem as i did.Only needed factory was really ValueFactory.Here are my two methods
private void populateTable() {
for (int rowNumber = 0; rowNumber < dataRows.size(); rowNumber++) {
for (TableColumn tc : columns) {
tc.setCellValueFactory(new ValueFactory(columns.indexOf(tc),rowNumber));
dpcontroller.tableView.getColumns().add(tc);
}
}
dpcontroller.tableView.setItems(dataRows);
}
private class ValueFactory implements Callback {
private int rowNumber;
private int columnNumber;
public ValueFactory(int columnNumber, int rowNumber) {
this.columnNumber = columnNumber;
this.rowNumber = rowNumber;
}
@Override
public Object call(Object o) {
SimpleStringProperty stringProperty = new SimpleStringProperty(dataRows.get(rowNumber)[columnNumber]);
return stringProperty;
}
}
回答1:
You will need to set some Factories, if you want to get this working.
In the example below, I do not get elements from a SQL server, but I believe will be enough for you to see how to accomplish this.
Note that it just fill with sequential values, but still it will have as many columns as the header
in the method createTable()
.
package table;
import com.sun.javafx.collections.ObservableListWrapper;
import javafx.application.Application;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.util.Collections;
import java.util.List;
public class TableDemo extends Application {
private int rowIndex = 0;
private int elementIndex = 0;
final TableView tableView = new TableView();
ObservableList<String[]> dataRows = FXCollections.observableArrayList();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
FlowPane pane = new FlowPane();
tableView.setRowFactory(new CountingRowFactory());
createTable();
pane.getChildren().add(tableView);
List items = Collections.singletonList(new Object());
tableView.setItems(dataRows);
stage.setScene(new Scene(pane));
stage.show();
}
private TableColumn createColumn(String header) {
TableColumn column = new TableColumn(header);
column.setCellFactory(new CellFactory());
column.setCellValueFactory(new CountingValueFactory());
return column;
}
private static class CellFactory implements Callback {
@Override
public Object call(Object column) {
return new TableCell() {
@Override
protected void updateItem(Object o, boolean b) {
super.updateItem(o, b);
setText(String.valueOf(o));
}
};
}
}
private class CountingRowFactory implements Callback {
@Override
public Object call(Object o) {
TableRow row = new TableRow();
row.setUserData(rowIndex);
rowIndex++;
return row;
}
}
private class CountingValueFactory implements Callback {
@Override
public Object call(Object o) {
SimpleIntegerProperty property = new SimpleIntegerProperty(elementIndex);
elementIndex++;
return property;
}
}
public void createTable(){
String[] header = {"a","b","c","d","e","f","g","h"};
for(String s: header)
tableView.getColumns().add(createColumn(s));
for(int i=0;i<30;i++){
String[] temp = header;
for(int j=0;j<temp.length;j++)
temp[j] += + i ;
dataRows.add(temp);
}
}
}
来源:https://stackoverflow.com/questions/24436196/populating-tableview-with-data-from-database-failed-to-set-rows