// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea
// Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com
// Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
// Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
package graphtea.platform.attribute;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
/**
* A handy NotifiableSet which acts on any AttributeSet and converts it to a NotifiableAttributeSet,
* This is done by checking the AttributeSet for changes in each (100) mili seconds.
* changes on (T) input will take effect on next 100 milisecond,
* using this class should be done with care, this class uses a thread
* and checks the edge on each 100ms for any changes, so creating a lot of
* instances of this class (for example for all edges of graph)
* will take more and more cpu,
* <p/>
* try to create as few as possible instances of this class and call stop() when you don't need
* it any more!
* <p/>
*/
public class TimeLimitedNotifiableAttrSet<T extends AttributeSet> implements Runnable, NotifiableAttributeSet {
private boolean started = false;
private long millis = 100;
Thread thread;
private T inp;
NotifiableAttributeSetImpl as = new NotifiableAttributeSetImpl();
public TimeLimitedNotifiableAttrSet(T input) {
this.inp = input;
thread = new Thread(this);
}
/**
* starts firinig listeners to this class
*/
public void start() {
started = true;
thread.start();
}
/**
* stops firing listeners
*/
public void stop() {
started = false;
}
/**
* -> Thread
*/
public void run() {
Map<String, Object> old = inp.getAttrs();
Map<String, Object> _new;
while (started) {
_new = inp.getAttrs();
fireChange(old, _new);
try {
old = inp.getAttrs();
Thread.sleep(millis);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
private void fireChange(Map<String, Object> _new, Map<String, Object> old) {
Iterator<Map.Entry<String, Object>> i = old.entrySet().iterator();
while (i.hasNext()) {
Map.Entry<String, Object> e = i.next();
String key = e.getKey();
Object value = e.getValue();
if (value == null) {
if (!(_new.get(key) == null && _new.containsKey(key))) {
inp.put(key, value);
}
} else {
if (!value.equals(_new.get(key))) {
fireAttributeChange(getAttributeListeners(), key, old, value);
inp.put(key, value);
fireAttributeChange(getAttributeListeners(), key, old, value);
}
}
}
}
//----- NotifiableAttributeSet Methods
public Map<String, Object> getAttrs() {
return inp.getAttrs();
}
public void put(String name, Object value) {
Object old = get(name);
inp.put(name, value);
fireAttributeChange(getAttributeListeners(), name, old, value);
}
public Object get(String name) {
return inp.get(name);
}
public void addAttributeListener(AttributeListener attributeListener) {
as.addAttributeListener(attributeListener);
}
public Collection<AttributeListener> getAttributeListeners() {
return as.getAttributeListeners();
}
public void removeAttributeListener(AttributeListener attributeListener) {
as.removeAttributeListener(attributeListener);
}
public void fireAttributeChange(Collection<AttributeListener> listeners, String name, Object oldVal, Object newVal) {
if (listeners != null) {
for (AttributeListener l : listeners) {
l.attributeUpdated(name, oldVal, newVal);
}
}
}
}