【发布时间】:2015-04-10 02:00:14
【问题描述】:
我创建了一个简单的应用程序来测试过滤列表及其在相应源列表更改时的行为。我还想测试 update 更改,所以我创建了 ObservableList 的 ObservableLists。它比创建具有可观察字段的 Person 等附加类更快、更简单。
代码如下:
ListChangeListener<ObservableList<String>> changeNotifier = new ListChangeListener<ObservableList<String>>() {
@Override
public void onChanged(Change<? extends ObservableList<String>> c) {
while (c.next()) {
if (c.wasPermutated()) {
System.out.println("permutation");
} else if (c.wasUpdated()) {
System.out.println("update");
} else {
if (c.wasRemoved()) {
System.out.println("remove");
}
if (c.wasAdded()) {
System.out.println("add");
}
if (c.wasReplaced()) {
System.out.println("replace");
}
}
}
}
};
Callback<ObservableList<String>, Observable[]> identityExtractor = new Callback<ObservableList<String>, Observable[]>() {
@Override
public Observable[] call(ObservableList<String> param) {
return new Observable[]{param};
}
};
Predicate<ObservableList<String>> nonEmptyFilter = new Predicate<ObservableList<String>>() {
@Override
public boolean test(ObservableList<String> obsl) {
boolean nonEmpty = ! obsl.isEmpty();
for (String item : obsl) {
nonEmpty = nonEmpty && (null != item) && ("" != item);
};
return nonEmpty;
}
};
ObservableList<ObservableList<String>> basicSimple = FXCollections.observableArrayList();
ObservableList<ObservableList<String>> basicComposed = FXCollections.observableArrayList( identityExtractor );
ObservableList<ObservableList<String>> filteredSimple = basicSimple.filtered( nonEmptyFilter );
ObservableList<ObservableList<String>> filteredComposed = basicComposed.filtered( nonEmptyFilter );
System.out.println("Basic testing");
System.out.println("Add invalid");
basicSimple.addAll( FXCollections.observableArrayList("") );
System.out.println( basicSimple );
System.out.println( filteredSimple );
System.out.println("Make it valid");
basicSimple.get(0).addAll("first");
System.out.println( filteredSimple );
System.out.println("Add valid");
basicSimple.addAll( FXCollections.observableArrayList("Second") );
System.out.println( filteredSimple );
System.out.println("Composed testing");
System.out.println("Add invalid");
basicComposed.addAll( FXCollections.observableArrayList("") );
System.out.println( basicComposed );
System.out.println( filteredComposed );
System.out.println("Make it valid");
basicComposed.get(0).addAll("first");
System.out.println( filteredComposed );
System.out.println("Add valid");
basicComposed.addAll( FXCollections.observableArrayList("Second") );
System.out.println( filteredComposed );
我在测试过程中发现了一个奇怪的错误:
[info] Running helloworld.HelloWorld
Basic testing
Add invalid
[[]]
[]
Make it valid
[]
Add valid
[[Second]]
Composed testing
Add invalid
[[]]
[]
Make it valid
[error] (JavaFX Application Thread) java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at javafx.collections.transformation.FilteredList.updateFilter(FilteredList.java:298)
at javafx.collections.transformation.FilteredList.update(FilteredList.java:239)
at javafx.collections.transformation.FilteredList.sourceChanged(FilteredList.java:137)
at javafx.collections.transformation.TransformationList.lambda$getListener$16(TransformationList.java:106)
at javafx.collections.transformation.TransformationList$$Lambda$63/1596532574.onChanged(Unknown Source)
at javafx.collections.WeakListChangeListener.onChanged(WeakListChangeListener.java:88)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
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:485)
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.collections.ListListenerHelper$SingleInvalidation.fireValueChangedEvent(ListListenerHelper.java:126)
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.addAll(ModifiableObservableListBase.java:102)
at javafx.collections.ObservableListBase.addAll(ObservableListBase.java:245)
at helloworld.HelloWorld.start(HelloWorld.java:87)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$153(LauncherImpl.java:821)
at com.sun.javafx.application.LauncherImpl$$Lambda$55/7143454.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$166(PlatformImpl.java:323)
at com.sun.javafx.application.PlatformImpl$$Lambda$51/397137382.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl.lambda$null$164(PlatformImpl.java:292)
at com.sun.javafx.application.PlatformImpl$$Lambda$53/1802784360.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$165(PlatformImpl.java:291)
at com.sun.javafx.application.PlatformImpl$$Lambda$52/1184782272.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$45(GtkApplication.java:126)
at com.sun.glass.ui.gtk.GtkApplication$$Lambda$43/450111611.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)
[trace] Stack trace suppressed: run last compile:run for the full output.
[]
Add valid
[[Second]]
basicSimple 和basicComposed 之间的区别在于后者定义了一个提取器,因此它接收更新事件。在处理更新事件的过程中,本机代码引发了异常。我应该考虑什么才能使示例代码正常工作?
一点调试
我已将 println 插入到 nonEmptyFilter 谓词测试的末尾。它工作正常,传递给它的 ObservableList 是刚刚更新的预期新值。稍后在执行FilteredList的一些内部代码时发生错误。
【问题讨论】:
-
您是否尝试更新过滤列表?
-
不,我只更新 ArrayLists。 FilteredList 是自动更新的
-
错误很明显
basicComposed.get(0)不存在,所以它抛出ArrayIndexOutOfBoundsException。如果您希望我们进行进一步调查,您可以创建MCVE 并发布。 -
它确实存在,并打印在迹线上方 3 行。
-
是的,我看到了,但我实际上看不出有什么问题。如果您可以发布 MCVE,这将有助于进一步调查
标签: java javafx observablecollection observable