简而言之,我有一个带有单个列的表视图,每当我向可观察列表中添加新项时,我都希望对其进行排序并保持排序。我在网上看了几个例子和类似的问题,但没有任何帮助。如果我尝试从列表的更改侦听器调用TableView.sort(),似乎什么都没有发生。
当我将列添加到表的排序顺序时,这就是问题。此后尝试对表进行排序会导致应用程序严重崩溃。唯一的错误是“应用程序启动方法中的异常”。然后,我将sort()调用移至Platform.runLater(),这可以防止应用崩溃。但是随后出现了一个新问题。调用sort时,我会得到一个数组索引超出范围的错误,这似乎是随机发生的,尽管我认为主要是当新项目超出了表格的视图并且需要滚动条时。
在撰写本文时,我将排序从变更侦听器中移出,并在下面移至要添加实际数据的Task中。没有更多的错误。所以我想我的新问题是,为什么尝试从听众那里做事时我会遇到这么多问题?
public class Temp extends Application{
private ObservableList<String> libraryList = FXCollections.observableArrayList();
public void start(Stage stage) {
Label statusLabel = new Label("stuff goes here");
TableView<String> table = new TableView<String>(libraryList);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
TableColumn<String, String> col = new TableColumn<String, String>("Stuff");
col.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue()));
table.getColumns().add(col);
table.getSortOrder().add(col);
libraryList.addListener(new ListChangeListener<String>() {
public void onChanged(Change change) {
Platform.runLater(()->{
table.sort();
statusLabel.setText(libraryList.size()+" entries");
});
}
});
// dummy stuff
libraryList.add("foo");
libraryList.add("bar");
Button b = new Button("Press Me");
b.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent e) {
FileTask task = new FileTask();
new Thread(task).start();
}
});
BorderPane mainBody = new BorderPane();
mainBody.setTop(statusLabel);
mainBody.setCenter(table);
mainBody.setBottom(b);
Scene scene = new Scene(mainBody);
stage.setScene(scene);
stage.show();
}
class FileTask extends Task<Boolean>{
public FileTask(){
}
protected Boolean call() throws Exception{
Random rand = new Random();
for(int i = 0; i < 3; i++) {
String s = ""+rand.nextInt(Integer.MAX_VALUE);
libraryList.add(s);
}
return true;
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
答案 0 :(得分:0)
我相信我现在已经了解了这个问题。当我将一个项目添加到列表中时,它将调用onChanged()。当我对表进行排序时,它还会触发onChanged,从而创建一个无限循环。我没有意识到表格实际上是通过更改列表本身来对数据进行排序的。