Hy guys,
我对JavaFX知识感到困惑。每次我的ObservableList更改时,我想实现我的过滤器列表中显示的列表(此处未显示,但代码重现了错误)。不幸的是,我有一个奇怪的问题。 每当我在ListChangeListener中更改我的属性时,以下代码抛出一个ArrayIndexOutOfBoundsException。
package com.tests.misterpresident;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.concurrent.Task;
import javafx.stage.Stage;
import java.util.Random;
public class Tester extends Application {
private static ObservableList<Person> myPersons;
private static FilteredList<Person> filteredPersons;
public static void main(String[] args) {
myPersons = FXCollections.observableArrayList(person -> new Observable[]{person.duplicateProperty()});
filteredPersons = new FilteredList<>(myPersons, p -> p.getDuplicate());
myPersons.addListener((ListChangeListener<Person>) change ->
{
//check for duplicates
while (change.next())
{
for(Person p1 : change.getAddedSubList())
{
for(Person p2 : myPersons)
{
if(p1 == p2)
continue;
if(p1.getName().equals(p2.getName()))
{
p1.setDuplicate(true);
p2.setDuplicate(true);
}
}
}
}
});
Task t = new Task<Void>() {
Random r = new Random();
@Override
protected Void call() {
for (int i = 0; i < 100; i++) {
int number = r.nextInt(10);
myPersons.add(new Person("Test" + number));
}
System.out.println("Finished");
return null;
}
};
Thread thread = new Thread(t);
thread.run();
}
@Override
public void start(Stage stage) {
}
static class Person{
private String name;
private BooleanProperty duplicate = new SimpleBooleanProperty(false);
public Person(String name) {
this.name = name;
System.out.println("Created Person " + name);
}
public String getName() {
return name;
}
public void setName(String name)
{
this.name = name;
}
public BooleanProperty duplicateProperty() {
return duplicate;
}
public boolean getDuplicate()
{
return this.duplicate.get();
}
public void setDuplicate(boolean duplicate)
{
this.duplicate.setValue(duplicate);
}
}
}
你们有胶水如何解决这个问题,或者你知道更好的解决方案。
谢谢!
修改 回溯:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at javafx.collections.transformation.FilteredList.addRemove(FilteredList.java:269)
at javafx.collections.transformation.FilteredList.sourceChanged(FilteredList.java:144)
at javafx.collections.transformation.TransformationList.lambda$getListener$0(TransformationList.java:106)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:524)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at com.sun.javafx.collections.ObservableListWrapper.access$200(ObservableListWrapper.java:45)
at com.sun.javafx.collections.ObservableListWrapper$1$1.invalidated(ObservableListWrapper.java:75)
at com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:137)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.BooleanPropertyBase.fireValueChangedEvent(BooleanPropertyBase.java:103)
at javafx.beans.property.BooleanPropertyBase.markInvalid(BooleanPropertyBase.java:110)
at javafx.beans.property.BooleanPropertyBase.set(BooleanPropertyBase.java:144)
at javafx.beans.property.BooleanProperty.setValue(BooleanProperty.java:81)
at com.tests.misterpresident.Tester$Person.setDuplicate(Tester.java:101)
at com.tests.misterpresident.Tester.lambda$main$2(Tester.java:41)
at com.sun.javafx.collections.ListListenerHelper$Generic.fireValueChangedEvent(ListListenerHelper.java:329)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at com.tests.misterpresident.Tester$1.call(Tester.java:56)
at com.tests.misterpresident.Tester$1.call(Tester.java:49)
at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
at java.util.concurrent.FutureTask.run(FutureTask.java)
at java.lang.Thread.run(Thread.java:748)
at com.tests.misterpresident.Tester.main(Tester.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)