java - 在没有阻塞 UI 线程的情况下更新 tableview javafx
问题描述
每次更新用户界面时,我都会不断地从我的数据库(每 2 秒)中提取数据(大约 10-15 个项目)。
我尝试使用预定服务、线程和任务来更新 UI,但它总是冻结。
我也尝试过使用可观察列表作为 tableview 并且只是 removeAll() 和 addAll() (根据JavaFX 2.1 TableView refresh items)
有没有办法避免阻塞ui线程?
编辑:
如果我删除 tableViewConcern.getItems().setAll(service.getValue()); 它不会滞后 部分,但是一旦我开始向数据库中添加东西,它就会变得越来越慢(直到它停止)。
在我的ActiveConcernService (ScheduledService) 中,它只是从数据库中获取数据。
public class ActiveConcernService extends ScheduledService<ObservableList<Concern>> {
private UserAccount currentUser;
public ActiveConcernService(UserAccount currentUser) {
this.currentUser = currentUser;
}
public final ObservableList<Concern> getConcerns() {
ObservableList<Concern> concerns;
if(RoleService.getInstance().getById(currentUser.getRoleId()).getTitle().equals(Role.DefaultRole.ADMIN.getRole())){
concerns = FXCollections.observableList(ConcernService.getInstance().allNotDone());
} else {
concerns = FXCollections.observableList(ConcernService.getInstance().allByUser(currentUser));
}
return concerns; //gets the data from database base on the user role
}
@Override
protected Task<ObservableList<Concern>> createTask() {
return new Task<ObservableList<Concern>>() {
@Override
protected ObservableList<Concern> call() {
return getConcerns();
}
};
}
在我的控制器中,这就是我初始化表列标题的方式,而 scheduleservice 确实是使用表的唯一两个部分。
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
// Initializes other ui elements (textfield, button, choicebox, etc)
initializeConcernTable();
ActiveConcernService service = new ActiveConcernService(currentUser);
service.setPeriod(Duration.millis(2000));
service.setOnSucceeded((t) -> {
tableViewConcern.getItems().setAll(service.getValue()); //Everytime this executes it lags
});
service.start();
}
private void initializeConcernTable() {
TableColumn<Concern, String> clientColumn = new TableColumn<>(Concern.NAME_HEADER);
clientColumn.setCellValueFactory(param -> param.getValue().getClientNameProperty());
clientColumn.setMinWidth(125);
clientColumn.setSortable(false);
TableColumn<Concern, String> remarkColumn = new TableColumn<>(Concern.REMARK_HEADER);
remarkColumn.setCellValueFactory(param -> param.getValue().getRemarkProperty());
remarkColumn.setMinWidth(175);
remarkColumn.setSortable(false);
TableColumn<Concern, String> categoryColumn = new TableColumn<>(Concern.CATEGORY_HEADER);
categoryColumn.setCellValueFactory(param -> new SimpleStringProperty(
CategoryService.getInstance().getById(param.getValue().getCatergoryId()).getTitle()));
categoryColumn.setMinWidth(150);
categoryColumn.setSortable(false);
TableColumn<Concern, String> assignToColumn = new TableColumn<>(Concern.EMPLOYEE_HEADER);
assignToColumn.setCellValueFactory(param -> new SimpleStringProperty(
UserAccountService.getInstance().getById(param.getValue().getUserAccountId()).getName()));
assignToColumn.setMinWidth(125);
assignToColumn.setSortable(false);
TableColumn<Concern, String> numberColumn = new TableColumn<>(Concern.NUMBER_HEADER);
numberColumn.setCellValueFactory(param -> new ReadOnlyObjectWrapper<String>(param.getValue().getNumber() + ""));
numberColumn.setSortable(false);
TableColumn<Concern, String> dateColumn = new TableColumn<>(Concern.DATE_HEADER);
dateColumn.setCellValueFactory(param -> new SimpleStringProperty(
param.getValue().getIssuedOn().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))));
dateColumn.setPrefWidth(150);
dateColumn.setSortable(false);
tableViewConcern.getColumns().addAll(numberColumn, assignToColumn, clientColumn, categoryColumn, remarkColumn,
dateColumn);
}
解决方案
问题是每次表更新时都会调用数据库。
TableColumn<Concern, String> categoryColumn = new TableColumn<>(Concern.CATEGORY_HEADER);
categoryColumn.setCellValueFactory(param -> new SimpleStringProperty(
CategoryService.getInstance().getById(param.getValue().getCatergoryId()).getTitle())); //This part was the one that was making it lag
categoryColumn.setMinWidth(150);
categoryColumn.setSortable(false);
TableColumn<Concern, String> assignToColumn = new TableColumn<>(Concern.EMPLOYEE_HEADER);
assignToColumn.setCellValueFactory(param -> new SimpleStringProperty(
UserAccountService.getInstance().getById(param.getValue().getUserAccountId()).getName())) ; //This part was the one that was making it lag
assignToColumn.setMinWidth(125);
assignToColumn.setSortable(false);
我通过制作本地副本而不是每次都调用数据库来解决它
谢谢费边
推荐阅读
- python-3.x - 在 Python 中不使用返回值是不好的做法/危险吗?
- kubernetes - 使用 aws elb 作为控制平面端点时,kubeadm init 失败
- sql - 如何使用 JOIN 在 Access 中指定应从中删除记录的表?
- reactjs - 如何在引导下拉列表中显示多列
- javascript - selectedHandlers 不是 nodejs 中的函数错误
- javascript - 将 json 对象数据与表头一起附加到表中
- python - 搜索字典的功能
- c# - 如何将两个 linq 查询组合在一起以优化性能
- reactjs - 只需添加 useState 钩子语句导致组件重新渲染
- phpstorm - PhpStorm:我在 Blade 模板文件中有这个连线问题,不知道如何描述