本文介绍了TableView中的延迟加载项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在实现一个自定义TableCellFactory来从数据库异步加载数据。查询数据库不应该阻止UI线程。I am implementing a custom TableCellFactory to load data asynchronously from a database. Querying the db should not block the UI thread.public abstract class AsynchronousTableCellFactory<E, T> implements Callback<TableColumn<E, T>, TableCell<E, T>> {private static final Executor exe1 = Executors.newFixedThreadPool(2);private static final Executor exe2 = Executors.newFixedThreadPool(2);@Overridepublic TableCell<E, T> call(final TableColumn<E, T> param) { final TableCell<E, T> cell = new TableCell<E, T>() { @Override public void updateItem(final T item, final boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); } else { setText("Thinking.."); // do this later some time, we need to finish here FAST exe1.execute(() -> { if (getTableRow() != null) { final Service<T> service = new Service<T>() { @Override protected Task<T> createTask() { return getTask((E) getTableRow().getItem()); } }; service.setExecutor(exe2); service.setOnSucceeded(e -> { if (e.getSource().getValue() == null) { setText("n/a"); } else { setText(e.getSource().getValue().toString()); } }); service.setOnFailed(e -> { final Throwable t = e.getSource().getException(); setText(t.getLocalizedMessage()); }); service.start(); } }); } } }; return cell;}protected abstract Task<T> getTask(E rowDataItem);}它大部分时间都在工作,但并非总是如此。一个奇怪的事情是 T item 总是 null 。 在哪种情况下我可以指望 T item null ? It is working most of the time, but not always. One strange thing about it is that T item is always null.In which cases can I expect T item to be null?相应的表格代码:public class OriginsTableViewController implements Initializable {@FXMLprivate TableView<LazyLoadingOriginWrapper> table;@FXMLprivate TableColumn<LazyLoadingOriginWrapper, String> cSampleName;@Overridepublic void initialize(final URL location, final ResourceBundle resources) { cSampleName.setCellFactory(new AsynchronousOriginTableCellFactory<>(e -> e.getSampleName()));} 编辑: 找到更好的方法此处。推荐答案请注意 TableCell 是可重用的!这意味着任何项目都可以分配给任何单元格(这是 updateItem 方法的用途)。当您的完成处理程序直接设置 TableCell 的文本时,您当前的代码可能会出现很多问题。Be aware that a TableCell is reusable! this means any item can be assigned to any cell (that's what the updateItem method is for). Your current code can provide a lot of problems as your completion handlers set a TableCell's text directly.简单的解决方案是将结果包装在 LazyLoadingOriginWrapper 中的 ObservableValue 中,并在 CellValueFactory中使用它而不是创建自己的 TableCell 。 ObservableValue 的更新将在 TableView 中保持不变(请确保修改 ObservableValue 在'fx-application'线程上!)。例如An easy solution is wrapping the result in a ObservableValue inside your LazyLoadingOriginWrapper and use that in a CellValueFactory rather than creating your own TableCell. Updates of the ObservableValue will be vissible inside the TableView (make sure you modify the ObservableValue on the 'fx-application' thread!). e.g.public static class LazyLoadingOriginWrapper{ // params are 'bean', 'id/name', 'default value' ObservableStringValue name = new SimpleStringProperty(this, "name", "thinking..."); public ObservableStringValue nameProperty() { return name; } public void setName(String value) { Platform.runLater(() -> name.set(value)); } // add your logic for asynchronious loading here and update the above ObservableValue instead. Make sure you trigger it manually!}@Overridepublic void initialize(final URL location, final ResourceBundle resources) { cSampleName.setCellValueFactory(C -> C.getValue().nameProperty());} 这篇关于TableView中的延迟加载项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 10-24 16:49