java - ListView.setItems() 如何工作?

标签 java listview javafx

我有一个实现可初始化的 Controller 类,它看起来像这样:

public class FileSharingController implements Initializable {

private ObservableList<User> UsersListData;
@FXML
private ListView<User> UsersList;

@Override
public void initialize(URL location, ResourceBundle resources) {
final Task<Void> UsersListTask=new Task<Void>(){
            protected Void call() throws SQLException{
                DatabaseManager DB=new DatabaseManager();
                UsersListData.clear();
                UsersListData.addAll(DB.returnUsers());
                UsersList.setItems(UsersListData);
                return null;}};
        new Thread(UsersListTask).start();

}

但是我的 ListView 没有更新!我该怎么办?!

最佳答案

final Task<List<User>> UsersListTask = new Task<List<User>>() {
    protected List<User> call() throws SQLException {
        return new DatabaseManager().returnUsers();
    }
};

UsersListTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
    @Override public void handle(WorkerStateEvent event) {
        UsersList.setItems(
            FXCollections.observableArrayList(UsersListTask.getValue())
        );
    }
});

UsersListTask.setOnFailed(new EventHandler<WorkerStateEvent>() {
    @Override public void handle(WorkerStateEvent event) {
        System.out.println("ERROR: " + UsersListTask.getException());
    }
});

new Thread(UsersListTask).start();

如果使用 java 8:

UsersListTask.setOnSucceeded(event ->
    UsersList.setItems(
        FXCollections.observableArrayList(UsersListTask.getValue())
    )
);

UsersListTask.setOnFailed(event ->
    System.out.println("ERROR: " + UsersListTask.getException())
);

请注意,您永远不应该更新支持 ListView 的 JavaFX 线程的项目列表,因为它可能会触发场景图更新,从而可能产生意外后果。通过在 setOnSucceeded 方法中执行对项目列表的更新,JavaFX 框架任务实现将在内部确保您的更新发生在 JavaFX 应用程序线程上。

示例代码

这是一个可执行示例,您可以尝试并与您的实现进行比较。

示例输出

listview

list.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane fx:controller="ListController" id="StackPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml">
  <children>
    <ListView fx:id="usersList"/>
  </children>
</StackPane>

ListApplication.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.*;
import javafx.stage.Stage;

public class ListApplication extends Application {
    @Override public void start(Stage stage) throws Exception{
        Parent layout = FXMLLoader.load(getClass().getResource("list.fxml"));
        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static void main(String[] args) { launch(args); }
}

ListController.java

import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.concurrent.*;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ListView;

import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

public class ListController {
    @FXML private ListView<User> usersList;

    @FXML void initialize() {
        assert usersList != null : "fx:id=\"usersList\" was not injected: check your FXML file 'list.fxml'.";

        final Task<List<User>> usersListTask = new Task<List<User>>() {
            protected List<User> call() throws SQLException {
                return new DatabaseManager().returnUsers();
            }
        };

        usersListTask.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent event) {
                usersList.setItems(
                        FXCollections.observableArrayList(usersListTask.getValue())
                );
            }
        });

        usersListTask.setOnFailed(new EventHandler<WorkerStateEvent>() {
            @Override
            public void handle(WorkerStateEvent event) {
                System.out.println("ERROR: " + usersListTask.getException());
            }
        });

        new Thread(usersListTask).start();
    }


    public static class User {
        private final StringProperty name = new SimpleStringProperty();

        public User(String name) {
            this.name.set(name);
        }

        public String getName() {
            return name.get();
        }

        public StringProperty nameProperty() {
            return name;
        }

        public void setName(String name) {
            this.name.set(name);
        }

        @Override
        public String toString() {
            return getName();
        }
    }

    public static class DatabaseManager {
        public List<User> returnUsers() throws SQLException {
            return Arrays.asList(
                new User("Sally"),
                new User("Jenny"),
                new User("Jill"),
                new User("Anne"),
                new User("Carol"),
                new User("Helen")
            );
        }
    }
}

关于java - ListView.setItems() 如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17874148/

相关文章:

java - 使用 EndlessRecyclerOnScrollListener 的 Asynctask 的无尽 RecyclerView

java - 使用 customAdapter 后项目的错误位置

java - 应用程序构造函数 javafx 中的异常

java - 我可以使用 JSON 在以不同编程语言实现的进程之间进行通信吗?

java - MongoDB 存储库 - 如何注释不是文档的子类?

android - RadioGroup 没有在 ListView 中保持正确的状态

java - 出于 OSGI 目的将 jfxrt 移至 lib/ext

java - 在 javafx 中 Swing JTextPane

java - 工作簿和 Oracle B2B 标注

java.lang.Boolean 无法转换为 ba.store.models.Merchants