Changeset 2361 in josm
- Timestamp:
- 2009-10-31T17:06:05+01:00 (15 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/download/BoundingBoxSelection.java
r2334 r2361 39 39 40 40 private JTextField[] latlon = null; 41 final JTextArea osmUrl = new JTextArea(); 42 final JTextArea showUrl = new JTextArea(); 41 private final JTextArea osmUrl = new JTextArea(); 42 private final JTextArea showUrl = new JTextArea(); 43 private DownloadDialog parent; 43 44 44 45 … … 54 55 latlon[0].addActionListener(latChecker); 55 56 56 latChecker = new LatValueChecker(latlon[ 3]);57 latChecker = new LatValueChecker(latlon[2]); 57 58 latlon[2].addFocusListener(latChecker); 58 59 latlon[2].addActionListener(latChecker); … … 72 73 JPanel dlg = new JPanel(new GridBagLayout()); 73 74 74 class osmUrlRefresher implements DocumentListener { 75 public void changedUpdate(DocumentEvent e) { parseURL(gui); } 76 public void insertUpdate(DocumentEvent e) { parseURL(gui); } 77 public void removeUpdate(DocumentEvent e) { parseURL(gui); } 78 } 79 80 osmUrl.getDocument().addDocumentListener(new osmUrlRefresher()); 75 osmUrl.getDocument().addDocumentListener(new OsmUrlRefresher()); 81 76 82 77 // select content on receiving focus. this seems to be the default in the … … 104 99 105 100 gui.addDownloadAreaSelector(dlg, tr("Bounding Box")); 101 this.parent = gui; 106 102 } 107 103 … … 184 180 return; 185 181 } 182 setErrorMessage(null); 186 183 } 187 184 … … 225 222 return; 226 223 } 224 setErrorMessage(null); 227 225 } 228 226 … … 248 246 } 249 247 } 248 249 class OsmUrlRefresher implements DocumentListener { 250 public void changedUpdate(DocumentEvent e) { parseURL(parent); } 251 public void insertUpdate(DocumentEvent e) { parseURL(parent); } 252 public void removeUpdate(DocumentEvent e) { parseURL(parent); } 253 } 250 254 } -
trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java
r2332 r2361 3 3 import static org.openstreetmap.josm.tools.I18n.tr; 4 4 5 import java.awt.BorderLayout; 5 6 import java.awt.Component; 6 import java.awt.Cursor;7 7 import java.awt.Dimension; 8 import java.awt.GridBagConstraints; 8 9 import java.awt.GridBagLayout; 10 import java.awt.Insets; 9 11 import java.awt.event.ActionEvent; 10 import java.awt.event.ActionListener;11 12 import java.awt.event.MouseAdapter; 12 13 import java.awt.event.MouseEvent; 14 import java.io.IOException; 13 15 import java.io.InputStream; 14 16 import java.io.InputStreamReader; 15 17 import java.net.HttpURLConnection; 16 18 import java.net.URL; 17 19 import java.util.ArrayList; 20 import java.util.LinkedList; 21 import java.util.List; 22 import java.util.StringTokenizer; 23 24 import javax.swing.AbstractAction; 25 import javax.swing.BorderFactory; 26 import javax.swing.DefaultListSelectionModel; 18 27 import javax.swing.JButton; 19 import javax.swing.JComponent;20 28 import javax.swing.JLabel; 21 import javax.swing.JOptionPane;22 29 import javax.swing.JPanel; 23 30 import javax.swing.JScrollPane; … … 25 32 import javax.swing.JTextField; 26 33 import javax.swing.ListSelectionModel; 34 import javax.swing.UIManager; 35 import javax.swing.event.DocumentEvent; 36 import javax.swing.event.DocumentListener; 27 37 import javax.swing.event.ListSelectionEvent; 28 38 import javax.swing.event.ListSelectionListener; 29 import javax.swing.table.DefaultTableC ellRenderer;39 import javax.swing.table.DefaultTableColumnModel; 30 40 import javax.swing.table.DefaultTableModel; 41 import javax.swing.table.TableCellRenderer; 42 import javax.swing.table.TableColumn; 31 43 import javax.xml.parsers.SAXParserFactory; 32 44 … … 34 46 import org.openstreetmap.josm.data.Bounds; 35 47 import org.openstreetmap.josm.data.coor.LatLon; 36 import org.openstreetmap.josm.tools.GBC; 48 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 49 import org.openstreetmap.josm.gui.ExceptionDialogUtil; 50 import org.openstreetmap.josm.gui.PleaseWaitRunnable; 51 import org.openstreetmap.josm.io.OsmTransferException; 52 import org.openstreetmap.josm.tools.ImageProvider; 37 53 import org.xml.sax.Attributes; 38 54 import org.xml.sax.InputSource; … … 42 58 public class PlaceSelection implements DownloadSelection { 43 59 44 private JTextField searchTerm = new JTextField(); 45 private JButton submitSearch = new JButton(tr("Search...")); 46 private DefaultTableModel searchResults = new DefaultTableModel() { 47 @Override public boolean isCellEditable(int row, int col) { return false; } 48 }; 49 private JTable searchResultDisplay = new JTable(searchResults); 50 private boolean updatingSelf; 51 52 /** 53 * Data storage for search results. 54 */ 55 class SearchResult 56 { 57 public String name; 58 public String type; 59 public String nearestPlace; 60 public String description; 61 public double lat; 62 public double lon; 63 public int zoom; 64 } 65 66 /** 67 * A very primitive parser for the name finder's output. 68 * Structure of xml described here: http://wiki.openstreetmap.org/index.php/Name_finder 69 * 70 */ 71 private class Parser extends DefaultHandler 72 { 73 private SearchResult currentResult = null; 74 private StringBuffer description = null; 75 private int depth = 0; 76 /** 77 * Detect starting elements. 78 * 79 */ 80 @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException 81 { 82 depth++; 83 try 84 { 85 if (qName.equals("searchresults")) 86 { 87 searchResults.setRowCount(0); 88 } 89 else if (qName.equals("named") && (depth == 2)) 90 { 91 currentResult = new PlaceSelection.SearchResult(); 92 currentResult.name = atts.getValue("name"); 93 currentResult.type = atts.getValue("info"); 94 currentResult.lat = Double.parseDouble(atts.getValue("lat")); 95 currentResult.lon = Double.parseDouble(atts.getValue("lon")); 96 currentResult.zoom = Integer.parseInt(atts.getValue("zoom")); 97 searchResults.addRow(new Object[] { currentResult, currentResult, currentResult, currentResult }); 98 } 99 else if (qName.equals("description") && (depth == 3)) 100 { 101 description = new StringBuffer(); 102 } 103 else if (qName.equals("named") && (depth == 4)) 104 { 105 // this is a "named" place in the nearest places list. 106 String info = atts.getValue("info"); 107 if ("city".equals(info) || "town".equals(info) || "village".equals(info)) { 108 currentResult.nearestPlace = atts.getValue("name"); 109 } 110 } 111 } 112 catch (NumberFormatException x) 113 { 114 x.printStackTrace(); // SAXException does not chain correctly 115 throw new SAXException(x.getMessage(), x); 116 } 117 catch (NullPointerException x) 118 { 119 x.printStackTrace(); // SAXException does not chain correctly 120 throw new SAXException(tr("Null pointer exception, possibly some missing tags."), x); 121 } 122 } 123 /** 124 * Detect ending elements. 125 */ 126 @Override public void endElement(String namespaceURI, String localName, String qName) throws SAXException 127 { 128 129 if (qName.equals("searchresults")) 130 { 131 } 132 else if (qName.equals("description") && description != null) 133 { 134 currentResult.description = description.toString(); 135 description = null; 136 } 137 depth--; 138 139 } 140 /** 141 * Read characters for description. 142 */ 143 @Override public void characters(char[] data, int start, int length) throws org.xml.sax.SAXException 144 { 145 if (description != null) 146 { 147 description.append(data, start, length); 148 } 149 } 150 } 151 152 /** 153 * This queries David Earl's server. Needless to say, stuff should be configurable, and 154 * error handling improved. 155 */ 156 public void queryServer(final JComponent component) 157 { 158 final Cursor oldCursor = component.getCursor(); 159 160 // had to put this in a thread as it wouldn't update the cursor properly before. 161 Runnable r = new Runnable() { 162 public void run() { 163 try 164 { 165 String searchtext = searchTerm.getText(); 166 if(searchtext.length()==0) 167 { 168 JOptionPane.showMessageDialog( 169 Main.parent, 170 tr("Please enter a search string"), 171 tr("Information"), 172 JOptionPane.INFORMATION_MESSAGE 173 ); 174 } 175 else 176 { 177 component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); 178 component.repaint(); 179 URL url = new URL("http://gazetteer.openstreetmap.org/namefinder/search.xml?find=" 180 +java.net.URLEncoder.encode(searchTerm.getText(), "UTF-8")); 181 HttpURLConnection activeConnection = (HttpURLConnection)url.openConnection(); 182 //System.out.println("got return: "+activeConnection.getResponseCode()); 183 activeConnection.setConnectTimeout(15000); 184 InputStream inputStream = activeConnection.getInputStream(); 185 InputSource inputSource = new InputSource(new InputStreamReader(inputStream, "UTF-8")); 186 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser()); 187 } 188 } 189 catch (Exception x) 190 { 191 x.printStackTrace(); 192 JOptionPane.showMessageDialog( 193 Main.parent, 194 tr("Cannot read place search results from server"), 195 tr("Error"), 196 JOptionPane.ERROR_MESSAGE 197 ); 198 } 199 component.setCursor(oldCursor); 200 } 201 }; 202 new Thread(r).start(); 60 private JTextField tfSearchExpression; 61 private JButton btnSearch; 62 private NamedResultTableModel model; 63 private JTable tblSearchResults; 64 private DownloadDialog parent; 65 66 protected JPanel buildSearchPanel() { 67 JPanel panel = new JPanel(); 68 panel.setLayout(new GridBagLayout()); 69 GridBagConstraints gc = new GridBagConstraints(); 70 71 // the label for the search field 72 // 73 gc.gridwidth = 2; 74 gc.fill = GridBagConstraints.HORIZONTAL; 75 gc.weightx =1.0; 76 gc.insets = new Insets(5, 5, 0, 5); 77 panel.add(new JLabel(tr("Enter a place name to search for:")), gc); 78 79 // the search expression field 80 // 81 tfSearchExpression = new JTextField(); 82 tfSearchExpression.setToolTipText(tr("Enter a place name to search for")); 83 gc.gridx = 0; 84 gc.gridy = 1; 85 gc.gridwidth = 1; 86 panel.add(tfSearchExpression, gc); 87 88 // the search button 89 // 90 SearchAction searchAction = new SearchAction(); 91 btnSearch = new JButton(searchAction); 92 tfSearchExpression.getDocument().addDocumentListener(searchAction); 93 tfSearchExpression.addActionListener(searchAction); 94 95 gc.gridx = 1; 96 gc.gridy = 1; 97 gc.fill = GridBagConstraints.HORIZONTAL; 98 gc.weightx = 0.0; 99 panel.add(btnSearch, gc); 100 101 return panel; 203 102 } 204 103 … … 210 109 public void addGui(final DownloadDialog gui) { 211 110 JPanel panel = new JPanel(); 212 panel.setLayout(new GridBagLayout()); 213 214 // this is manually tuned so that it looks nice on a GNOME 215 // desktop - maybe needs some cross platform proofing. 216 panel.add(new JLabel(tr("Enter a place name to search for:")), GBC.eol().insets(5, 5, 5, 5)); 217 panel.add(searchTerm, GBC.std().fill(GBC.HORIZONTAL).insets(5, 0, 5, 4)); 218 panel.add(submitSearch, GBC.eol().insets(5, 0, 5, 5)); 219 Dimension btnSize = submitSearch.getPreferredSize(); 220 btnSize.setSize(btnSize.width, btnSize.height * 0.8); 221 submitSearch.setPreferredSize(btnSize); 222 223 GBC c = GBC.std().fill().insets(5, 0, 5, 5); 224 c.gridwidth = 2; 225 JScrollPane scrollPane = new JScrollPane(searchResultDisplay); 111 panel.setLayout(new BorderLayout()); 112 panel.add(buildSearchPanel(), BorderLayout.NORTH); 113 114 DefaultListSelectionModel selectionModel = new DefaultListSelectionModel(); 115 model = new NamedResultTableModel(selectionModel); 116 tblSearchResults = new JTable(model, new NamedResultTableColumnModel()); 117 tblSearchResults.setSelectionModel(selectionModel); 118 JScrollPane scrollPane = new JScrollPane(tblSearchResults); 226 119 scrollPane.setPreferredSize(new Dimension(200,200)); 227 panel.add(scrollPane, c); 228 gui.addDownloadAreaSelector(panel, tr("Places")); 229 230 scrollPane.setPreferredSize(scrollPane.getPreferredSize()); 231 232 // when the button is clicked 233 submitSearch.addActionListener(new ActionListener() { 234 public void actionPerformed(ActionEvent e) { 235 queryServer(gui.getRootPane()); 236 } 237 }); 238 239 searchTerm.addActionListener(new ActionListener() { 240 public void actionPerformed(ActionEvent e) { 241 queryServer(gui.getRootPane()); 242 } 243 }); 244 245 searchResults.addColumn(tr("name")); 246 searchResults.addColumn(tr("type")); 247 searchResults.addColumn(tr("near")); 248 searchResults.addColumn(tr("zoom")); 249 250 // TODO - this is probably not the coolest way to set relative sizes? 251 searchResultDisplay.getColumn(tr("name")).setPreferredWidth(200); 252 searchResultDisplay.getColumn(tr("type")).setPreferredWidth(100); 253 searchResultDisplay.getColumn(tr("near")).setPreferredWidth(100); 254 searchResultDisplay.getColumn(tr("zoom")).setPreferredWidth(50); 255 searchResultDisplay.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 256 257 // display search results in a table. for simplicity, the table contains 258 // the same SearchResult object in each of the four columns, but it is rendered 259 // differently depending on the column. 260 searchResultDisplay.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { 261 @Override public Component getTableCellRendererComponent(JTable table, Object value, 262 boolean isSelected, boolean hasFocus, int row, int column) { 263 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 264 if (value != null) { 265 SearchResult sr = (SearchResult) value; 266 switch(column) { 267 case 0: 268 setText(sr.name); 269 break; 270 case 1: 271 setText(sr.type); 272 break; 273 case 2: 274 setText(sr.nearestPlace); 275 break; 276 case 3: 277 setText(Integer.toString(sr.zoom)); 278 break; 279 } 280 setToolTipText("<html>"+((SearchResult)value).description+"</html>"); 281 } 282 return this; 283 } 284 }); 285 286 // if item is selected in list, notify dialog 287 searchResultDisplay.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 288 public void valueChanged(ListSelectionEvent lse) { 289 if (lse.getValueIsAdjusting()) return; 290 SearchResult r = null; 291 try 292 { 293 r = (SearchResult) searchResults.getValueAt(lse.getFirstIndex(), 0); 294 } 295 catch (Exception x) 296 { 297 // Ignore 298 } 299 if (r != null) 300 { 301 double size = 180.0 / Math.pow(2, r.zoom); 302 Bounds b = new Bounds( 303 new LatLon( 304 r.lat - size / 2, 305 r.lat + size / 2 306 ), 307 new LatLon( 308 r.lon - size, 309 r.lon + size 310 ) 311 ); 312 gui.boundingBoxChanged(b,null); 313 } 314 } 315 }); 316 317 // TODO - we'd like to finish the download dialog upon double-click but 318 // don't know how to bypass the JOptionPane in which the whole thing is 319 // displayed. 320 searchResultDisplay.addMouseListener(new MouseAdapter() { 120 panel.add(scrollPane, BorderLayout.CENTER); 121 122 gui.addDownloadAreaSelector(panel, tr("Areas around Places")); 123 124 scrollPane.setPreferredSize(scrollPane.getPreferredSize()); 125 tblSearchResults.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 126 tblSearchResults.getSelectionModel().addListSelectionListener(new ListSelectionHandler()); 127 tblSearchResults.addMouseListener(new MouseAdapter() { 321 128 @Override public void mouseClicked(MouseEvent e) { 322 129 if (e.getClickCount() > 1) { 323 if (searchResultDisplay.getSelectionModel().getMinSelectionIndex() > -1) { 324 // add sensible action here. 130 SearchResult sr = model.getSelectedSearchResult(); 131 if (sr == null) return; 132 parent.startDownload(sr.getDownloadArea()); 133 } 134 } 135 }); 136 parent = gui; 137 } 138 139 public void setDownloadArea(Bounds area) { 140 tblSearchResults.clearSelection(); 141 } 142 143 /** 144 * Data storage for search results. 145 */ 146 static private class SearchResult { 147 public String name; 148 public String info; 149 public String nearestPlace; 150 public String description; 151 public double lat; 152 public double lon; 153 public int zoom; 154 public int osmId; 155 public OsmPrimitiveType type; 156 157 public Bounds getDownloadArea() { 158 double size = 180.0 / Math.pow(2, zoom); 159 Bounds b = new Bounds( 160 new LatLon(lat - size / 2, lon - size), 161 new LatLon(lat + size / 2, lon+ size) 162 ); 163 return b; 164 } 165 } 166 167 168 /** 169 * A very primitive parser for the name finder's output. 170 * Structure of xml described here: http://wiki.openstreetmap.org/index.php/Name_finder 171 * 172 */ 173 private class NameFinderResultParser extends DefaultHandler { 174 private SearchResult currentResult = null; 175 private StringBuffer description = null; 176 private int depth = 0; 177 private List<SearchResult> data = new LinkedList<SearchResult>(); 178 179 /** 180 * Detect starting elements. 181 * 182 */ 183 @Override 184 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) 185 throws SAXException { 186 depth++; 187 try { 188 if (qName.equals("searchresults")) { 189 // do nothing 190 } else if (qName.equals("named") && (depth == 2)) { 191 currentResult = new PlaceSelection.SearchResult(); 192 currentResult.name = atts.getValue("name"); 193 currentResult.info = atts.getValue("info"); 194 currentResult.lat = Double.parseDouble(atts.getValue("lat")); 195 currentResult.lon = Double.parseDouble(atts.getValue("lon")); 196 currentResult.zoom = Integer.parseInt(atts.getValue("zoom")); 197 currentResult.osmId = Integer.parseInt(atts.getValue("id")); 198 currentResult.type = OsmPrimitiveType.from(atts.getValue("type")); 199 data.add(currentResult); 200 } else if (qName.equals("description") && (depth == 3)) { 201 description = new StringBuffer(); 202 } else if (qName.equals("named") && (depth == 4)) { 203 // this is a "named" place in the nearest places list. 204 String info = atts.getValue("info"); 205 if ("city".equals(info) || "town".equals(info) || "village".equals(info)) { 206 currentResult.nearestPlace = atts.getValue("name"); 325 207 } 326 208 } 327 } 328 }); 329 330 } 331 332 public void setDownloadArea(Bounds area) { 333 searchResultDisplay.clearSelection(); 209 } catch (NumberFormatException x) { 210 x.printStackTrace(); // SAXException does not chain correctly 211 throw new SAXException(x.getMessage(), x); 212 } catch (NullPointerException x) { 213 x.printStackTrace(); // SAXException does not chain correctly 214 throw new SAXException(tr("Null pointer exception, possibly some missing tags."), x); 215 } 216 } 217 218 /** 219 * Detect ending elements. 220 */ 221 @Override 222 public void endElement(String namespaceURI, String localName, String qName) throws SAXException { 223 if (qName.equals("searchresults")) { 224 } else if (qName.equals("description") && description != null) { 225 currentResult.description = description.toString(); 226 description = null; 227 } 228 depth--; 229 230 } 231 232 /** 233 * Read characters for description. 234 */ 235 @Override 236 public void characters(char[] data, int start, int length) throws org.xml.sax.SAXException { 237 if (description != null) { 238 description.append(data, start, length); 239 } 240 } 241 242 public List<SearchResult> getResult() { 243 return data; 244 } 245 } 246 247 class SearchAction extends AbstractAction implements DocumentListener { 248 249 public SearchAction() { 250 putValue(NAME, tr("Search ...")); 251 putValue(SMALL_ICON, ImageProvider.get("dialogs","search")); 252 putValue(SHORT_DESCRIPTION, tr("Click to start searching for places")); 253 updateEnabledState(); 254 } 255 256 public void actionPerformed(ActionEvent e) { 257 if (!isEnabled() || tfSearchExpression.getText().trim().length() == 0) 258 return; 259 NameQueryTask task = new NameQueryTask(tfSearchExpression.getText()); 260 Main.worker.submit(task); 261 } 262 263 protected void updateEnabledState() { 264 setEnabled(tfSearchExpression.getText().trim().length() > 0); 265 } 266 267 public void changedUpdate(DocumentEvent e) { 268 updateEnabledState(); 269 } 270 271 public void insertUpdate(DocumentEvent e) { 272 updateEnabledState(); 273 } 274 275 public void removeUpdate(DocumentEvent e) { 276 updateEnabledState(); 277 } 278 } 279 280 281 class NameQueryTask extends PleaseWaitRunnable { 282 283 private String searchExpression; 284 private HttpURLConnection connection; 285 private List<SearchResult> data; 286 private boolean canceled = false; 287 private Exception lastException; 288 289 public NameQueryTask(String searchExpression) { 290 super(tr("Querying name server"),false /* don't ignore exceptions */); 291 this.searchExpression = searchExpression; 292 } 293 294 295 @Override 296 protected void cancel() { 297 this.canceled = true; 298 synchronized (this) { 299 if (connection != null) { 300 connection.disconnect(); 301 } 302 } 303 } 304 305 @Override 306 protected void finish() { 307 if (canceled) 308 return; 309 if (lastException != null) { 310 ExceptionDialogUtil.explainException(lastException); 311 return; 312 } 313 model.setData(this.data); 314 } 315 316 @Override 317 protected void realRun() throws SAXException, IOException, OsmTransferException { 318 try { 319 getProgressMonitor().indeterminateSubTask(tr("Querying name server ...")); 320 URL url = new URL("http://gazetteer.openstreetmap.org/namefinder/search.xml?find=" 321 +java.net.URLEncoder.encode(searchExpression, "UTF-8")); 322 synchronized(this) { 323 connection = (HttpURLConnection)url.openConnection(); 324 } 325 connection.setConnectTimeout(15000); 326 InputStream inputStream = connection.getInputStream(); 327 InputSource inputSource = new InputSource(new InputStreamReader(inputStream, "UTF-8")); 328 NameFinderResultParser parser = new NameFinderResultParser(); 329 SAXParserFactory.newInstance().newSAXParser().parse(inputSource, parser); 330 this.data = parser.getResult(); 331 } catch(Exception e) { 332 if (canceled) { 333 // ignore exception 334 return; 335 } 336 lastException = e; 337 } 338 } 339 } 340 341 class NamedResultTableModel extends DefaultTableModel { 342 private ArrayList<SearchResult> data; 343 private ListSelectionModel selectionModel; 344 345 public NamedResultTableModel(ListSelectionModel selectionModel) { 346 data = new ArrayList<SearchResult>(); 347 this.selectionModel = selectionModel; 348 } 349 @Override 350 public int getRowCount() { 351 if (data == null) return 0; 352 return data.size(); 353 } 354 355 @Override 356 public Object getValueAt(int row, int column) { 357 if (data == null) return null; 358 return data.get(row); 359 } 360 361 public void setData(List<SearchResult> data) { 362 if (data == null) { 363 this.data.clear(); 364 } else { 365 this.data =new ArrayList<SearchResult>(data); 366 } 367 fireTableDataChanged(); 368 } 369 @Override 370 public boolean isCellEditable(int row, int column) { 371 return false; 372 } 373 374 public SearchResult getSelectedSearchResult() { 375 if (selectionModel.getMinSelectionIndex() < 0) { 376 return null; 377 } 378 return data.get(selectionModel.getMinSelectionIndex()); 379 } 380 } 381 382 class NamedResultTableColumnModel extends DefaultTableColumnModel { 383 protected void createColumns() { 384 TableColumn col = null; 385 NamedResultCellRenderer renderer = new NamedResultCellRenderer(); 386 387 // column 0 - Name 388 col = new TableColumn(0); 389 col.setHeaderValue(tr("Name")); 390 col.setResizable(true); 391 col.setPreferredWidth(200); 392 col.setCellRenderer(renderer); 393 addColumn(col); 394 395 // column 1 - Version 396 col = new TableColumn(1); 397 col.setHeaderValue(tr("Type")); 398 col.setResizable(true); 399 col.setPreferredWidth(100); 400 col.setCellRenderer(renderer); 401 addColumn(col); 402 403 // column 2 - Near 404 col = new TableColumn(2); 405 col.setHeaderValue(tr("Near")); 406 col.setResizable(true); 407 col.setPreferredWidth(100); 408 col.setCellRenderer(renderer); 409 addColumn(col); 410 411 412 // column 3 - Zoom 413 col = new TableColumn(3); 414 col.setHeaderValue(tr("Zoom")); 415 col.setResizable(true); 416 col.setPreferredWidth(50); 417 col.setCellRenderer(renderer); 418 addColumn(col); 419 } 420 421 public NamedResultTableColumnModel() { 422 createColumns(); 423 } 424 } 425 426 class ListSelectionHandler implements ListSelectionListener { 427 public void valueChanged(ListSelectionEvent lse) { 428 SearchResult r = null; 429 try { 430 r = (SearchResult) model.getValueAt(lse.getFirstIndex(), 0); 431 } catch (Exception x) { 432 // Ignore 433 } 434 if (r != null) { 435 parent.boundingBoxChanged(r.getDownloadArea(), PlaceSelection.this); 436 } 437 } 438 } 439 440 class NamedResultCellRenderer extends JLabel implements TableCellRenderer { 441 public NamedResultCellRenderer() { 442 setOpaque(true); 443 setBorder(BorderFactory.createEmptyBorder(2,2,2,2)); 444 } 445 446 protected void reset() { 447 setText(""); 448 setIcon(null); 449 } 450 451 protected void renderColor(boolean selected) { 452 if (selected) { 453 setForeground(UIManager.getColor("Table.selectionForeground")); 454 setBackground(UIManager.getColor("Table.selectionBackground")); 455 } else { 456 setForeground(UIManager.getColor("Table.foreground")); 457 setBackground(UIManager.getColor("Table.background")); 458 } 459 } 460 461 protected String lineWrapDescription(String description) { 462 StringBuffer ret = new StringBuffer(); 463 StringBuffer line = new StringBuffer(); 464 StringTokenizer tok = new StringTokenizer(description, " "); 465 while(tok.hasMoreElements()) { 466 String t = tok.nextToken(); 467 if (line.length() == 0) { 468 line.append(t); 469 } else if (line.length() < 80) { 470 line.append(" ").append(t); 471 } else { 472 line.append(" ").append(t).append("<br>"); 473 ret.append(line); 474 line = new StringBuffer(); 475 } 476 } 477 ret.insert(0, "<html>"); 478 ret.append("</html>"); 479 return ret.toString(); 480 } 481 482 public Component getTableCellRendererComponent(JTable table, Object value, 483 boolean isSelected, boolean hasFocus, int row, int column) { 484 485 reset(); 486 renderColor(isSelected); 487 488 if (value == null) return this; 489 SearchResult sr = (SearchResult) value; 490 switch(column) { 491 case 0: 492 setText(sr.name); 493 break; 494 case 1: 495 setText(sr.info); 496 break; 497 case 2: 498 setText(sr.nearestPlace); 499 break; 500 case 3: 501 setText(Integer.toString(sr.zoom)); 502 break; 503 } 504 setToolTipText(lineWrapDescription(sr.description)); 505 return this; 506 } 334 507 } 335 508 } -
trunk/src/org/openstreetmap/josm/io/OsmServerBackreferenceReader.java
r2303 r2361 83 83 * 84 84 * @param id the id of the primitive. > 0 expected 85 * @param type the type of the primitive. Must not be null.86 85 * @param readFull true, if referers should be read fully (i.e. including their immediate children) 87 86 *
Note:
See TracChangeset
for help on using the changeset viewer.