如何在JavaFX Thread之外更新TableView项

Asa*_*s77 3 java multithreading javafx exception

我有一个列表用户朋友的表视图,我需要每隔5秒用我从数据库中检索的数据更新它.

这是我使用的代码:

Main.java
   private List<Friend> userFriends;
Run Code Online (Sandbox Code Playgroud)

fx控制器:

    ObservableList<FriendWrapper> friendList = FXCollections.observableList(
    new ArrayList<FriendWrapper>());

private void updateFriendList() {
    new Thread(new Runnable() {
        public void run() {
            while (Params.loggedUser != null) {
                Main.setUserFriends(Params.dao.listUserFriends(Params.loggedUser));
                friendList.clear();
                for (Friend friend : Main.getUserFriends()) {
                    friendList.add(new FriendWrapper(friend.getFriendName(), friend.getOnline(), friend.getFriendId(), friend.getWelcomeMessage()));
                }
                Params.dao.updateOnlineStatus(Params.loggedUser, 3);
                try {
                    Thread.sleep(1000 * 5); 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }, "updateFriendList").start();
}
Run Code Online (Sandbox Code Playgroud)

Friend是数据库模型.FriendWrapper是用于表行的对象.

但是我IllegalStateException: Not on FX application thread上线了friendList.clear();

如何从后台运行的线程更改TableView的项目?

eck*_*kig 10

Platform.runLater()你可能应该使用这个Task类,而不是快速入侵:

protected class LoadFriendsTask extends Task<List<FriendWrapper>>
{

    @Override
    protected List<FriendWrapper> call() throws Exception {

        List<Friend> database = new ArrayList<>(); //TODO fetch from DB
        List<FriendWrapper> result = new ArrayList<>();
        //TODO fill from database in result
        return result;
    }

    @Override
    protected void succeeded() {
        getTableView().getItems().setAll(getValue());
    }

}
Run Code Online (Sandbox Code Playgroud)

您可以将其作为一个启动Thread,例如:

new Thread(new LoadFriendsTask()).start()
Run Code Online (Sandbox Code Playgroud)

供进一步参考: