JavaFx TableView - как оформить строки при запуске на основе данных? - PullRequest
1 голос
/ 30 января 2020

Нужна помощь. Я делаю концептуальный проект для проверки того, что я могу в итоге применить к гораздо большему проекту.

В этом проекте у меня есть простой элемент TableView с несколькими столбцами. Я настроил документ CSS, который будет стилизовать каждую строку таблицы в зависимости от состояния объекта. В этом случае класс Person имеет перечисление с различными возможными вариантами состояния. У меня есть фабрика строк, которая будет добавлять / удалять классы стилей для каждой строки. Это прекрасно работает, когда я нажимаю на каждую строку или сортирую таблицу, нажимая на заголовки столбцов таблицы. Он не применяет эти стили до тех пор, пока я это не сделаю, и не применяет их при запуске приложения, и я не могу понять, почему. Я попытался принудительно обновить refre sh или отсортировать предварительно встроенный код после инициализации таблицы и фабрику строк, но это не имеет значения, пока я не отсортирую строку вручную или не нажму на каждую строку .

Я ищу предложения о том, как заставить его обновляться в зависимости от статуса. Любая помощь приветствуется.

private ObservableList<Person> contacts;

    @FXML private BorderPane mainBorderPane;
    @FXML private TableView mainTableView;

    public void initialize() {
        contacts = FXCollections.observableArrayList();
        Person person = new Person("Mark", "Pug", "555-555-5555", Person.statusOptions.NO_STATUS);
        contacts.add(person);
        person = new Person("Cassy", "Garza", "222-222-2222", Person.statusOptions.AUTH_HOLD);
        contacts.add(person);
        person = new Person("Adrian", "Medula", "111-111-1111", Person.statusOptions.WORKING);
        contacts.add(person);
        person = new Person("Bob", "Fisher", "333-333-33330", Person.statusOptions.COMPLETE);
        contacts.add(person);
        person = new Person("Toy", "Yoda", "444-444-4444", Person.statusOptions.HOLD);
        contacts.add(person);
        person = new Person("Henry", "Ford", "666-666-6666", Person.statusOptions.READY);
        contacts.add(person);

        mainTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        mainTableView.setItems(contacts);

        mainTableView.setRowFactory(row -> new TableRow<Person>() {
            @Override
            public void updateItem(Person item, boolean empty) {
                super.updateItem(item, empty);

                if (item == null || empty) {
                    setStyle("");
                } else {
                    for (int i = 0; i < getChildren().size(); i++) {
                        if (! item.getPrevStatus().equals(item.getStatus().toString())) {
                            getStyleClass().removeAll("NO_STATUS", "AUTH_HOLD", "COMPLETE", "HOLD", "READY", "WORKING");
                            getStyleClass().add(item.getStatus().toString());
                        } else {
                            if (! getStyleClass().contains(item.getStatus().toString())) {
                                getStyleClass().removeAll("NO_STATUS", "AUTH_HOLD", "COMPLETE", "HOLD", "READY", "WORKING");
                                getStyleClass().add(item.getStatus().toString());
                            }
                        }
//                        System.out.println("Style class of " + item.getFirstName() + ": " + getStyleClass());
                    }
                }
            }
        });

    }

НАЙДЕНО РЕШЕНИЕ

private ObservableList<Person> contacts;

    @FXML private BorderPane mainBorderPane;
    @FXML private TableView mainTableView;

    public void initialize() {
        contacts = FXCollections.observableArrayList();
        Person person = new Person("Mark", "Pug", "555-555-5555", Person.statusOptions.NO_STATUS);
        contacts.add(person);
        person = new Person("Cassy", "Garza", "222-222-2222", Person.statusOptions.AUTH_HOLD);
        contacts.add(person);
        person = new Person("Adrian", "Medula", "111-111-1111", Person.statusOptions.WORKING);
        contacts.add(person);
        person = new Person("Bob", "Fisher", "333-333-33330", Person.statusOptions.COMPLETE);
        contacts.add(person);
        person = new Person("Toy", "Yoda", "444-444-4444", Person.statusOptions.HOLD);
        contacts.add(person);
        person = new Person("Henry", "Ford", "666-666-6666", Person.statusOptions.READY);
        contacts.add(person);

        mainTableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
        mainTableView.setItems(contacts);

        PseudoClass working = PseudoClass.getPseudoClass("WORKING");
        PseudoClass hold = PseudoClass.getPseudoClass("HOLD");
        PseudoClass auth_hold = PseudoClass.getPseudoClass("AUTH_HOLD");
        PseudoClass ready = PseudoClass.getPseudoClass("READY");
        PseudoClass complete = PseudoClass.getPseudoClass("COMPLETE");

        mainTableView.setRowFactory(tableView -> {
            TableRow<Person> row = new TableRow<>();
            Person selected = row.getItem();
            ChangeListener<String> changeListener = (obs, oldValue, newValue) -> {
                row.pseudoClassStateChanged(working, newValue.equalsIgnoreCase("WORKING"));
                row.pseudoClassStateChanged(hold, newValue.equalsIgnoreCase("HOLD"));
                row.pseudoClassStateChanged(auth_hold, newValue.equalsIgnoreCase("AUTH_HOLD"));
                row.pseudoClassStateChanged(ready, newValue.equalsIgnoreCase("READY"));
                row.pseudoClassStateChanged(complete, newValue.equalsIgnoreCase("COMPLETE"));
            };

            row.itemProperty().addListener((obs, prevPerson, currentPerson) -> {
                if (prevPerson != null) {
                    prevPerson.statusProperty().removeListener(changeListener);
                }
                if (currentPerson != null) {
                    currentPerson.statusProperty().addListener(changeListener);
                    row.pseudoClassStateChanged(working, currentPerson.getStatus().toString().equals("WORKING"));
                    row.pseudoClassStateChanged(hold, currentPerson.getStatus().toString().equals("HOLD"));
                    row.pseudoClassStateChanged(auth_hold, currentPerson.getStatus().toString().equals("AUTH_HOLD"));
                    row.pseudoClassStateChanged(ready, currentPerson.getStatus().toString().equals("READY"));
                    row.pseudoClassStateChanged(complete, currentPerson.getStatus().toString().equals("COMPLETE"));
                } else {
                    row.pseudoClassStateChanged(working, false);
                    row.pseudoClassStateChanged(hold, false);
                    row.pseudoClassStateChanged(auth_hold, false);
                    row.pseudoClassStateChanged(ready, false);
                    row.pseudoClassStateChanged(complete, false);
                }
            });
            return row;
        });
}

Хотя я нашел решение, которое работает, кажется, что это может быть немного длинным решением для этой проблемы. Я был бы признателен, если бы кто-нибудь знал, как сделать это более универсальным. Теоретически я бы хотел, чтобы клиент мог добавлять или удалять собственные стили статуса в клиенте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...