Last active
March 30, 2016 11:38
-
-
Save hastebrot/efe0a4d39e054730f8090ef9facfe050 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.function.Predicate | |
import javafx.beans.binding.Bindings | |
import javafx.beans.property.ObjectProperty | |
import javafx.beans.property.SimpleObjectProperty | |
import javafx.collections.FXCollections | |
import javafx.collections.ObservableList | |
import javafx.collections.transformation.FilteredList | |
import javafx.collections.transformation.SortedList | |
class TransformatedListContext<E> { | |
//--------------------------------------------------------------------------------------------- | |
// MAIN METHOD. | |
//--------------------------------------------------------------------------------------------- | |
static void main(String[] args) { | |
def listContext = new TransformatedListContext() | |
def targetList = FXCollections.observableArrayList(1, 2, 3, 4, 5) | |
def masterList = listContext.register(targetList) | |
println targetList // [1, 2, 3, 4, 5] | |
println masterList // [1, 2, 3, 4, 5] | |
listContext.sortProperty.set({ a, b -> b <=> a } as Comparator) | |
println targetList // [5, 4, 3, 2, 1] | |
listContext.filterProperty.set({ a -> a > 3 } as Predicate) | |
println targetList // [5, 4] | |
masterList.add(6) | |
println targetList // [6, 5, 4] | |
masterList.remove(3 as Object) | |
println targetList // [6, 5, 4] | |
listContext.filterProperty.set({ true } as Predicate) | |
println targetList // [6, 5, 4, 2, 1] | |
listContext.sortProperty.set({ a, b -> a <=> b } as Comparator) | |
println targetList // [1, 2, 4, 5, 6] | |
} | |
//--------------------------------------------------------------------------------------------- | |
// CONSTANTS. | |
//--------------------------------------------------------------------------------------------- | |
static final Predicate ALWAYS_TRUE_PREDICATE = { true } as Predicate | |
//--------------------------------------------------------------------------------------------- | |
// FIELDS. | |
//--------------------------------------------------------------------------------------------- | |
// filter: Predicate (ObjectProperty<Predicate>). | |
private ObjectProperty<Predicate> filterProperty = | |
new SimpleObjectProperty(this, "filter") | |
ObjectProperty<Predicate> filterProperty() { return this.filterProperty } | |
Predicate getFilter() { return this.filterProperty.get() } | |
void setFilter(Predicate value) { this.filterProperty.set(value) } | |
// sort: Comparator (ObjectProperty<Comparator>). | |
private ObjectProperty<Comparator> sortProperty = | |
new SimpleObjectProperty(this, "sort") | |
ObjectProperty<Comparator> sortProperty() { return this.sortProperty } | |
Comparator getSort() { return this.sortProperty.get() } | |
void setSort(Comparator value) { this.sortProperty.set(value) } | |
//--------------------------------------------------------------------------------------------- | |
// PRIVATE FIELDS. | |
//--------------------------------------------------------------------------------------------- | |
Map<ObservableList<E>, ObservableList<E>> boundLists | |
//--------------------------------------------------------------------------------------------- | |
// CONSTRUCTORS. | |
//--------------------------------------------------------------------------------------------- | |
public TransformatedListContext() { | |
this.boundLists = [:] | |
this.filterProperty = new SimpleObjectProperty(ALWAYS_TRUE_PREDICATE) | |
this.sortProperty = new SimpleObjectProperty() | |
} | |
//--------------------------------------------------------------------------------------------- | |
// METHODS. | |
//--------------------------------------------------------------------------------------------- | |
// TODO: Dokumentieren dass targetList nach Registrierung nicht mehr modifiziert werden darf. | |
ObservableList<E> register(ObservableList<E> targetList) { | |
def masterList = this.buildMasterList(targetList) | |
def transformatedList = this.buildTransformatedList(masterList) | |
// Bind transformatedList to targetList and keep a reference to transformatedList. | |
Bindings.bindContent(targetList, transformatedList) | |
this.boundLists[targetList] = transformatedList | |
return masterList | |
} | |
//--------------------------------------------------------------------------------------------- | |
// PRIVATE METHODS. | |
//--------------------------------------------------------------------------------------------- | |
private ObservableList<E> buildMasterList(ObservableList<E> targetList) { | |
def masterList = FXCollections.observableArrayList(targetList) | |
return masterList | |
} | |
private ObservableList<E> buildTransformatedList(ObservableList<E> masterList) { | |
def filteredList = new FilteredList(masterList) | |
def sortedList = new SortedList(filteredList) | |
filteredList.predicateProperty().bind(this.filterProperty) | |
sortedList.comparatorProperty().bind(this.sortProperty) | |
def transformatedList = FXCollections.unmodifiableObservableList(sortedList) | |
return transformatedList | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.function.Predicate | |
import javafx.collections.FXCollections | |
import javafx.collections.ObservableList | |
import spock.lang.Specification | |
final class TransformatedListContextSpec extends Specification { | |
//--------------------------------------------------------------------------------------------- | |
// FIELDS. | |
//--------------------------------------------------------------------------------------------- | |
TransformatedListContext listContext | |
ObservableList targetList_integers | |
//--------------------------------------------------------------------------------------------- | |
// FIXTURE METHODS. | |
//--------------------------------------------------------------------------------------------- | |
def setup() { | |
listContext = new TransformatedListContext() | |
targetList_integers = FXCollections.observableArrayList(1, 2, 3, 4, 5) | |
} | |
//--------------------------------------------------------------------------------------------- | |
// FEATURE METHODS. | |
//--------------------------------------------------------------------------------------------- | |
def "setSort() and setFilter()"() { | |
given: | |
def masterList = listContext.register(targetList_integers) | |
when: | |
listContext.sort = { int a, int b -> b <=> a } as Comparator | |
listContext.filter = { int a -> a > 3 } as Predicate | |
then: | |
targetList_integers == [5, 4] | |
masterList == [1, 2, 3, 4, 5] | |
} | |
def "register() returns masterList"() { | |
given: | |
def masterList = listContext.register(targetList_integers) | |
when: | |
listContext.sort = Comparator.reverseOrder() | |
masterList.add(6) | |
then: | |
targetList_integers == [6, 5, 4, 3, 2, 1] | |
masterList == [1, 2, 3, 4, 5, 6] | |
} | |
def "register() is not garbage collected"() { | |
when: | |
def masterList = listContext.register(targetList_integers) | |
System.gc() | |
and: | |
listContext.sort = Comparator.reverseOrder() | |
then: | |
masterList == [1, 2, 3, 4, 5] | |
targetList_integers == [5, 4, 3, 2, 1] | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment