我有一个ClassTestEvaluation类型的对象。它拥有Task类型的ArrayList。该数组可以具有任意数量的任务,并且是不可预测的。我想建立一个表视图,将显示在列给定的任务,使用户可以输入点。
我的问题是我不知道如何设置可变长度的数组,它是另一个对象作为源为我的表视图的一部分。我不能用简单的成员task1,task2等构建像ClassTestEvaluationItem这样的包装器,因为任务的数量是不固定的。因此,我的问题是什么做我必须做的正确设置propertyValueFactories的任务栏?
我已经关注了很多教程,例如:https://docs.oracle.com/javafx/2/ui_controls/table-view.htm。一般来说,遵循它们并使它们工作是没有问题的。但是它们只处理简单的(平面)数据。
TableView<ClassTestEvaluation> table = new TableView<>();
TableColumn colFirstName = new TableColumn("Vorname");
colFirstName.setCellValueFactory(new PropertyValueFactory<ClassTestEvaluation, String>("firstName");
TableColumn colLastName = new TableColumn("Nachname");
colLastName.setCellValueFactory(new PropertyValueFactory<ClassTestEvaluation, String>("lastName");
table.getColumns().addAll(colFirstName, colLastName);
ArrayList<Task> tasks = classTestEvaluation.getTasks();
for(Task t : tasks) {
TableColumn colTask = new TableColumn(t.getTitle());
table.getColumns().add(colTask);
}
正如你可以看到它不是很难的colFirstName和colLastName集PropertyValueFactory。但是,对于那些在 长度,并存储在一个数组中,该数组本身是 ClassTestEvaluation对象?
根据任务的classtest得到了数,我希望我的表视图看起来像:
名字|姓氏|任务1 |任务2 | ...
我希望有人能在这里帮助我,因为我不明白。非常感谢!
编辑1:
为了使我的数据源更加清楚,这是我的ClassTestEvaluation和Task类的相关结构:
public class ClassTestEvaluation{
// ... more members ...
ArrayList<Task> tasks = ArrayList<>();
public ArrayList<Task> getTasks(){
return this.tasks;
}
// ...more methods...
}
public class Task{
private int id;
private int idClassTestEvaluation;
private Double points;
private String title;
public String getTitle(){
return this.title;
}
public Double getPoints(){ // This methods needs to be connected as data source for tasks cells.
return this.points;
}
// ...more methods...
}
在数据来自SQLite数据库,其中每个任务经由外键到特定ClassTestEvaluation连接。必要时,将构造一个特定的ClassTestEvaluation并填充相应的任务。因此,我需要找到一种方法来使任务(即不仅其标题为列,而且其点为单元格)在表视图中可用且可编辑。
答案 0 :(得分:0)
好吧,我实际上找到了自己的问题的解决方案,并认为其他人可能对此感兴趣。回想一下:我的问题是我不知道如何用可变长度的数组来构建列,而可变长度的数组是另一个项(组成)的一部分。
我需要了解的是如何分别使用cellValueFactory,cellFactory和onEditCommit与回调或lambda结合使用以获得所需的结果。这花了我一段时间。
这是我要做的:
private void createTableColumnsForTasks(ClassTestEvaluation cte) {
int resultCounter = 1;
// For each given task in ClassTestEvaluation...
for (Task t : cte.getTasks()) {
// ...create a column for the corresponding points reached (0 in the beginning).
TableColumn<ClassTestEvaluationRow, Double> colResult = new TableColumn<>("A" + resultCounter + " (" + t.getPoints() + ")");
resultCounter++;
// Make the column editable.
colResult.setEditable(true);
// Define how the values in the task columns will be set.
colResult.setCellValueFactory((TableColumn.CellDataFeatures<ClassTestEvaluationRow, Double> row) -> {
ClassTestEvaluationRow cter = row.getValue();
for(Result r : cter.getResults()) {
if(r.getIdTask() == t.getId()) {
ObservableValue<Double> obsResult = new SimpleObjectProperty<Double>(r.getPoints());
return obsResult;
}
}
return null;
});
// Create combo box to choose points from for each given task and result.
createTableColumnComboBoxForResultEditing(colResult, t);
// Create method to store edited data in selected ClassTestEvaluationRow.
createOnEditCommitMethods(colResult, t);
((EvaluatorUI) this.getView()).getTableView().getColumns().add(colResult);
}
}
private void createTableColumnComboBoxForResultEditing(TableColumn<ClassTestEvaluationRow, Double> colResult, Task t) {
ArrayList<Double> cbPoints = new ArrayList<>();
for(double i = 0.0; i <= t.getPoints(); i = i+0.5) {
cbPoints.add(i);
}
ObservableList<Double> obsPoints = FXCollections.observableArrayList(cbPoints);
colResult.setCellFactory(ComboBoxTableCell.<ClassTestEvaluationRow, Double>forTableColumn(obsPoints));
}
private void createOnEditCommitMethods(TableColumn<ClassTestEvaluationRow, Double> colResult, Task t) {
colResult.setOnEditCommit((CellEditEvent<ClassTestEvaluationRow, Double> event) -> {
TablePosition<ClassTestEvaluationRow, Double> pos = event.getTablePosition();
Double newValue = event.getNewValue();
int row = pos.getRow();
ClassTestEvaluationRow cter = (ClassTestEvaluationRow) event.getTableView().getItems().get(row);
for(Result result : cter.getResults()) {
if(result.getIdTask() == t.getId()){
result.setPoints(newValue);
classTestEvaluationsService.updateResult(cter.getClassTestEvaluation(), result);
}
}
});
}
我希望这对某些人有所帮助。问候。