Results 1 to 3 of 3
  1. #1
    take2hikes is offline Member
    Join Date
    Nov 2010
    Posts
    2
    Rep Power
    0

    Default JList/ListDataListener Autocomplete functionality

    I'm trying to make an auto complete application and am not entirely sure how I need to implement the calls from what the user types to the ListDataListener and the logic behind actually narrowing the list. I haven't done much with JList's. The program has provided a list of locations that the JList is built off of.




    /**
    * Class to set up the GUI for our auto complete application
    */
    public class AutoCompleteApplication extends JFrame
    {

    /**
    * Not used
    */
    private static final long serialVersionUID = 0;
    /**
    * JPanel to act as our container panel
    */
    JPanel canvasPanel;

    public AutoCompleteApplication()
    {
    super("Auto Complete Application");

    /**
    * Set up the file menu
    */
    JMenu fileMenu = new JMenu("File");
    fileMenu.setMnemonic('F'); // set the mnemonic for the file menu

    /**
    * Set up exit menu item
    */
    JMenuItem exitItem = new JMenuItem("Exit");
    exitItem.setMnemonic('x'); // set the mnemonic for the exit menu item

    fileMenu.add(exitItem); // add the exitItem to the file menu

    /**
    * Add the action listener for the exitItem
    */
    exitItem.addActionListener(
    // Anonymous inner class
    new ActionListener()
    {
    // terminate application when user clicks exitItem

    public void actionPerformed(ActionEvent event)
    {
    System.exit(0);
    } // end method actionPerformed
    }); // end call to addActionListener



    /**
    * Set up menu bar
    */
    JMenuBar menuBar = new JMenuBar(); // create the menu bar
    setJMenuBar(menuBar); // add menu bar to application
    menuBar.add(fileMenu); // add file menu to the menu bar

    /**
    * Instantiate canvas panel to add to the layout
    */
    canvasPanel = new JPanel();

    /**
    * Set up layout
    */
    canvasPanel.setLayout(new GridBagLayout());
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.weightx = 0.0;
    constraints.weighty = 1.0;
    constraints.gridheight = 1;
    constraints.fill = GridBagConstraints.BOTH;

    /**
    * Add components to panel
    */
    canvasPanel.add(new AutoCompletePanel(), constraints);

    /*constraints.gridx = 0;
    constraints.gridy = 0;
    add(new SearchFieldPanel(), constraints);

    constraints.gridx = 0;
    constraints.gridy = 1;
    add(new ResultsPanel(), constraints);
    */

    setDefaultCloseOperation(EXIT_ON_CLOSE);

    /**
    * Window listener to ensure DB connection is closed
    */
    addWindowListener(
    new WindowAdapter()
    {
    // disconnect from database and exit when window has closed

    @Override
    public void windowClosed(WindowEvent event)
    {
    System.exit(0);
    } // end method windowClosed
    } // end WindowAdapter inner class
    ); // end call to addWindowListener

    } // end AutoCompleteApplication constructor

    public static void main(String args[])
    {
    new AutoCompleteApplication().run();
    } // end main

    private void run()
    {
    add(canvasPanel);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setVisible(true);
    } // end method run
    } // end class AutoCompleteApplication

    [/CODE]

    The sub panel handling most of the component functionality at this point:

    Java Code:
    package net.hrtmn.a9;
    
    import java.awt.Component;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.util.ArrayList;
    import javax.swing.JList;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    import javax.swing.text.Document;
    import library.Similarity;
    
    
    public class AutoCompletePanel extends JPanel
    {
    
        /**
         * JTextField for our auto-complete search field
         */
        private final JTextField searchField;
        /**
         * JList for our list of locations
         */
        private JList locationList;
        /**
         * LocationListModel for our locations JList
         */
        private LocationsListModel locationsListModel;
        /**
         * ArrayList of Components. Components removed from JList are added
         */
        private ArrayList<Component> components;
    
    
        public AutoCompletePanel()
        {
            searchField = new JTextField(25);
    
            // get the document for the JTextField
            Document document = searchField.getDocument();
    
            document.addDocumentListener(new MyDocumentListener());
    
            // build our JList with values from file
            locationsListModel = new LocationsListModel();
            locationList = new JList(locationsListModel);
    
            // add ListSelectionListener to the locationList
            locationList.addListSelectionListener(new MyListSelectionListener());
    
            // add the JList to a JScrollPane
            JScrollPane scrollPane = new JScrollPane(locationList);
            
            /**
             * Set up layout
             */
            setLayout(new GridBagLayout());
            GridBagConstraints constraints = new GridBagConstraints();
            constraints.weightx = 0.0;
            constraints.weighty = 1.0;
            constraints.gridheight = 1;
            constraints.fill = GridBagConstraints.BOTH;
    
            /**
             * Add components to panel
             */
            constraints.gridx = 0;
            constraints.gridy = 0;
            add(searchField, constraints);
    
            constraints.gridx = 0;
            constraints.gridy = 1;
            add(scrollPane, constraints);
    
        } // end constructor for AutoCompletePanel
    
        /**
         * Private inner class to handle Document Events
         */
        private class MyDocumentListener implements DocumentListener
        {
            public void changedUpdate(DocumentEvent event)
            {
                //System.out.println(searchField.getText());
                searchList();
            } // end method changedUpdate
    
            public void removeUpdate(DocumentEvent event)
            {
                //System.out.println(searchField.getText());
                searchList();
            } // end method removeUpdate
    
            public void insertUpdate(DocumentEvent event)
            {
                //System.out.println(searchField.getText());
                searchList();
            } // end method insertUpdate
    
            public void searchList()
            {
                for(int i = 0; i <= locationsListModel.size(); i++)
                {
                    float similarity = Similarity.a_in_b(searchField.getText(), locationList.getComponent(i).toString());
    
    
                    if(similarity >= 0.6)
                    {
                        components.add(locationList.getComponent(i));
                    } // end if
                }
    
                for(int i = 0; i <= components.size(); i++)
                {
                    System.out.println(components.get(i).toString());
                }
            } // end method searchList
    
        } // end inner class MyDocumentListener
    
        /**
         * Private inner class for ListListener
         */
        private class MyListSelectionListener implements ListSelectionListener
        {
    
            public void valueChanged(ListSelectionEvent event)
            {
                if (!event.getValueIsAdjusting()) {
                    // Set the value of the searchField to what the user has selected
                    searchField.setText(locationList.getSelectedValue().toString());
                } // end if
            } // end method valueChanged
    
        } // end inner class MyListListener
    } // end class AutoCompletePanel
    Custom ListModel:

    Java Code:
    package net.hrtmn.a9;
    
    import javax.swing.DefaultListModel;
    import javax.swing.event.ListDataEvent;
    import javax.swing.event.ListDataListener;
    import library.InputList;
    
    
    public class LocationsListModel extends DefaultListModel
    {
    
        private String[] data;
    
        public LocationsListModel()
        {
    
            // instantiate InputList object and pass it a filename
            InputList inputList = new InputList("PostalCodes.csv");
    
            // get the values from file and assign them to a String array
            data = inputList.get();
    
            this.addListDataListener(new MyListDataListener());
        } // end construct for LocationsListModel
    
        @Override
        public Object getElementAt(int index)
        {
            return data[index];
    
        } // end method getElementAt
    
        @Override
        public int getSize()
        {
            return data.length;
        } // end method getSize
    
        @Override
        public void addListDataListener(ListDataListener l)
        {
        } // end method addListDataListener
    
        @Override
        public void removeListDataListener(ListDataListener l)
        {
        } // end method removeListDataListener
    
        public void listChange(ListDataListener listener)
        {
        } // end method listChange
    
        private class MyListDataListener implements ListDataListener
        {
    
            public void contentsChanged(ListDataEvent listDataEvent)
            {
            }
    
            public void intervalAdded(ListDataEvent listDataEvent)
            {
            }
    
            public void intervalRemoved(ListDataEvent listDataEvent)
            {
            }
        } // end inner class MyListDataListener
    } // end class LocationsListModel
    Supplied code for reading the file:

    Java Code:
    package library;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.InvalidParameterException;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    /**
     * Get an array of Strings representing lines from a given input resource.
     */
    public class InputList
    {
    
        /**
         * The name of the file resource.
         */
        String filename;
    
        /**
         * Input a list of lines from the given file resource.
         *
         * @param filename the name of the file resource
         */
        public InputList(String filename)
        {
            if (filename == null) {
                throw new InvalidParameterException("File name is null");
            }
    
            this.filename = filename;
        }
    
        /**
         * Read the file and return an array containing the lines.
         */
        public String[] get()
        {
            InputStream is = getClass().getResourceAsStream(filename);
            Scanner sc = new Scanner(is);
            List<String> lines = new ArrayList<String>();
    
            while (sc.hasNext()) {
                lines.add(sc.nextLine());
            }
    
            try {
                is.close();
            }
            catch (IOException iOException) {
            }
    
            return lines.toArray(new String[1]);
        }
    }
    Supplied code to check for similarity between strings:

    Java Code:
    package library;
    
    /**
     * This class provides a method for computing the similarity between two strings.
     * <p/>
     *  2010 Paladin Software International, Incorporated. All Rights Reserved.
     *
     * @version 1.0
     */
    public final class Similarity
    {
    
        /**
         * Maximum prefix length to use in adjusting Jaro style score to Jaro-Winkler score.
         */
        private static final int PREFIXCOUNT = 6;
        /**
         * Weighting for the adjustment of the Jaro score.
         */
        private static final float WEIGHT = 0.1F;
        /**
         * Maximum distance to look for possible transpositions of characters.
         */
        private static final int MAXSEPARATION = 3;
        /**
         * Ignore case differences in comparisons.
         */
        private static boolean ignoreCase = true;
        /**
         * Ignore punctuation in comparisons.
         */
        private static boolean ignorePunctuation;
    
        /**
         * Prevent the class from being instantiated.
         */
        private Similarity()
        {
        }
    
        /**
         * Gets a similarity measure of a String a within a String by using a modified form of the the Jaro-Winkler metric for
         * the given strings. The properties <code>ignoreCase</code> and <code>ingnorePunctuation</code> control how and which
         * characters are compared.
         *
         * @param a the trial String
         * @param b the String to which it is to be compared.
         *
         * @return a score in the range 0.0-1.0
         */
        public static float a_in_b(final String a, final String b)
        {
            /* Copy strings to StringBuilders, removing case differences and
            punctuation if desired. */
            StringBuilder asb = specialCopy(a);
            StringBuilder bsb = specialCopy(b);
    
            /*	Quick test for identity. */
            if (asb.equals(bsb)) {
                return 1.0F;
            }
    
            /* Get common characters looking at it both ways. */
            final StringBuilder common1 = find_common(asb, bsb);
            final StringBuilder common2 = find_common(bsb, asb);
    
            /*	There is no similarity if no characters in common. */
            if (common1.length() == 0 && common2.length() == 0) {
                return 0.0F;
            }
    
            /*	Check for same length of common strings; return zero if not the
            same. */
            if (common1.length() != common2.length()
                || asb.length() > bsb.length()) {
                return 0.0F;
            }
    
            /* Get the number of transpositions. */
            int transpositions = 0;
            for (int i = 0; i < common1.length(); i++) {
                if (common1.charAt(i) != common2.charAt(i)) {
                    transpositions++;
                }
            }
            transpositions /= 2.0F;
    
            /* Calculate the Jaro metric. */
            final float dist =
                        (common1.length() / ((float) asb.length())
                         + common2.length() / ((float) bsb.length())
                         + (common1.length() - transpositions)
                           / ((float) common1.length())) / 3.0F;
    
            /* This extension modifies the weights of poorly matching pairs a, b which
            share a common prefix gets the prefix length found of common characters
            at the begining of the strings. */
            int len = Math.min(PREFIXCOUNT, Math.min(asb.length(), bsb.length()));
            /*	Check for prefix similarity of length len. */
            for (int i = 0; i != len; i++) /* Check the prefix is the same so far. */ {
                if (asb.charAt(i) != b.charAt(i)) {
                    /*	Not the same, so return as far as have gotten. */
                    len = i;
                    break;
                }
            }
            return dist + ((float) len * WEIGHT * (1.0F - dist));
        }
    
        /**
         * Set the value of the property saying to ignore case differences. Default value is <code>true</code).
         *
         * @param ignoreCase the desired value of the property
         */
        public static void setIgnoreCase(boolean ignoreCase)
        {
            Similarity.ignoreCase = ignoreCase;
        }
    
        /**
         * Get the the value of property saying to ignore case differences. Default value is <code>true</code).
         */
        public static boolean getIgnoreCase()
        {
            return Similarity.ignoreCase;
        }
    
        /**
         * Set the value of the property saying to ignore punctuation. Default value is <code>false</code).
         *
         * @param ignorePunctuation the desired value of the property
         */
        public static void setIgnorePunctuation(boolean ignorePunctuation)
        {
            Similarity.ignorePunctuation = ignorePunctuation;
        }
    
        /**
         * Get the the value of property saying to ignore punctuation. Default value is <code>false</code).
         */
        public static boolean getIgnorePunctuation()
        {
            return Similarity.ignorePunctuation;
        }
    
        /**
         * Returns a string buffer of characters from sb1 that also occur in sb2 if they are within a given distance separation
         * from the position in sb1.
         */
        private static StringBuilder find_common(StringBuilder sb1, StringBuilder sb2)
        {
            /* Create a buffer of characters for the return value*/
            StringBuilder result = new StringBuilder();
    
            /* Get half the length of the longest string, rounded up - (this is the
            distance used for acceptable transpositions, but limited by the
            MAXSEPARATION value). */
            int separation = Math.min(MAXSEPARATION,
                                      Math.max((sb1.length() + 1) / 2, (sb2.length() + 1) / 2));
    
            /* Iterate over sb1, looking at each character in sb2.  */
            for (int i = 0; i != sb1.length(); ++i) {
                char ch = sb1.charAt(i);
                /* Look either way in sb2 from the current position in sb1, plus or minus the
                separation distance, for the character from sb1. */
                int from = Math.max(0, i - separation);
                if (from == sb2.length()) {
                    break;
                }
                int to = Math.min(i + separation, sb2.length() - 1) + 1;
                for (int j = from; j != to; ++j) /* If there is a matching character, then add it to the common
                character list. */ {
                    if (sb2.charAt(j) == ch) {
                        int k;
                        /* If the character is already in the common set, give up. */
                        for (k = 0; k != result.length(); ++k) {
                            if (result.charAt(k) == ch) {
                                break;
                            }
                        }
    
                        /* If loop exhausted, the character is not there, so place
                        it there, and then give up on looking any further. */
                        if (k == result.length()) {
                            result.append(ch);
                            break;
                        }
                    }
                }
            }
            return result;
        }
    
        /**
         * Returns a StringBuilder copy of the input CharSequence with punctuation characters removed.
         *
         * @param input the input character sequence
         */
        private static StringBuilder specialCopy(CharSequence input)
        {
            StringBuilder output = new StringBuilder();
    
            for (int i = 0; i != input.length(); ++i) {
                char c = ignoreCase
                         ? Character.toLowerCase(input.charAt(i)) : input.charAt(i);
    
                if (ignorePunctuation) {
                    int type = Character.getType(c);
    
                    if (type == Character.CONNECTOR_PUNCTUATION
                        || type == Character.DASH_PUNCTUATION
                        || type == Character.END_PUNCTUATION
                        || type == Character.FINAL_QUOTE_PUNCTUATION
                        || type == Character.INITIAL_QUOTE_PUNCTUATION
                        || type == Character.OTHER_PUNCTUATION
                        || type == Character.START_PUNCTUATION) {
                        continue;
                    }
                }
    
                output.append(c);
            }
            return output;
        }
    }
    If anyone can help it would be greatly appreciated!
    Last edited by take2hikes; 11-09-2010 at 04:55 PM. Reason: Incomplete Post

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    25

    Default

    I tried to find an actual question buried in that mountain of code but couldn't. Maybe someone else will have better luck.

  3. #3
    take2hikes is offline Member
    Join Date
    Nov 2010
    Posts
    2
    Rep Power
    0

    Default

    Fubarable,
    Sorry about that. I had a question up there initially but I think when I started pasting in all the code it somehow did away with it.

    If you or anyone else has any additional questions, please let me know. I would really appreciate some guidance ;-).

Similar Threads

  1. autocomplete in text file
    By Markus1 in forum New To Java
    Replies: 0
    Last Post: 08-06-2010, 04:57 PM
  2. JComboBox Functionality
    By Moncleared in forum AWT / Swing
    Replies: 1
    Last Post: 02-19-2009, 07:57 PM
  3. AutoComplete for jtextfield
    By pinks_70986 in forum New To Java
    Replies: 2
    Last Post: 02-12-2009, 06:46 AM
  4. Replies: 2
    Last Post: 01-23-2009, 04:09 PM
  5. Functionality of Buttons
    By ljk8950 in forum AWT / Swing
    Replies: 6
    Last Post: 08-15-2008, 01:44 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •