- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个有趣的问题,我是 JavaFX 的新手,我需要创建一个小众市场 ObservableList
执行。
本质上,我需要一个 ObservableList
维护另一个 ObservableList
的映射派生值列表.我需要创建一个 ObservableDistinctList<P,V>
接受另一个 ObservableList<P>
和一个 Function<P,V>
lambda 作为其构造函数参数。 ObservableDistinctList<P,V>
维护应用 Function<P,V>
的不同值列表对于 ObservableList<P>
中的每个元素.
例如,假设我有 ObservableList<Flight> flights
具有以下实例。
Flt # Carrier Orig Dest Dep Date
174 WN ABQ DAL 5/6/2015
4673 WN DAL HOU 5/6/2015
485 DL DAL PHX 5/7/2015
6758 UA JFK HOU 5/7/2015
如果我根据每个 Flight 对象的承运人值创建一个新的 ObservableDistinctList,我将在客户端执行此操作。
ObservableDistinctList<Flight,String> distinctCarriers = new
ObservableDistinctList(flights, f -> f.getCarrier());
这些将是 distinctCarriers
中唯一的值列表。
WN
DL
UA
如果将航类添加到 flights
,它会首先检查一个新的不同值是否确实存在,然后再添加它。所以一个新的 WN
飞行不会导致增加 distinctCarriers
列表,而是一个 AA
飞行会。相反,如果航类从 flights
中删除,它需要检查其他实例是否会在删除之前保留该值。从 flights
中删除 WN 航类不会导致删除 WN
来自 distinctCarriers
列表,但删除了 DL
飞行将导致其移除。
这是我的实现。我是否实现了 ListChangeListener
正确吗?我对 List 可变性感到非常不舒服,所以我想在考虑在我的项目中使用它之前发布它。另外,我是否需要担心使用 ArrayList
的线程安全?支持这个?
public final class ObservableDistinctList<P,V> extends ObservableListBase<V> {
private final ObservableList<P> parentList;
private final Function<P,V> valueExtractor;
private final List<V> values;
public ObservableDistinctList(ObservableList<P> parentList, Function<P,V> valueExtractor) {
this.parentList = parentList;
this.valueExtractor = valueExtractor;
this.values = parentList.stream().map(p -> valueExtractor.apply(p)).distinct().collect(Collectors.toList());
this.parentList.addListener((ListChangeListener.Change<? extends P> c) -> {
while (c.next()) {
if (c.wasRemoved()) {
final Stream<V> candidatesForRemoval = c.getRemoved().stream().map(p -> valueExtractor.apply(p));
final List<V> persistingValues = parentList.stream().map(p -> valueExtractor.apply(p)).distinct().collect(Collectors.toList());
final Stream<V> valuesToRemove = candidatesForRemoval.filter(v -> ! persistingValues.contains(v));
valuesToRemove.forEach(v -> values.remove(v));
}
if (c.wasAdded()) {
final Stream<V> candidatesForAdd = c.getAddedSubList().stream().map(p -> valueExtractor.apply(p));
final List<V> existingValues = parentList.stream().map(p -> valueExtractor.apply(p)).distinct().collect(Collectors.toList());
final Stream<V> valuesToAdd = candidatesForAdd.filter(v -> ! values.contains(v));
valuesToAdd.forEach(v -> values.add(v));
}
}
});
}
@Override
public V get(int index) {
return values.get(index);
}
@Override
public int size() {
return values.size();
}
}
最佳答案
下面是一个简单示例(加上驱动程序 - 提示:这就是您应该在问题中提供的内容:-) 自定义 ObservableList,它在源列表中保留元素属性的不同值。它使自己在添加/删除项目时与源同步。同步由以下人员实现:
通知是通过向实用程序方法 nextRemove/nextAdd 发送消息来处理的。
/**
* Example of how to implement a custom ObservableList.
*
* Here: an immutable and unmodifiable (in itself) list containing distinct
* values of properties of elements in a backing list, the values are extracted
* via a function
*/
public class DistinctMapperDemo extends Application {
public static class DistinctMappingList<V, E> extends ObservableListBase<E> {
private List<E> mapped;
private Function<V, E> mapper;
public DistinctMappingList(ObservableList<V> source, Function<V, E> mapper) {
this.mapper = mapper;
mapped = applyMapper(source);
ListChangeListener l = c -> sourceChanged(c);
source.addListener(l);
}
private void sourceChanged(Change<? extends V> c) {
beginChange();
List<E> backing = applyMapper(c.getList());
while(c.next()) {
if (c.wasAdded()) {
wasAdded(c, backing);
} else if (c.wasRemoved()) {
wasRemoved(c, backing);
} else {
// throw just for the example
throw new IllegalStateException("unexpected change " + c);
}
}
endChange();
}
private void wasRemoved(Change<? extends V> c, List<E> backing) {
List<E> removedCategories = applyMapper(c.getRemoved());
for (E e : removedCategories) {
if (!backing.contains(e)) {
int index = indexOf(e);
mapped.remove(index);
nextRemove(index, e);
}
}
}
private void wasAdded(Change<? extends V> c, List<E> backing) {
List<E> addedCategories = applyMapper(c.getAddedSubList());
for (E e : addedCategories) {
if (!contains(e)) {
int last = size();
mapped.add(e);
nextAdd(last, last +1);
}
}
}
private List<E> applyMapper(List<? extends V> list) {
List<E> backing = list.stream().map(p -> mapper.apply(p)).distinct()
.collect(Collectors.toList());
return backing;
}
@Override
public E get(int index) {
return mapped.get(index);
}
@Override
public int size() {
return mapped.size();
}
}
int categoryCount;
private Parent getContent() {
ObservableList<DemoData> data = FXCollections.observableArrayList(
new DemoData("first", "some"),
new DemoData("second", "some"),
new DemoData("first", "other"),
new DemoData("dup", "other"),
new DemoData("dodo", "next"),
new DemoData("getting", "last")
);
TableView<DemoData> table = new TableView<>(data);
TableColumn<DemoData, String> name = new TableColumn<>("Name");
name.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<DemoData, String> cat = new TableColumn<>("Category");
cat.setCellValueFactory(new PropertyValueFactory<>("category"));
table.getColumns().addAll(name, cat);
Function<DemoData, String> mapper = c -> c.categoryProperty().get();
ObservableList<String> mapped = new DistinctMappingList<>(data, mapper);
ListView<String> cats = new ListView<>(mapped);
Button remove = new Button("RemoveSelected DemoData");
remove.setOnAction(e -> {
int selected = table.getSelectionModel().getSelectedIndex();
if (selected <0) return;
data.remove(selected);
});
Button createNewCategory = new Button("Create DemoData with new Category");
createNewCategory.setOnAction(e -> {
String newCategory = data.size() == 0 ? "some" + categoryCount :
data.get(0).categoryProperty().get() + categoryCount;
data.add(new DemoData("name" + categoryCount, newCategory));
categoryCount++;
});
VBox buttons = new VBox(remove, createNewCategory);
HBox box = new HBox(table, cats, buttons);
return box;
}
public static class DemoData {
StringProperty name = new SimpleStringProperty(this, "name");
StringProperty category = new SimpleStringProperty(this, "category");
public DemoData(String name, String category) {
this.name.set(name);
this.category.set(category);
}
public StringProperty nameProperty() {
return name;
}
public StringProperty categoryProperty() {
return category;
}
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent()));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
关于java - 从另一个 ObservableList 中将映射的不同值派生到一个 ObservableList 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29656772/
我有一个有趣的问题,我是 JavaFX 的新手,我需要创建一个小众市场 ObservableList执行。 本质上,我需要一个 ObservableList维护另一个 ObservableList 的
如果我有两个单独的 ObservableLists,并且都放在一个单独的 ObservableList 中用于 TableView...有没有办法在这两个 ObservableLists 和聚合的 O
当我尝试将项目设置到 tableView 中时遇到问题,有关我使用 SceneBuilder 的信息。 Main.java: public class Main extends Application
我想知道为什么TableView方法setItems不需要ObservableList作为参数,但是 ObservableList ? 还有什么是最好的转型方式ObservableList至Obser
当我将监听器附加到可观察列表并在该监听器中尝试删除一些元素时,在某些情况下它会通过,而在某些情况下会崩溃。 场景:项目已从列表中删除。它触发监听器,在该监听器中我尝试删除另一个项目。 如果在监听器中我
我在不同的条件下尝试了不同的集合,但我能够收到的所有更改都是排列、添加、删除和替换更改。 更新变化在什么条件下出现?什么基类,什么存储类以及需要什么操作来产生这样的事件? 最佳答案 要生成更新事件,您
This answer为可观察列表提供解决方案,如果列表元素的属性更改,它将发送“列表已更新” 通知>. 在我的例子中,此类可观察列表的元素(元素类)很复杂,我不喜欢为每个成员变量实现属性。因此,我在
这是我的问题:我有一堂 Detenu 课: public class Detenu { private static String n_ecrou; // Unique id p
我正在使用 JavaFX 编写日志读取器应用程序,并且我想根据所选属性实现基于搜索的过滤。 Application screenshot组合框中的值表示填充表的对象字段的名称。现在,我只想显示属性包含
给出以下代码示例: private final ObservableList data = FXCollections.observableArrayList( new Per
我有一个使用 JavaFX 的应用程序。它包含一个ListView(它使用ObservableList)。我使用添加了一个 ChangeListener list.getSelectionModel(
我有一个可观察列表,我尝试通过不同的谓词来过滤它。 我有要进行过滤的嵌套对象。 这是第一个 pojo public Class Transaction { private String na
例如,如果您有一个ArrayList,您可以执行以下操作: ArrayList list = new ArrayList(); ObservableList data = FXCollections.
我不太确定如何表达这个问题,请耐心等待。 我有一个 ObservableList用户定义的对象与几个 getter 方法,例如: public String getName() { return th
编辑 事实证明,当我实际上想要一个深拷贝时,FXCollections.observableArrayList() 正在创建列表的浅拷贝。 this.value 和 value “指向”两个不同的 O
我正在处理一个 javaFx 项目,我们必须在其中使用 ObservableList 添加 Listner。 ObservableList 包含人的模型。但是我想通过序列化将整个 Observable
我有一个自定义对象 FermentableInRecipe,它填充了一个 TableView。为了响应列表中项目的更改以及列表本身,我决定使用提取器。这是我的 ObservableList 的声明和实
我试图理解 ObservableList 和 Realms 的概念。我试图创建一个 ObservableList 的实例,如下所示: public ObservableList createObs
我有一个 Java ObservableList有数千个条目每秒接收数百个更新支持 JavaFX TableView . ObservableList 是 backed by an ArrayList
我有一张 Albums 的表格可由用户过滤和排序。 这是这张 table 的样子。如您所见,列是可排序的,顶部有一个文本框,当前正在过滤其中包含字符串“cu”的专辑: 一切正常专辑列表填充后 . 但是
我是一名优秀的程序员,十分优秀!