Ignore:
Timestamp:
2007-08-25T03:07:47+02:00 (17 years ago)
Author:
frederik
Message:

new version with nicer table for results; fixed bug that would close the download dialog on pressing ENTER; added wait cursor

Location:
applications/editors/josm/plugins/namefinder
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/namefinder/README

    r2925 r4307  
    1 A very simple first implementation of a Name Finder that will
    2 add a "place" tab to the download dialog. This is a "proof of concept"
    3 intended for others to build on ;-)
     1A very simple implementation of a Name Finder that will
     2add a "place" tab to the download dialog and connect to
     3David Earl's name finder service to get results.
    44
    5 Frederik Ramm <frederik@remote.org>
     5Author: Frederik Ramm <frederik@remote.org>
     6License: Public Domain
    67
     8(but note, some JOSM components & MinML library are used
     9which may have different licensing.)
  • applications/editors/josm/plugins/namefinder/build.xml

    r3783 r4307  
    2121      <classpath>
    2222        <pathelement path="${josm.prj.dir}/build"/>
     23        <pathelement path="${josm.prj.dir}/src"/>
    2324        <fileset dir="${josm.prj.dir}/lib">
    2425          <include name="**/*.jar"/>
     
    3435        <attribute name="Plugin-Class" value="namefinder.NameFinderPlugin" />
    3536        <attribute name="Plugin-Description" value="Allows selection of download areas by name, using an external service" />
     37        <attribute name="Plugin-Version" value="0.9" />
    3638      </manifest>
    3739    </jar>
  • applications/editors/josm/plugins/namefinder/namefinder/PlaceSelection.java

    r3067 r4307  
    44
    55import java.awt.Component;
     6import java.awt.Cursor;
    67import java.awt.Dimension;
    78import java.awt.GridBagLayout;
    89import java.awt.event.ActionEvent;
    910import java.awt.event.ActionListener;
     11import java.awt.event.MouseAdapter;
     12import java.awt.event.MouseEvent;
    1013import java.io.InputStream;
    1114import java.io.InputStreamReader;
     
    1316import java.net.URL;
    1417
    15 import javax.swing.DefaultListCellRenderer;
    16 import javax.swing.DefaultListModel;
    1718import javax.swing.JButton;
     19import javax.swing.JComponent;
    1820import javax.swing.JLabel;
    19 import javax.swing.JList;
    2021import javax.swing.JOptionPane;
    2122import javax.swing.JPanel;
    2223import javax.swing.JScrollPane;
     24import javax.swing.JTable;
    2325import javax.swing.JTextField;
     26import javax.swing.ListSelectionModel;
    2427import javax.swing.event.ListSelectionEvent;
    2528import javax.swing.event.ListSelectionListener;
     29import javax.swing.table.DefaultTableCellRenderer;
     30import javax.swing.table.DefaultTableModel;
    2631
    2732import org.openstreetmap.josm.Main;
     
    3843        private JTextField searchTerm = new JTextField();
    3944        private JButton submitSearch = new JButton(tr("Search..."));
    40         private DefaultListModel searchResults = new DefaultListModel();
    41         private JList searchResultDisplay = new JList(searchResults);
     45        private DefaultTableModel searchResults = new DefaultTableModel() {
     46                @Override public boolean isCellEditable(int row, int col) { return false; }
     47        };
     48        private JTable searchResultDisplay = new JTable(searchResults);
    4249        private boolean updatingSelf;
    4350       
     
    4855        {
    4956                public String name;
     57                public String type;
     58                public String nearestPlace;
    5059                public String description;
    5160                public double lat;
     
    7584                                if (qName.equals("searchresults"))
    7685                                {
    77                                         searchResults.clear();
     86                                        searchResults.setRowCount(0);
    7887                                }
    7988                                else if (qName.equals("named") && (depth == 2))
     
    8190                                        currentResult = new PlaceSelection.SearchResult();
    8291                                        currentResult.name = atts.getValue("name");
     92                                        currentResult.type = atts.getValue("info");
    8393                                        currentResult.lat = Double.parseDouble(atts.getValue("lat"));
    8494                                        currentResult.lon = Double.parseDouble(atts.getValue("lon"));
    8595                                        currentResult.zoom = Integer.parseInt(atts.getValue("zoom"));
    86                                         searchResults.addElement(currentResult);
     96                                        searchResults.addRow(new Object[] { currentResult, currentResult, currentResult, currentResult });
    8797                                }
    8898                                else if (qName.equals("description") && (depth == 3))
    8999                                {
    90100                                        description = new StringBuffer();
    91                                 }
     101                                }
     102                                else if (qName.equals("named") && (depth == 4))
     103                                {
     104                                        // this is a "named" place in the nearest places list.
     105                                        String info = atts.getValue("info");
     106                                        if ("city".equals(info) || "town".equals(info) || "village".equals(info)) {
     107                                                currentResult.nearestPlace = atts.getValue("name");
     108                                        }
     109                                }
    92110                        }
    93111                        catch (NumberFormatException x)
     
    135153         * error handling improved.
    136154         */
    137         public void queryServer()
     155        public void queryServer(final JComponent component)
    138156        {
    139                 try
    140                 {
    141                         URL url = new URL("http://www.frankieandshadow.com/osm/search.xml?find="+java.net.URLEncoder.encode(searchTerm.getText(), "UTF-8"));
    142                         HttpURLConnection activeConnection = (HttpURLConnection)url.openConnection();
    143                         System.out.println("got return: "+activeConnection.getResponseCode());
    144                         activeConnection.setConnectTimeout(15000);
    145                         InputStream inputStream = activeConnection.getInputStream();
    146                         new Parser().parse(new InputStreamReader(inputStream, "UTF-8"));
    147                 }
    148                 catch (Exception x)
    149                 {
    150                         JOptionPane.showMessageDialog(Main.parent,tr("Cannot read place search results from server"));
    151                         x.printStackTrace();
    152                 }
    153         }
    154        
    155         // add a new tab to the download dialog
     157                final Cursor oldCursor = component.getCursor();
     158               
     159                // had to put this in a thread as it wouldn't update the cursor properly before.
     160                Runnable r = new Runnable() {
     161                        public void run() {
     162                                try
     163                                {
     164                                        component.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
     165                                        component.repaint();
     166                                        URL url = new URL("http://www.frankieandshadow.com/osm/search.xml?find="+java.net.URLEncoder.encode(searchTerm.getText(), "UTF-8"));
     167                                        HttpURLConnection activeConnection = (HttpURLConnection)url.openConnection();
     168                                        System.out.println("got return: "+activeConnection.getResponseCode());
     169                                        activeConnection.setConnectTimeout(15000);
     170                                        InputStream inputStream = activeConnection.getInputStream();
     171                                        new Parser().parse(new InputStreamReader(inputStream, "UTF-8"));
     172                                }
     173                                catch (Exception x)
     174                                {
     175                                        JOptionPane.showMessageDialog(Main.parent,tr("Cannot read place search results from server"));
     176                                        x.printStackTrace();
     177                                }
     178                                component.setCursor(oldCursor);
     179                        }
     180                };
     181                new Thread(r).start();
     182        }
     183       
     184        /**
     185         * Adds a new tab to the download dialog in JOSM.
     186         *
     187         * This method is, for all intents and purposes, the constructor for this class.
     188         */
    156189        public void addGui(final DownloadDialog gui) {
    157190                JPanel panel = new JPanel();
    158191                panel.setLayout(new GridBagLayout());
    159                 panel.add(new JLabel(tr("Enter a place name to search for:")), GBC.eol());
    160                 panel.add(searchTerm, GBC.std().fill(GBC.HORIZONTAL));
    161                 panel.add(submitSearch, GBC.eol());
    162                
    163                 GBC c = GBC.std().fill();
     192               
     193                // this is manually tuned so that it looks nice on a GNOME
     194                // desktop - maybe needs some cross platform proofing.
     195                panel.add(new JLabel(tr("Enter a place name to search for:")), GBC.eol().insets(5, 5, 5, 5));
     196                panel.add(searchTerm, GBC.std().fill(GBC.BOTH).insets(5, 0, 5, 4));
     197                panel.add(submitSearch, GBC.eol().insets(5, 0, 5, 5));
     198                Dimension btnSize = submitSearch.getPreferredSize();
     199                btnSize.setSize(btnSize.width, btnSize.height * 0.8);
     200                submitSearch.setPreferredSize(btnSize);
     201               
     202                GBC c = GBC.std().fill().insets(5, 0, 5, 5);
     203                c.gridwidth = 2;
    164204                JScrollPane scrollPane = new JScrollPane(searchResultDisplay);
     205                scrollPane.setPreferredSize(new Dimension(200,200));
    165206                panel.add(scrollPane, c);
    166207                gui.tabpane.add(panel, tr("Places"));
     
    171212                submitSearch.addActionListener(new ActionListener() {
    172213                        public void actionPerformed(ActionEvent e) {
    173                                 queryServer();
    174                         }
    175                 });
    176                
    177                 // display search results in list just by name, and add tooltip
    178                 // for description. would also be possible to use a table model
    179                 // instead of list, and display lat/lon etc.
    180                 searchResultDisplay.setCellRenderer(new DefaultListCellRenderer() {
    181                         @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    182                                 super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
     214                                queryServer(gui);
     215                        }
     216                });
     217               
     218                searchTerm.addActionListener(new ActionListener() {
     219                        public void actionPerformed(ActionEvent e) {
     220                                queryServer(gui);
     221                        }
     222                });
     223       
     224                searchResults.addColumn("name");
     225                searchResults.addColumn("type");
     226                searchResults.addColumn("near");
     227                searchResults.addColumn("zoom");
     228               
     229                // TODO - this is probably not the coolest way to set relative sizes?
     230                searchResultDisplay.getColumn("name").setPreferredWidth(200);
     231                searchResultDisplay.getColumn("type").setPreferredWidth(100);
     232                searchResultDisplay.getColumn("near").setPreferredWidth(100);
     233                searchResultDisplay.getColumn("zoom").setPreferredWidth(50);
     234                searchResultDisplay.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     235               
     236                // display search results in a table. for simplicity, the table contains
     237                // the same SearchResult object in each of the four columns, but it is rendered
     238                // differently depending on the column.
     239                searchResultDisplay.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {
     240                        @Override public Component getTableCellRendererComponent(JTable table, Object value,
     241                    boolean isSelected, boolean hasFocus, int row, int column) {
     242                                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    183243                                if (value != null) {
    184                                         setText(((SearchResult)value).name);
     244                                        SearchResult sr = (SearchResult) value;
     245                                        switch(column) {
     246                                        case 0:
     247                                                setText(sr.name);
     248                                                break;
     249                                        case 1:
     250                                                setText(sr.type);
     251                                                break;
     252                                        case 2:
     253                                                setText(sr.nearestPlace);
     254                                                break;
     255                                        case 3:
     256                                                setText(Integer.toString(sr.zoom));
     257                                                break;
     258                                        }
    185259                                        setToolTipText("<html>"+((SearchResult)value).description+"</html>");
    186260                                }
     
    190264               
    191265                // if item is selected in list, notify dialog
    192                 //searchResultDisplay.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    193                 searchResultDisplay.addListSelectionListener(new ListSelectionListener() {
     266                searchResultDisplay.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
    194267                        public void valueChanged(ListSelectionEvent lse) {
    195268                                if (lse.getValueIsAdjusting()) return;
     
    197270                                try
    198271                                {
    199                                         r = (SearchResult) searchResults.getElementAt(lse.getFirstIndex());
     272                                        r = (SearchResult) searchResults.getValueAt(lse.getFirstIndex(), 0);
    200273                                }
    201274                                catch (Exception x)
     
    216289                        }
    217290                });
     291               
     292                // TODO - we'd like to finish the download dialog upon double-click but
     293                // don't know how to bypass the JOptionPane in which the whole thing is
     294                // displayed.
     295                searchResultDisplay.addMouseListener(new MouseAdapter() {
     296                        @Override public void mouseClicked(MouseEvent e) {
     297                                if (e.getClickCount() > 1) {
     298                                        if (searchResultDisplay.getSelectionModel().getMinSelectionIndex() > -1) {
     299                                                // add sensible action here.
     300                                        }
     301                                }
     302                        }
     303                });
     304
    218305        }
    219306
Note: See TracChangeset for help on using the changeset viewer.