Skip to content

Instantly share code, notes, and snippets.

@kleopatra
Last active January 25, 2021 14:06
Show Gist options
  • Select an option

  • Save kleopatra/fcce1e40c48e84b37f62631df348be90 to your computer and use it in GitHub Desktop.

Select an option

Save kleopatra/fcce1e40c48e84b37f62631df348be90 to your computer and use it in GitHub Desktop.
Comparing effect of listener support api in SkinBase
/**
* Listening to listChanges of a list-valued property.
* see https://bugs.openjdk.java.net/browse/JDK-8258777
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static class SkinBaseObservableList extends SkinBase<ExampleControl> {
public SkinBaseObservableList(ExampleControl control) {
super(control);
// list-valued observables need invalidation listener to re-wire content listener reliably
registerInvalidationListener(control.itemsProperty(), p -> updateItemsContentListener());
updateItemsContentListener();
}
// reference to items, needed to unregister listChangeListener
private ObservableList items;
private void updateItemsContentListener() {
// rewire
unregisterListChangeListeners(items);
items = getSkinnable().itemsProperty().getValue();
registerListChangeListener(items, (Consumer<Change<?>>) c -> itemsContentChanged(c));
// update internal state
itemsContentChanged(null);
}
private void itemsContentChanged(Change c) {
// update internals based on list content
}
}
/**
* Example of current changed api (added registerInvalidation, no listChange support) api.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static class SkinBaseObservableList2 extends SkinBase<ExampleControl> {
private ListChangeListener itemsContentListener;
private WeakListChangeListener weakItemsContentListener;
public SkinBaseObservableList2(ExampleControl control) {
super(control);
// list-valued observables need invalidation listener to re-wire content listener reliably
registerInvalidationListener(control.itemsProperty(), obs -> updateItemsContentListener());
itemsContentListener = c -> itemsContentChanged(c);
weakItemsContentListener = new WeakListChangeListener<>(itemsContentListener);
updateItemsContentListener();
}
// reference to items, needed to unregister listChangeListener
private ObservableList items;
private void updateItemsContentListener() {
// rewire
if (items != null) {
items.removeListener(weakItemsContentListener);
}
items = getSkinnable().itemsProperty().getValue();
if (items != null) {
items.addListener(weakItemsContentListener);
}
// update internal state
itemsContentChanged(null);
}
private void itemsContentChanged(Change c) {
// update internals based on list content
}
@Override
public void dispose() {
if (items != null) {
items.removeListener(weakItemsContentListener);
items = null;
}
super.dispose();
}
}
/**
* Example of current (registerChangeListener only) api.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static class SkinBaseObservableList extends SkinBase<ExampleControl> {
private InvalidationListener itemsListener;
private WeakInvalidationListener weakItemsListener;
private ListChangeListener itemsContentListener;
private WeakListChangeListener weakItemsContentListener;
public SkinBaseObservableList(ExampleControl control) {
super(control);
// list-valued observables need invalidation listener to re-wire content listener reliably
itemsListener = list -> updateItemsContentListener();
weakItemsListener = new WeakInvalidationListener(itemsListener);
control.itemsProperty().addListener(weakItemsListener);
itemsContentListener = c -> itemsContentChanged(c);
weakItemsContentListener = new WeakListChangeListener<>(itemsContentListener);
updateItemsContentListener();
}
// reference to items, needed to unregister listChangeListener
private ObservableList items;
private void updateItemsContentListener() {
// rewire
if (items != null) {
items.removeListener(weakItemsContentListener);
}
items = getSkinnable().itemsProperty().getValue();
if (items != null) {
items.addListener(weakItemsContentListener);
}
// update internal state
itemsContentChanged(null);
}
private void itemsContentChanged(Change c) {
// update internals based on list content
}
@Override
public void dispose() {
if (getSkinnable() == null) return;
getSkinnable().itemsProperty().removeListener(weakItemsListener);
if (items != null) {
items.removeListener(weakItemsContentListener);
items = null;
}
super.dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment