001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.projection;
003
004import java.awt.GridBagLayout;
005import java.awt.event.ActionListener;
006import java.util.Collection;
007import java.util.Collections;
008
009import javax.swing.JLabel;
010import javax.swing.JPanel;
011
012import org.openstreetmap.josm.gui.widgets.JosmComboBox;
013import org.openstreetmap.josm.tools.GBC;
014import org.openstreetmap.josm.tools.Utils;
015
016/**
017 * A projection choice, that offers a list of projections in a combo-box.
018 */
019public abstract class ListProjectionChoice extends AbstractProjectionChoice {
020
021    protected int index;        // 0-based index
022    protected int defaultIndex;
023    protected String[] entries;
024    protected String label;
025
026    /**
027     * Constructs a new {@code ListProjectionChoice}.
028     *
029     * @param name the display name
030     * @param id the unique id for this ProjectionChoice
031     * @param entries the list of display entries for the combo-box
032     * @param label a label shown left to the combo-box
033     * @param defaultIndex the default index for the combo-box
034     */
035    public ListProjectionChoice(String name, String id, String[] entries, String label, int defaultIndex) {
036        super(name, id);
037        this.entries = Utils.copyArray(entries);
038        this.label = label;
039        this.defaultIndex = defaultIndex;
040    }
041
042    /**
043     * Constructs a new {@code ListProjectionChoice}.
044     * @param name the display name
045     * @param id the unique id for this ProjectionChoice
046     * @param entries the list of display entries for the combo-box
047     * @param label a label shown left to the combo-box
048     */
049    public ListProjectionChoice(String name, String id, String[] entries, String label) {
050        this(name, id, entries, label, 0);
051    }
052
053    /**
054     * Convert 0-based index to preference value.
055     */
056    protected abstract String indexToZone(int idx);
057
058    /**
059     * Convert preference value to 0-based index.
060     */
061    protected abstract int zoneToIndex(String zone);
062
063    @Override
064    public void setPreferences(Collection<String> args) {
065        String zone = null;
066        if (args != null && args.size() >= 1) {
067            zone = args.iterator().next();
068        }
069        int idx;
070        if (zone == null) {
071            idx = defaultIndex;
072        } else {
073            idx = zoneToIndex(zone);
074            if (idx < 0 || idx >= entries.length) {
075                idx = defaultIndex;
076            }
077        }
078        this.index = idx;
079    }
080
081    protected class CBPanel extends JPanel {
082        public JosmComboBox<String> prefcb;
083
084        public CBPanel(String[] entries, int initialIndex, String label, final ActionListener listener) {
085            prefcb = new JosmComboBox<>(entries);
086
087            prefcb.setSelectedIndex(initialIndex);
088            this.setLayout(new GridBagLayout());
089            this.add(new JLabel(label), GBC.std().insets(5,5,0,5));
090            this.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL));
091            this.add(prefcb, GBC.eop().fill(GBC.HORIZONTAL));
092            this.add(GBC.glue(1, 1), GBC.eol().fill(GBC.BOTH));
093
094            if (listener != null) {
095                prefcb.addActionListener(listener);
096            }
097        }
098    }
099
100    @Override
101    public JPanel getPreferencePanel(ActionListener listener) {
102        return new CBPanel(entries, index, label, listener);
103    }
104
105    @Override
106    public Collection<String> getPreferences(JPanel panel) {
107        if (!(panel instanceof CBPanel)) {
108            throw new IllegalArgumentException("Unsupported panel: "+panel);
109        }
110        CBPanel p = (CBPanel) panel;
111        int idx = p.prefcb.getSelectedIndex();
112        return Collections.singleton(indexToZone(idx));
113    }
114}