DelegatingObservableSet.java
001 /*
002  * Copyright 2008-2017 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.javafx.collections;
017 
018 import javafx.collections.ObservableSet;
019 import javafx.collections.SetChangeListener;
020 import javafx.collections.WeakSetChangeListener;
021 
022 import javax.annotation.Nonnull;
023 import java.util.Collection;
024 import java.util.Iterator;
025 
026 import static java.util.Objects.requireNonNull;
027 
028 /**
029  @author Andres Almiray
030  @since 2.9.0
031  */
032 public abstract class DelegatingObservableSet<E> extends ObservableSetBase<E> implements ObservableSet<E> {
033     private final ObservableSet<E> delegate;
034     private SetChangeListener<E> sourceListener;
035 
036     public DelegatingObservableSet(@Nonnull ObservableSet<E> delegate) {
037         this.delegate = requireNonNull(delegate, "Argument 'delegate' must not be null");
038         this.delegate.addListener(new WeakSetChangeListener<>(getListener()));
039     }
040 
041     @Nonnull
042     protected ObservableSet<E> getDelegate() {
043         return delegate;
044     }
045 
046     private SetChangeListener<E> getListener() {
047         if (sourceListener == null) {
048             sourceListener = DelegatingObservableSet.this::sourceChanged;
049         }
050         return sourceListener;
051     }
052 
053     protected abstract void sourceChanged(@Nonnull SetChangeListener.Change<? extends E> c);
054 
055     // --== Delegate methods ==--
056 
057     @Override
058     public int size() {
059         return getDelegate().size();
060     }
061 
062     @Override
063     public boolean isEmpty() {
064         return getDelegate().isEmpty();
065     }
066 
067     @Override
068     public boolean contains(Object o) {
069         return getDelegate().contains(o);
070     }
071 
072     @Override
073     public Iterator<E> iterator() {
074         return getDelegate().iterator();
075     }
076 
077     @Override
078     public Object[] toArray() {
079         return getDelegate().toArray();
080     }
081 
082     @Override
083     public <T> T[] toArray(T[] a) {
084         return getDelegate().toArray(a);
085     }
086 
087     @Override
088     public boolean add(E e) {
089         return getDelegate().add(e);
090     }
091 
092     @Override
093     public boolean remove(Object o) {
094         return getDelegate().remove(o);
095     }
096 
097     @Override
098     public boolean containsAll(Collection<?> c) {
099         return getDelegate().containsAll(c);
100     }
101 
102     @Override
103     public boolean addAll(Collection<? extends E> c) {
104         return getDelegate().addAll(c);
105     }
106 
107     @Override
108     public boolean retainAll(Collection<?> c) {
109         return getDelegate().retainAll(c);
110     }
111 
112     @Override
113     public boolean removeAll(Collection<?> c) {
114         return getDelegate().removeAll(c);
115     }
116 
117     @Override
118     public void clear() {
119         getDelegate().clear();
120     }
121 
122     @Override
123     public boolean equals(Object o) {
124         return getDelegate().equals(o);
125     }
126 
127     @Override
128     public int hashCode() {
129         return getDelegate().hashCode();
130     }
131 }