gpt4 book ai didi

JavaFX:使用 sum 函数对 TableView 进行分组

转载 作者:行者123 更新时间:2023-11-30 06:06:19 25 4
gpt4 key购买 nike

我有一个包含人员的可观察列表:

ObservableList<Person> persons = FXCollections.observableArrayList();

还有一个 Person 类:

public class Person {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty count = new SimpleIntegerProperty();
// ...
}

现在我可以将它们显示在这样的表格中:

TableView<Person> table = new TableView<>(persons);

TableColumn<Person, String> name = new TableColumn<>("Name");
name.setCellValueFactory(cell -> cell.getValue().nameProperty());

TableColumn<Person, Number> count = new TableColumn<>("Count");
count.setCellValueFactory(cell -> cell.getValue().countProperty());

table.getColumns().addAll(name, count);

如果有多个人同名,则会出现多次。

现在我只想在表中显示每个名称一次并将计数加在一起。

例如,在 SQL 中,它是按函数分组。

如何在 JavaFX 中执行此操作?

最佳答案

如果您需要一个在 Person 实例中的属性发生更改时更新表的解决方案,您可以执行以下操作:

ObservableList<Person> persons = FXCollections
.observableArrayList(p -> new Observable[] { p.nameProperty(), p.countProperty() });
ObservableList<String> uniqueNames = FXCollections.observableArrayList();

persons.addListener((Change<? extends Person> c) -> uniqueNames
.setAll(persons.stream().map(Person::getName).distinct().collect(Collectors.toList())));

TableView<String> table = new TableView<>(uniqueNames);
TableColumn<String, String> name = new TableColumn<>("Name");
name.setCellValueFactory(n -> new SimpleStringProperty(n.getValue()));
TableColumn<String, Number> count = new TableColumn<>("Count");
count.setCellValueFactory(n -> Bindings.createIntegerBinding(() -> persons.stream()
.filter(p -> p.getName().equals(n.getValue())).collect(Collectors.summingInt(Person::getCount)), persons));

此解决方案不是特别有效:如果基础列表中的数据发生更改(包括 Person 实例中的属性更改),所有可见单元格都将重新计算。这对于相当小的列表应该是可行的;但如果您有大量数据,您可能需要以更智能的方式处理列表中的更改 (persons.addListener(...))(这可能相当复杂)。

这是一个 SSCCE。它显示两个表:一个是包含完整人员列表的常规表;另一个是包含完整人员列表的常规表。另一个是上面设置的表格,显示“分组”列表。您可以通过填写文本字段(第二个需要是整数)并按“添加”将项目添加到主列表,或者通过选择项目并按删除来删除条目。 “完整表格”也是可编辑的,因此您可以测试更改现有值。

import java.util.stream.Collectors;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.converter.IntegerStringConverter;

public class GroupedTable extends Application {

@Override
public void start(Stage primaryStage) {
ObservableList<Person> persons = FXCollections
.observableArrayList(p -> new Observable[] { p.nameProperty(), p.countProperty() });
ObservableList<String> uniqueNames = FXCollections.observableArrayList();

persons.addListener((Change<? extends Person> c) -> uniqueNames
.setAll(persons.stream().map(Person::getName).distinct().collect(Collectors.toList())));

TableView<String> table = new TableView<>(uniqueNames);
TableColumn<String, String> name = new TableColumn<>("Name");
name.setCellValueFactory(n -> new SimpleStringProperty(n.getValue()));
TableColumn<String, Number> count = new TableColumn<>("Count");
count.setCellValueFactory(n -> Bindings.createIntegerBinding(() -> persons.stream()
.filter(p -> p.getName().equals(n.getValue())).collect(Collectors.summingInt(Person::getCount)), persons));

table.getColumns().add(name);
table.getColumns().add(count);

TableView<Person> fullTable = new TableView<>(persons);
fullTable.setEditable(true);
TableColumn<Person, String> allNamesCol = new TableColumn<>("Name");
TableColumn<Person, Integer> allCountsCol = new TableColumn<>("Count");
allNamesCol.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
allNamesCol.setCellFactory(TextFieldTableCell.forTableColumn());
allCountsCol.setCellValueFactory(cellData -> cellData.getValue().countProperty().asObject());
allCountsCol.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
fullTable.getColumns().add(allNamesCol);
fullTable.getColumns().add(allCountsCol);

TextField nameTF = new TextField();
TextField countTF = new TextField();
Button add = new Button("Add");
add.setOnAction(e -> {
persons.add(new Person(nameTF.getText(), Integer.parseInt(countTF.getText())));
nameTF.clear();
countTF.clear();
});
Button delete = new Button("Delete");
delete.setOnAction(e -> persons.remove(fullTable.getSelectionModel().getSelectedItem()));
delete.disableProperty().bind(fullTable.getSelectionModel().selectedItemProperty().isNull());

HBox controls = new HBox(5, new Label("Name:"), nameTF, new Label("Count:"), countTF, add, delete);
BorderPane root = new BorderPane(new HBox(5, fullTable, table));
root.setBottom(controls);

Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}

public static class Person {
private final StringProperty name = new SimpleStringProperty();
private final IntegerProperty count = new SimpleIntegerProperty();

public Person(String name, int count) {
setName(name);
setCount(count);
}


public final StringProperty nameProperty() {
return this.name;
}

public final String getName() {
return this.nameProperty().get();
}

public final void setName(final String name) {
this.nameProperty().set(name);
}

public final IntegerProperty countProperty() {
return this.count;
}

public final int getCount() {
return this.countProperty().get();
}

public final void setCount(final int count) {
this.countProperty().set(count);
}





}
}

屏幕截图序列:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

关于JavaFX:使用 sum 函数对 TableView 进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44287378/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com