package com.revolsys.swing.map.component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.Vector;
import javax.swing.JComboBox;
import javax.swing.SwingConstants;
import com.revolsys.datatype.DataTypes;
import com.revolsys.swing.field.FunctionStringConverter;
import com.revolsys.swing.map.MapPanel;
import com.revolsys.swing.parallel.Invoke;
import com.revolsys.util.Property;
public class SelectMapScale extends JComboBox
implements ItemListener, PropertyChangeListener, ActionListener {
private static final long serialVersionUID = 1L;
private final Reference<MapPanel> map;
public SelectMapScale(final MapPanel map) {
super(new Vector<>(map.getScales()));
this.map = new WeakReference<>(map);
setEditable(true);
final FunctionStringConverter renderer = new FunctionStringConverter(MapScale::formatScale);
renderer.setHorizontalAlignment(SwingConstants.RIGHT);
final SelectMapScaleEditor editor = new SelectMapScaleEditor(getEditor(), renderer);
setEditor(editor);
setRenderer(renderer);
addItemListener(this);
addActionListener(this);
Property.addListener(map, "scale", this);
final Dimension size = new Dimension(140, 22);
setPreferredSize(size);
setMaximumSize(size);
setToolTipText("Map Scale");
}
@Override
public void actionPerformed(final ActionEvent e) {
final MapPanel map = getMap();
if (map != null) {
try {
final Object item = getSelectedItem();
String string = DataTypes.toString(item);
string = string.replaceAll("((^1:)|([^0-9\\.])+)", "");
final double scale = Double.parseDouble(string);
map.setScale(scale);
} catch (final Throwable t) {
}
}
}
public MapPanel getMap() {
return this.map.get();
}
@Override
public void itemStateChanged(final ItemEvent e) {
final MapPanel map = getMap();
if (map != null) {
if (e.getStateChange() == ItemEvent.SELECTED) {
double scale = map.getScale();
final Object value = e.getItem();
if (value instanceof Double) {
scale = (Double)value;
}
map.setScale(scale);
}
}
}
@Override
public void propertyChange(final PropertyChangeEvent event) {
final MapPanel map = getMap();
if (map != null) {
final String propertyName = event.getPropertyName();
if ("scale".equals(propertyName)) {
final double scale = map.getScale();
double currentScale = 0;
final Object currentValue = getSelectedItem();
if (currentValue instanceof Number) {
currentScale = ((Number)currentValue).doubleValue();
} else if (Property.hasValue(currentValue)) {
final String scaleString = currentValue.toString()
.replaceAll("1:", "")
.replaceAll("[^0-9\\.]+", "");
if (Property.hasValue(scaleString)) {
try {
currentScale = Double.valueOf(scaleString);
} catch (final Throwable t) {
}
}
}
final Number newValue = (Number)event.getNewValue();
if (scale > 0 && !Double.isInfinite(scale) && !Double.isNaN(scale)) {
if (currentScale != newValue.doubleValue()) {
Invoke.later(() -> setSelectedItem(scale));
}
}
}
}
}
}