Ignore:
Timestamp:
02.05.2010 18:12:34 (2 years ago)
Author:
bastiK
Message:

autocompletion cleanup - fixes #2729

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingComboBox.java

    r3210 r3214  
    22package org.openstreetmap.josm.gui.tagging.ac; 
    33 
     4import java.awt.Component; 
    45import java.awt.event.FocusEvent; 
    56import java.awt.event.FocusListener; 
    67import java.util.Collection; 
    78 
     9import javax.swing.ComboBoxEditor; 
    810import javax.swing.ComboBoxModel; 
    911import javax.swing.DefaultComboBoxModel; 
    1012import javax.swing.JComboBox; 
     13import javax.swing.JLabel; 
     14import javax.swing.JList; 
     15import javax.swing.ListCellRenderer; 
    1116import javax.swing.text.AttributeSet; 
    1217import javax.swing.text.BadLocationException; 
     
    4146 
    4247        @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { 
    43             if(selecting || (offs == 0 && str.equals(getText(0, getLength())))) 
     48            if (selecting || (offs == 0 && str.equals(getText(0, getLength())))) 
    4449                return; 
    4550            boolean initial = (offs == 0 && getLength() == 0 && str.length() > 1); 
     
    5863            int end = start; 
    5964            String curText = getText(0, size); 
     65             
     66            // if the text starts with a number we don't autocomplete 
     67            // 
     68            try { 
     69                Long.parseLong(str); 
     70                if (curText.length() == 0) { 
     71                    // we don't autocomplete on numbers 
     72                    return; 
     73                } 
     74                Long.parseLong(curText); 
     75                return; 
     76            } catch (NumberFormatException e) { 
     77                // either the new text or the current text isn't a number. We continue with 
     78                // autocompletion 
     79            } 
     80             
    6081            // lookup and select a matching item 
    6182            Object item = lookupItem(curText); 
    6283            setSelectedItem(item); 
    63             if(initial) { 
     84            if (initial) { 
    6485                start = 0; 
    6586            } 
    6687            if (item != null) { 
    67                 String newText = item.toString(); 
    68                 if(!newText.equals(curText)) 
     88                String newText = ((AutoCompletionListItem) item).getValue(); 
     89                if (!newText.equals(curText)) 
    6990                { 
    7091                    selecting = true; 
     
    89110        private Object lookupItem(String pattern) { 
    90111            ComboBoxModel model = comboBox.getModel(); 
     112            AutoCompletionListItem bestItem = null; 
    91113            for (int i = 0, n = model.getSize(); i < n; i++) { 
    92                 Object currentItem = model.getElementAt(i); 
    93                 if (currentItem.toString().startsWith(pattern)) 
    94                     return currentItem; 
    95             } 
    96             return null; 
     114                AutoCompletionListItem currentItem = (AutoCompletionListItem) model.getElementAt(i);; 
     115                if (currentItem.getValue().startsWith(pattern)) { 
     116                    if (bestItem == null || currentItem.getPriority().compareTo(bestItem.getPriority()) > 0) { 
     117                        bestItem = currentItem; 
     118                    } 
     119                } 
     120            } 
     121            return bestItem; // may be null 
    97122        } 
    98123    } 
    99124 
    100125    public AutoCompletingComboBox() { 
     126        setRenderer(new AutoCompleteListCellRenderer()); 
    101127        final JTextComponent editor = (JTextComponent) this.getEditor().getEditorComponent(); 
    102128        editor.setDocument(new AutoCompletingComboBoxDocument(this)); 
     
    112138    } 
    113139 
     140    /** 
     141     * Convert the selected item into a String 
     142     * that can be edited in the editor component. 
     143     * 
     144     * @param editor    the editor 
     145     * @param item      excepts AutoCompletionListItem, String and null 
     146     */ 
     147    @Override public void configureEditor(ComboBoxEditor editor, Object item) { 
     148        if (item == null) { 
     149            editor.setItem(null); 
     150        } else if (item instanceof String) { 
     151            editor.setItem(item); 
     152        } else if (item instanceof AutoCompletionListItem) { 
     153            editor.setItem(((AutoCompletionListItem)item).getValue()); 
     154        } else 
     155            throw new IllegalArgumentException(); 
     156    } 
     157 
     158    /** 
     159     * Selects a given item in the ComboBox model 
     160     * @param item      excepts AutoCompletionListItem, String and null 
     161     */ 
     162    @Override public void setSelectedItem(Object item) { 
     163        if (item == null) { 
     164            super.setSelectedItem(null); 
     165        } else if (item instanceof AutoCompletionListItem) { 
     166            super.setSelectedItem(item); 
     167        } else if (item instanceof String) { 
     168            String s = (String) item; 
     169            // find the string in the model or create a new item 
     170            for (int i=0; i< getModel().getSize(); i++) { 
     171                AutoCompletionListItem acItem = (AutoCompletionListItem) getModel().getElementAt(i); 
     172                if (s.equals(acItem.getValue())) { 
     173                    super.setSelectedItem(acItem); 
     174                    return; 
     175                } 
     176            } 
     177            super.setSelectedItem(new AutoCompletionListItem(s, AutoCompletionItemPritority.UNKNOWN)); 
     178        } else 
     179            throw new IllegalArgumentException(); 
     180    } 
     181 
     182    /** 
     183     * sets the items of the combobox to the given strings 
     184     */ 
    114185    public void setPossibleItems(Collection<String> elems) { 
    115186        DefaultComboBoxModel model = (DefaultComboBoxModel)this.getModel(); 
     
    117188        model.removeAllElements(); 
    118189        for (String elem : elems) { 
     190            model.addElement(new AutoCompletionListItem(elem, AutoCompletionItemPritority.UNKNOWN)); 
     191        } 
     192        this.getEditor().setItem(oldValue); 
     193    } 
     194 
     195    /** 
     196     * sets the items of the combobox to the given AutoCompletionListItems 
     197     */ 
     198    public void setPossibleACItems(Collection<AutoCompletionListItem> elems) { 
     199        DefaultComboBoxModel model = (DefaultComboBoxModel)this.getModel(); 
     200        Object oldValue = this.getEditor().getItem(); 
     201        model.removeAllElements(); 
     202        for (AutoCompletionListItem elem : elems) { 
    119203            model.addElement(elem); 
    120204        } 
    121205        this.getEditor().setItem(oldValue); 
    122206    } 
     207 
    123208 
    124209    protected boolean isAutocompleteEnabled() { 
     
    129214        this.autocompleteEnabled = autocompleteEnabled; 
    130215    } 
     216 
     217    /** 
     218     * ListCellRenderer for AutoCompletingComboBox 
     219     * renders an AutoCompletionListItem by showing only the string value part 
     220     */ 
     221    public class AutoCompleteListCellRenderer extends JLabel implements ListCellRenderer { 
     222 
     223        public AutoCompleteListCellRenderer() { 
     224            setOpaque(true); 
     225        } 
     226 
     227        public Component getListCellRendererComponent( 
     228                JList list, 
     229                Object value, 
     230                int index, 
     231                boolean isSelected, 
     232                boolean cellHasFocus) 
     233        { 
     234            if (isSelected) { 
     235                setBackground(list.getSelectionBackground()); 
     236                setForeground(list.getSelectionForeground()); 
     237            } else { 
     238                setBackground(list.getBackground()); 
     239                setForeground(list.getForeground()); 
     240            } 
     241 
     242            AutoCompletionListItem item = (AutoCompletionListItem) value; 
     243            setText(item.getValue()); 
     244            return this; 
     245        } 
     246    } 
    131247} 
Note: See TracChangeset for help on using the changeset viewer.