// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.turnrestrictions.editor;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import javax.swing.ComboBoxModel;
import javax.swing.event.EventListenerList;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import org.openstreetmap.josm.tools.CheckParameterUtil;
/**
* This is a model for a combo box to select a turn restriction type. The
* user can choose from a list of standard types but the model also supports
* non-standard tag values in the OSM data.
*
*/
public class TurnRestrictionComboBoxModel implements ComboBoxModel<Object>, Observer {
private TurnRestrictionEditorModel model;
private final List<Object> values = new ArrayList<>();
private String selectedTagValue = null;
private final transient EventListenerList listeners = new EventListenerList();
/**
* Populates the model with the list of standard values. If the
* data contains a non-standard value it is displayed in the combo
* box as an additional element.
*/
protected void populate() {
values.clear();
for (TurnRestrictionType type: TurnRestrictionType.values()) {
values.add(type);
}
String tagValue = model.getRestrictionTagValue();
if (tagValue.trim().equals("")) {
selectedTagValue = null;
} else {
TurnRestrictionType type = TurnRestrictionType.fromTagValue(tagValue);
if (type == null) {
values.add(0, tagValue);
selectedTagValue = tagValue;
} else {
selectedTagValue = type.getTagValue();
}
}
fireContentsChanged();
}
/**
* Creates the combo box model.
*
* @param model the turn restriction editor model. Must not be null.
*/
public TurnRestrictionComboBoxModel(TurnRestrictionEditorModel model) {
CheckParameterUtil.ensureParameterNotNull(model, "model");
this.model = model;
model.addObserver(this);
populate();
}
@Override
public Object getSelectedItem() {
TurnRestrictionType type = TurnRestrictionType.fromTagValue(selectedTagValue);
if (type != null) return type;
return selectedTagValue;
}
@Override
public void setSelectedItem(Object anItem) {
String tagValue = null;
if (anItem instanceof String) {
tagValue = (String) anItem;
} else if (anItem instanceof TurnRestrictionType) {
tagValue = ((TurnRestrictionType) anItem).getTagValue();
}
model.setRestrictionTagValue(tagValue);
}
@Override
public Object getElementAt(int index) {
return values.get(index);
}
@Override
public int getSize() {
return values.size();
}
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(ListDataListener.class, l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(ListDataListener.class, l);
}
protected void fireContentsChanged() {
for (ListDataListener l: listeners.getListeners(ListDataListener.class)) {
l.contentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, 0, getSize()));
}
}
/* ------------------------------------------------------------------------------------ */
/* interface Observer */
/* ------------------------------------------------------------------------------------ */
@Override
public void update(Observable o, Object arg) {
String tagValue = model.getRestrictionTagValue();
if (tagValue == null && selectedTagValue != null) {
populate();
} else if (tagValue != null && selectedTagValue == null) {
populate();
} else if (tagValue != null) {
if (!tagValue.equals(selectedTagValue)) {
populate();
}
}
}
}