001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui.widgets; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.util.ArrayList; 007 import java.util.List; 008 import java.util.StringTokenizer; 009 010 import javax.swing.JTextField; 011 import javax.swing.text.JTextComponent; 012 013 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 014 import org.openstreetmap.josm.data.osm.PrimitiveId; 015 import org.openstreetmap.josm.data.osm.SimplePrimitiveId; 016 import org.openstreetmap.josm.tools.Utils; 017 018 /** 019 * @author Matthias Julius 020 */ 021 public class OsmIdTextField extends JTextField { 022 023 private OsmIdValidator validator; 024 025 public OsmIdTextField() { 026 validator = OsmIdValidator.decorate(this); 027 } 028 029 public void setType(OsmPrimitiveType type) { 030 validator.type = type; 031 } 032 033 /** 034 * Get entered ID list - supports "1,2,3" "1 2 ,3" or even "1 2 3 v2 6 v8" 035 * @return list of id's 036 */ 037 public List<PrimitiveId> getIds() { 038 return validator.ids; 039 } 040 041 public boolean readOsmIds() { 042 return validator.readOsmIds(); 043 } 044 045 public void performValidation() { 046 validator.validate(); 047 } 048 049 public void clearTextIfInvalid() { 050 if (!validator.isValid()) 051 setText(""); 052 validator.validate(); 053 } 054 055 /** 056 * Validator for a changeset ID entered in a {@link JTextComponent}. 057 * 058 */ 059 static private class OsmIdValidator extends AbstractTextComponentValidator { 060 061 static public OsmIdValidator decorate(JTextComponent tc) { 062 return new OsmIdValidator(tc); 063 } 064 065 private List<PrimitiveId> ids = new ArrayList<PrimitiveId>(); 066 private OsmPrimitiveType type; 067 068 public OsmIdValidator(JTextComponent tc) { 069 super(tc, false); 070 } 071 072 @Override 073 public boolean isValid() { 074 return readOsmIds(); 075 } 076 077 @Override 078 public void validate() { 079 if (!isValid()) { 080 feedbackInvalid(tr("The current value is not a valid OSM ID. Please enter an integer value > 0")); 081 } else { 082 feedbackValid(tr("Please enter an integer value > 0")); 083 } 084 } 085 086 public boolean readOsmIds() { 087 String value = getComponent().getText(); 088 char c; 089 if (value == null || value.trim().length() == 0) { 090 return false; 091 } 092 ids.clear(); 093 StringTokenizer st = new StringTokenizer(value, ",.+/ \t\n"); 094 String s; 095 while (st.hasMoreTokens()) { 096 s = st.nextToken(); 097 // convert tokens to int skipping v-words (version v2 etc) 098 c = s.charAt(0); 099 if (c == 'v') { 100 continue; 101 } else { 102 try { 103 ids.add(SimplePrimitiveId.fromString(s)); 104 } catch (IllegalArgumentException ex) { 105 try { 106 if (type == OsmPrimitiveType.NODE) { 107 ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.NODE)); 108 } else if (type == OsmPrimitiveType.WAY) { 109 ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.WAY)); 110 } else if (type == OsmPrimitiveType.RELATION) { 111 ids.add(new SimplePrimitiveId(Long.parseLong(s), OsmPrimitiveType.RELATION)); 112 } else { 113 return false; 114 } 115 } catch (IllegalArgumentException ex2) { 116 return false; 117 } 118 } 119 } 120 } 121 return true; 122 } 123 } 124 }