Проблема с пользовательским setCellFactory TreeTableColumn, не обновляющим пользовательский интерфейс немедленно - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть TreeTableColumn<ProjectView, ComboBox> treeTableColumn. Я установил пользовательскую фабрику ячеек, где я устанавливаю ширину ComboBox равной ширине самого столбца. Сам пользовательский интерфейс не будет обновляться, пока я не начну прокручивать вверх и вниз TreeTableView.

Надеемся, что приведенный ниже код - это весь соответствующий код.

TreeTableColumn<ProjectView, ComboBox> treeTableColumn = new TreeTableColumn<>("Description");
treeTableColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("comboBox"));
treeTableColumn.setCellFactory(col -> {
            TreeTableCell<ProjectView, ComboBox> cell = new TreeTableCell<ProjectView, ComboBox>() {
                @Override
                public void updateItem(ComboBox item, boolean empty) {
                    super.updateItem(item, empty);
                    ComboBox newItem = new ComboBox();
                    newItem.setMinWidth(this.getWidth());                   
                    this.setGraphic(newItem);                   
                }

            };
            return cell;
        });

treeTableView.getColumns().add(treeTableColumn);

Кроме того, у меня есть этот метод, который изменит данные в табличном представлении. Этот метод вызывается, когда пользователь изменяет выбранный элемент в раскрывающемся меню:

...
TreeItem root = new TreeItem();
projectList.stream().filter((p) -> (p != null)).forEachOrdered((ProjectView p) -> {
            TreeItem project = new TreeItem(p);
            root.getChildren().add(project);
        });
treeTableView.setRoot(root);
...

Как видите, это очень тупая реализация фабрики значений ячеек. Я удалил как можно больше лишнего кода, чтобы попытаться определить проблему, но даже с этой реализацией все отображаемые ComboBox имеют неправильную ширину. Как только вы начали прокручивать вверх и вниз TreeTableView, ComboBox внутри ячеек начинает отображаться правильно, используя правильную ширину.

Я видел несколько постов, посвященных схожим проблемам, но ни одно из их исправлений не работает. Я попытался вызвать refre sh, я попытался переключить видимость col и представления таблицы. Я гарантировал, что супер метод вызывается, и setGraphics всегда устанавливается в методе обновления, который я переопределяю в методе setCellFactory. Я уверен, что что-то упустил, но я просто не вижу этого. Любая помощь будет оценена.

Редактировать:

Вот небольшой пример, который воспроизводит эту проблему. Должен отметить, что после публикации я обнаружил, что если я обертываю обновление в потоке Platform.runLater, оно работает, но это не похоже на правильный способ сделать это.

 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javafxapplication;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.scene.control.cell.TreeItemPropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


public class JavaFXApplication extends Application {

    @Override
    public void start(Stage primaryStage) {

        TreeTableView treeTableView = new TreeTableView();

        treeTableView.getColumns().clear();

        TreeTableColumn<ProjectView, ComboBox> treeTableColumn = new TreeTableColumn<>("Dependencies");

        treeTableColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>("comboBox"));

        treeTableColumn.setCellFactory(col -> {
            TreeTableCell<ProjectView, ComboBox> cell = new TreeTableCell<ProjectView, ComboBox>() {
                @Override
                public void updateItem(ComboBox item, boolean empty) {
                    super.updateItem(item, empty);
                    ComboBox newItem = new ComboBox();
                    newItem.getItems().add("Test");
                    newItem.setMinWidth(this.getWidth());
                    this.setGraphic(newItem);
                }

            };
            return cell;
        });

        List<ProjectView> projectList = new ArrayList<>();

        for (int i = 0; i < 25; i++) {
            projectList.add(new ProjectView());
        }

        treeTableView.getColumns().add(treeTableColumn);

        TreeItem treeRoot = new TreeItem();
        projectList.stream().filter((p) -> (p != null)).forEachOrdered((ProjectView p) -> {
            TreeItem project = new TreeItem(p);
            treeRoot.getChildren().add(project);
        });
        treeTableView.setShowRoot(false);
        treeTableView.setRoot(treeRoot);

        StackPane root = new StackPane();

        root.getChildren().add(treeTableView);
        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public static class ProjectView {

        public ProjectView() {
        }

        public ComboBox getComboBox() {
            ComboBox cb = new ComboBox();
            cb.getItems().add("Test");
            return cb;
        }
    }

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