001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences.projection; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.event.ActionListener; 007import java.io.Serializable; 008import java.util.Collection; 009import java.util.Collections; 010import java.util.Comparator; 011import java.util.regex.Matcher; 012import java.util.regex.Pattern; 013 014import javax.swing.JPanel; 015 016import org.openstreetmap.josm.data.projection.Projection; 017import org.openstreetmap.josm.data.projection.Projections; 018import org.openstreetmap.josm.tools.Utils; 019 020/** 021 * Projection choice that lists all known projects by code. 022 * @since 5634 023 */ 024public class CodeProjectionChoice extends AbstractProjectionChoice implements SubPrefsOptions { 025 026 private String code; 027 028 /** 029 * Constructs a new {@code CodeProjectionChoice}. 030 */ 031 public CodeProjectionChoice() { 032 super(tr("By Code (EPSG)"), /* NO-ICON */ "core:code"); 033 } 034 035 /** 036 * Comparator that compares the number part of the code numerically. 037 */ 038 public static class CodeComparator implements Comparator<String>, Serializable { 039 private static final long serialVersionUID = 1L; 040 private final Pattern codePattern = Pattern.compile("([a-zA-Z]+):(\\d+)"); 041 042 @Override 043 public int compare(String c1, String c2) { 044 Matcher matcher1 = codePattern.matcher(c1); 045 Matcher matcher2 = codePattern.matcher(c2); 046 if (matcher1.matches()) { 047 if (matcher2.matches()) { 048 int cmp1 = matcher1.group(1).compareTo(matcher2.group(1)); 049 if (cmp1 != 0) 050 return cmp1; 051 int num1 = Integer.parseInt(matcher1.group(2)); 052 int num2 = Integer.parseInt(matcher2.group(2)); 053 return Integer.compare(num1, num2); 054 } else 055 return -1; 056 } else if (matcher2.matches()) 057 return 1; 058 return c1.compareTo(c2); 059 } 060 } 061 062 @Override 063 public Projection getProjection() { 064 return Projections.getProjectionByCode(code); 065 } 066 067 @Override 068 public String getCurrentCode() { 069 // not needed - getProjection() is overridden 070 throw new UnsupportedOperationException(); 071 } 072 073 @Override 074 public String getProjectionName() { 075 // not needed - getProjection() is overridden 076 throw new UnsupportedOperationException(); 077 } 078 079 @Override 080 public void setPreferences(Collection<String> args) { 081 if (!Utils.isEmpty(args)) { 082 code = args.iterator().next(); 083 } 084 } 085 086 @Override 087 public JPanel getPreferencePanel(ActionListener listener) { 088 return new CodeSelectionPanel(code, listener); 089 } 090 091 @Override 092 public Collection<String> getPreferences(JPanel panel) { 093 if (!(panel instanceof CodeSelectionPanel)) { 094 throw new IllegalArgumentException("Unsupported panel: "+panel); 095 } 096 CodeSelectionPanel csPanel = (CodeSelectionPanel) panel; 097 return Collections.singleton(csPanel.getCode()); 098 } 099 100 /* don't return all possible codes - this projection choice it too generic */ 101 @Override 102 public String[] allCodes() { 103 return new String[0]; 104 } 105 106 /* not needed since allCodes() returns empty array */ 107 @Override 108 public Collection<String> getPreferencesFromCode(String code) { 109 return null; 110 } 111 112 @Override 113 public boolean showProjectionCode() { 114 return true; 115 } 116 117 @Override 118 public boolean showProjectionName() { 119 return true; 120 } 121 122}