/*
* Copyright (C) 2009 Quadduc <quadduc@gmail.com>
* Copyright (C) 2014 Robert B. Colton
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.ui.swing.propertylink;
import java.beans.ExceptionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.BoundedRangeModel;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JList;
import javax.swing.text.Document;
import org.lateralgm.ui.swing.propertylink.ComboBoxLink;
import org.lateralgm.ui.swing.propertylink.ComboBoxLink.DefaultComboBoxConversion;
import org.lateralgm.ui.swing.propertylink.ComboBoxLink.ComboBoxConversion;
import org.lateralgm.util.PropertyEditor;
import org.lateralgm.util.PropertyLink;
import org.lateralgm.util.PropertyMap;
public class PropertyLinkFactory<K extends Enum<K>>
{
private PropertyMap<K> map;
private final ExceptionListener exceptionListener;
/* This is a map used to inform all property links that the factory that created them has changed maps
* and they should thus update their controls.
*/
private List<PropertyLinkMapListener<K>> mapListeners = new ArrayList<PropertyLinkMapListener<K>>();
/* Necessary for mass disposing links created by the factory */
private List<PropertyLink<K,?>> mapLinks = new ArrayList<PropertyLink<K,?>>();
public void addLinkMapListener(PropertyLinkMapListener<K> plml) {
mapListeners.add(plml);
}
public void removeLinkMapListener(PropertyLinkMapListener<K> plml) {
mapListeners.remove(plml);
}
public void removeAllLinks()
{
for (PropertyLink<?,?> link : mapLinks) {
link.remove();
}
mapLinks.clear();
mapListeners.clear();
}
public void setMap(PropertyMap<K> m) {
map = m;
for (PropertyLinkMapListener<K> listener : mapListeners) {
listener.mapChanged(map);
}
}
public abstract interface PropertyLinkMapListener<K extends Enum<K>> {
public abstract void mapChanged(PropertyMap<K> m);
}
public PropertyLinkFactory(PropertyMap<K> m, ExceptionListener el)
{
map = m;
exceptionListener = el;
}
public <L extends PropertyLink<K,?>>L init(L l)
{
/* This should probably be moved into PropertyLink itself, but either way the PropertyLink needs
* to know the plf that created it so it knows when to add and remove itself as a listener to
* revert when the PLF decides to changes its map.
*/
l.factory = this;
addLinkMapListener(l);
mapLinks.add(l);
l.setExceptionListener(exceptionListener);
return l;
}
public <V>PropertyLink<K,V> make(PropertyEditor<V> pe, K k)
{
return init(pe.getLink(map,k));
}
public <V>ComboBoxLink<K,V> make(JComboBox<?> b, K k)
{
return init(new ComboBoxLink<K,V>(b,map,k, new DefaultComboBoxConversion<V>()));
}
public <V>ComboBoxLink<K,V> make(JComboBox<?> b, K k, ComboBoxConversion<V> conv)
{
return init(new ComboBoxLink<K,V>(b,map,k,conv));
}
public <V>ListLink<K,V> make(JList<?> l, K k)
{
return init(new ListLink<K,V>(l,map,k));
}
public FormattedLink<K> make(JFormattedTextField f, K k)
{
return init(new FormattedLink<K>(f,map,k));
}
public DocumentLink<K> make(Document d, K k)
{
return init(new DocumentLink<K>(d,map,k));
}
public ButtonModelLink<K> make(ButtonModel m, K k)
{
return init(new ButtonModelLink<K>(m,map,k));
}
public ButtonModelLink<K> make(AbstractButton b, K k)
{
return init(new ButtonModelLink<K>(b.getModel(),map,k));
}
public BoundedRangeLink<K,Integer> make(BoundedRangeModel m, K k)
{
return init(new BoundedRangeLink<K,Integer>(m,new BoundedRangeLink.IntegerConverter(),map,k));
}
public BoundedRangeLink<K,Double> make(BoundedRangeModel m, K k, double s)
{
return init(new BoundedRangeLink<K,Double>(m,new BoundedRangeLink.DoubleConverter(s),map,k));
}
public <V extends Enum<V>>ButtonGroupLink<K,V> make(ButtonGroup g, K k, Class<V> vt)
{
return init(new ButtonGroupLink<K,V>(g,vt,map,k));
}
public ButtonIncrementLink<K,Integer> make(AbstractButton ab, K k, int i, int l)
{
return init(ButtonIncrementLink.make(ab,i,l,map,k));
}
}