У меня есть 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;
}
}
}