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 protected 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 protected 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 * @param idx 0-based index 056 * @return preference value 057 * @see #zoneToIndex 058 */ 059 protected abstract String indexToZone(int idx); 060 061 /** 062 * Convert preference value to 0-based index. 063 * @param zone preference value 064 * @return 0-based index 065 * @see #indexToZone 066 */ 067 protected abstract int zoneToIndex(String zone); 068 069 @Override 070 public void setPreferences(Collection<String> args) { 071 String zone = null; 072 if (!Utils.isEmpty(args)) { 073 zone = args.iterator().next(); 074 } 075 int idx; 076 if (zone == null) { 077 idx = defaultIndex; 078 } else { 079 idx = zoneToIndex(zone); 080 if (idx < 0 || idx >= entries.length) { 081 idx = defaultIndex; 082 } 083 } 084 this.index = idx; 085 } 086 087 protected static class CBPanel extends JPanel { 088 public JosmComboBox<String> prefcb; 089 090 public CBPanel(String[] entries, int initialIndex, String label, final ActionListener listener) { 091 prefcb = new JosmComboBox<>(entries); 092 093 prefcb.setSelectedIndex(initialIndex); 094 this.setLayout(new GridBagLayout()); 095 this.add(new JLabel(label), GBC.std().insets(5, 5, 0, 5)); 096 this.add(GBC.glue(1, 0), GBC.std().fill(GBC.HORIZONTAL)); 097 this.add(prefcb, GBC.eop().fill(GBC.HORIZONTAL)); 098 this.add(GBC.glue(1, 1), GBC.eol().fill(GBC.BOTH)); 099 100 if (listener != null) { 101 prefcb.addActionListener(listener); 102 } 103 } 104 } 105 106 @Override 107 public JPanel getPreferencePanel(ActionListener listener) { 108 return new CBPanel(entries, index, label, listener); 109 } 110 111 @Override 112 public Collection<String> getPreferences(JPanel panel) { 113 if (!(panel instanceof CBPanel)) { 114 throw new IllegalArgumentException("Unsupported panel: "+panel); 115 } 116 CBPanel p = (CBPanel) panel; 117 int idx = p.prefcb.getSelectedIndex(); 118 return Collections.singleton(indexToZone(idx)); 119 } 120}