Эффективная популяция вложенного JavaFX TreeView - PullRequest
0 голосов
/ 20 июня 2019

Моя категория класса может иметь parentCategory или быть корнем Category, а затем parentCategory устанавливается на null.Каждый Category может иметь подкатегории

Код для моего Category класса:

public class Category extends AbstractEntity<Integer> {

    @ManyToOne(cascade = { CascadeType.ALL, CascadeType.REMOVE })
    @JoinColumn(name = "parentCategory_id")
    private Category parentCategory;

    @OneToMany(mappedBy = "parentCategory", fetch = FetchType.EAGER)
    private Set<Category> subcategories;
    private String name;

    @OneToMany(cascade = { CascadeType.ALL, CascadeType.REMOVE }, fetch = FetchType.EAGER)
    private List<Item> items;

    public Category(String name) {
    this.subcategories = new HashSet<>();
    this.name = name;
    this.items = new ArrayList<>();
    }
...
}

Допустим, у меня есть много категорий с подкатегориями в моей базе данных.Я хочу показать иерархию категорий с javafx TreeView, но в общем случае без ручного заполнения TreeItem s.К сожалению, мне легко удается показать только прямые подкатегории корневых категорий

Код, который я тестировал:

    public void initialize(URL paramURL, ResourceBundle paramResourceBundle) {

    List<Category> categoriesAll = categoryDao.findAll();

    categories.getSelectionModel().selectedItemProperty()
        .addListener((ObservableValue<? extends Category> observable, Category oldValue, Category newValue) -> {

        });

    categories.getItems().addAll(FXCollections.observableArrayList(categoriesAll));

    TreeItem<String> rootNode = new TreeItem<>("Categories");
    rootNode.setExpanded(true);

    List<Category> superCategories = categoriesAll.stream().filter(category -> !category.hasParentCategory())
        .collect(Collectors.toList());

    Map<Category, TreeItem<String>> nodesMap = new HashMap<>();
    for (Category cat : superCategories) {
        TreeItem<String> leaf = new TreeItem<String>(cat.getName());
        addTreeItems(0, cat, nodesMap);
        rootNode.getChildren().add(leaf);
    }

    rootNode.getChildren().get(0).getChildren().add(nodesMap.entrySet().stream()
        .filter(entry -> entry.getKey().getName().equals("automotive")).findFirst().get().getValue());

    categoriesTree.setRoot(rootNode);

    }

    public void addTreeItems(int index, Category category, Map<Category, TreeItem<String>> nodesMap) {
    // System.out.println(index + " " + category.getName());
    nodesMap.put(category, new TreeItem<String>(category.getName()));
    List<TreeItem<String>> childrenCategories = category.getSubcategories().stream()
        .map(c -> new TreeItem<String>(c.getName())).collect(Collectors.toList());
    nodesMap.get(category).getChildren().addAll(childrenCategories);
    category.getSubcategories().forEach(cat -> addTreeItems(index + 1, cat, nodesMap));
    }

вывод (в компоненте treeView):

automotive
|_tires and rims
|_auto parts
|_cars
|_car workshop equipment

но это должно быть:

automotive
|_tires and rims
| |_winter tires
| |_summer tires
|_auto parts
|_cars
| |_audi
| | |_a4
| |_nissan
|  |_gtr
|_car workshop equipment

1 Ответ

0 голосов
/ 21 июня 2019

Итак, я решил свою проблему для вложенных иерархий данных.Решение этой проблемы - найти корневые категории, у которых нет родителя.

List<Category> superCategories = categoriesAll.stream().filter(category -> !category.hasParentCategory())
        .collect(Collectors.toList());

Тогда каждый superCategory рассматривается как сам корень:

TreeItem<String> rootNode = new TreeItem<>("Categories");
rootNode.setExpanded(true);
superCategories.forEach(superCategory -> Utils.buildRoot(superCategory, rootNode));

buildRoot метод:

public static void buildRoot(Category category, TreeItem<String> root) {
    if (category.hasParentCategory()) {
        TreeItem<String> found = find(root, category.getParentCategory().getName());
        if (found != null) {
            found.getChildren().add(new TreeItem<String>(category.getName()));
        }
    } else {
        root.getChildren().add(new TreeItem<String>(category.getName()));
    }
    category.getSubcategories().forEach(subcategory -> buildRoot(subcategory, root));
}

find метод:

private static TreeItem<String> find(TreeItem<String> root, String value) {
    if (root != null) {
        if (root.getValue().equals(value)) {
            return root;
        }
        ObservableList<TreeItem<String>> children = root.getChildren();
        if (children != null) {
            for (TreeItem<String> child : children) {
                if (child.getValue().equals(value)) {
                    return child;
                }
                return find(child, value);
            }
        }
    }
    return null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...