如何设置嵌套对象的阵列,其具有可变的大小作为源为JavaFX的TableView TableColumn来

时间:2019-02-01 23:43:00

标签: java javafx

我有一个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并填充相应的任务。因此,我需要找到一种方法来使任务(即不仅其标题为列,而且其点为单元格)在表视图中可用且可编辑。

1 个答案:

答案 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);
            }
        }

    });

}

我希望这对某些人有所帮助。问候。