javafx treeTableView пометить дочерние строки красным - PullRequest
0 голосов
/ 07 августа 2020

У меня проблема с выделением цвета строки treeTableView. Маркировка строки «первого уровня» не проблема и код работает. В методе updateItem -> item я могу получить доступ к свойствам фруктов первой строки.

enter image description here

But I dont know how to access deeper in "second level" of treeTableView and color the rows?

введите описание изображения здесь

Ниже мой код. Заранее благодарим за любую помощь.

import javafx.fxml.Initializable;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ResourceBundle;

public class ControllerWindowTest implements Initializable {

    public TreeTableView<Fruit> treeTableView;
    ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
            new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
            new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
            new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        createTreeTable();
        fillTreeTable();
    }

    public void buttonMarkFruits(){
        treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
            @Override
            protected void updateItem(Fruit item, boolean empty) {
                super.updateItem(item, empty);
                //Fruit item - is here "first level" of treeTableView(TreeItem: apples, plums).
                // How to go deeper to second level to access children of apples, plums -
                // where I can check color of fruit and mark treeTable row red??
                if (item == null) {
                    setStyle(null);
                } else if (item.getColor().equals("red")){
                    setStyle("-fx-background-color: tomato;");
                } else {
                    setStyle(null);
                }
            }
        });
    }

    public void createTreeTable(){
        TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
        TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
        TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");

        colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
        colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
        colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));

        treeTableView.getColumns().addAll(colName, colShape, colColor);
    }

    public void fillTreeTable(){
        TreeItem root = new TreeItem(new Fruit("", "", ""));
        TreeItem apples = new TreeItem(new Fruit("Apple", "", ""));
        TreeItem plums = new TreeItem(new Fruit("Plum", "", ""));
        for (Fruit fruit: fruitsList){
            if (fruit.getName().equals("Apple")){
                apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
            }
            if (fruit.getName().equals("Plum")){
                plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
            }
        }
        root.getChildren().addAll(apples,plums);
        root.setExpanded(true);
        treeTableView.setRoot(root);
        treeTableView.setShowRoot(false);
    }
}

1 Ответ

3 голосов
/ 07 августа 2020

Проблема не в том, что строки не находятся на «первом уровне» дерева; это то, что метод updateItem() строки таблицы не вызывается при нажатии кнопки.

Основная идея c состоит в том, чтобы иметь какое-то наблюдаемое свойство, которое наблюдают строки, чтобы они обновляли стили как необходимо. Используйте эту реализацию строки независимо от того, нажата кнопка или нет (поэтому установите фабрику строк в методе initialize()), и просто обновите свойство при нажатии кнопки. Минимальная реализация этого будет выглядеть так:

public class ControllerWindowTest implements Initializable {

    @FXML
    private TreeTableView<Fruit> treeTableView;
    
    private BooleanProperty redFruitsMarked = new SimpleBooleanProperty(false);
    
    ArrayList<Fruit> fruitsList = new ArrayList<>(Arrays.asList(
            new Fruit("Apple", "round", "green"), new Fruit("Apple", "round", "red"),
            new Fruit("Apple", "round", "yellow"), new Fruit("Plum", "round", "yellow"),
            new Fruit("Plum", "round", "navy blue"), new Fruit("Plum", "oval", "red")));

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        createTreeTable();
        fillTreeTable();
        treeTableView.setRowFactory(ttv -> new TreeTableRow<Fruit>(){
            
            {
                redFruitsMarked.addListener((obs, wereMarked, areNowMarked) -> updateStyles());
            }
            
            @Override
            protected void updateItem(Fruit item, boolean empty) {
                super.updateItem(item, empty);
                updateStyles();
            }
            
            private void updateStyles() {
                                
                if (getItem() == null || (! redFruitsMarked.get())) {
                    setStyle(null);
                } else if (getItem().getColor().equals("red")){
                    setStyle("-fx-background-color: tomato;");
                } else {
                    setStyle(null);
                }
            }
        });
    }

    @FXML
    private void buttonMarkWires(){
        redFruitsMarked.set(true);
    }

    public void createTreeTable(){
        TreeTableColumn<Fruit, String> colName = new TreeTableColumn<>("Fruit");
        TreeTableColumn<Fruit, String> colShape = new TreeTableColumn<>("Shape");
        TreeTableColumn<Fruit, String> colColor = new TreeTableColumn<>("Color");

        colName.setCellValueFactory(new TreeItemPropertyValueFactory<>("name"));
        colShape.setCellValueFactory(new TreeItemPropertyValueFactory<>("shape"));
        colColor.setCellValueFactory(new TreeItemPropertyValueFactory<>("color"));

        treeTableView.getColumns().addAll(colName, colShape, colColor);
    }

    public void fillTreeTable(){
        TreeItem<Fruit> root = new TreeItem<>(new Fruit("", "", ""));
        TreeItem<Fruit> apples = new TreeItem<>(new Fruit("Apple", "", ""));
        TreeItem<Fruit> plums = new TreeItem<>(new Fruit("Plum", "", ""));
        for (Fruit fruit: fruitsList){
            if (fruit.getName().equals("Apple")){
                apples.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
            }
            if (fruit.getName().equals("Plum")){
                plums.getChildren().add(new TreeItem<>(new Fruit("", fruit.getShape(), fruit.getColor())));
            }
        }
        root.getChildren().addAll(apples,plums);
        root.setExpanded(true);
        treeTableView.setRoot(root);
        treeTableView.setShowRoot(false);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...