This class {@link #install}s support for filtering and autocompletion into a standard {@link JComboBox}. It also acts as a factory class for {@link #createTableCellEditor creating autocompleting table cell editors}.
All autocompletion behaviour provided is meant to mimic the functionality of the Firefox address field. To be explicit, the following is a list of expected behaviours which are installed:
Typing into the ComboBox Editor
- typing any value into the editor when the popup is invisible causes the popup to appear and its contents to be filtered according to the editor's text. It also autocompletes to the first item that is prefixed with the editor's text and selects that item within the popup.
- typing any value into the editor when the popup is visible causes the popup to be refiltered according to the editor's text and reselects an appropriate autocompletion item.
- typing the down or up arrow keys in the editor when the popup is invisible causes the popup to appear and its contents to be filtered according to the editor's text. It also autocompletes to the first item that is prefixed with the editor's text and selects that item within the popup.
- typing the up arrow key when the popup is visible and the selected element is the first element causes the autocompletion to be cleared and the popup's selection to be removed.
- typing the up arrow key when no selection exists causes the last element of the popup to become selected and used for autocompletion
- typing the down arrow key when the popup is visible and the selected element is the last element causes the autocompletion to be cleared and the popup's selection to be removed
- typing the down arrow key when no selection exists causes the first element of the popup to become selected and used for autocompletion
- typing the delete key while in strict mode will select the prior text rather than delete it. Attempting to delete all text results in a beep unless the autcomplete support has been configured to not beep.
Clicking on the Arrow Button - clicking the arrow button when the popup is invisible causes the popup to appear and its contents to be shown unfiltered
- clicking the arrow button when the popup is visible causes the popup to be hidden
Sizing the ComboBox Popup - the popup is always at least as wide as the autocompleting {@link JComboBox}, but may be wider to accomodate a {@link JComboBox#getPrototypeDisplayValue() prototype display value}if a non-null prototype display value exists
- as items are filtered in the ComboBoxModel, the popup height is adjusted to display between 0 and {@link JComboBox#getMaximumRowCount()}rows before scrolling the popup
JComboBox ActionEvents A single {@link ActionEvent} is fired from the JComboBox in these situations:
- the user hits the enter key
- the selected item within the popup is changed (which can happen due to a mouse click, a change in the autocompletion term, or using the arrow keys)
- the JComboBox loses focus and contains a value that does not appear in the ComboBoxModel
Null Values in the ComboBoxModel null
values located in the ComboBoxModel are considered identical to empty Strings ("") for the purposes of locating autocompletion terms.
ComboBoxEditor Focus - the text in the ComboBoxEditor is selected if {@link #getSelectsTextOnFocusGain()} returns true
- the JPopupMenu is hidden when the ComboBoxEditor loses focus if {@link #getHidesPopupOnFocusLost()} returns true
Extracting String Values Each value in the ComboBoxModel must be converted to a String for many reasons: filtering, setting into the ComboBoxEditor, displaying in the renderer, etc. By default, JComboBox relies on {@link Object#toString()}to map elements to their String equivalents. Sometimes, however, toString() is not a reliable or desirable mechanism to use. To deal with this problem, AutoCompleteSupport provides an install method that takes a {@link Format}object which is used to do all converting back and forth between Strings and ComboBoxModel objects.
In order to achieve all of the autocompletion and filtering behaviour, the following occurs when {@link #install} is called:
- the JComboBox will be made editable
- the JComboBox will have a custom ComboBoxModel installed on it containing the given items
- the ComboBoxEditor will be wrapped with functionality and set back into the JComboBox as the editor
- the JTextField which is the editor component for the JComboBox will have a DocumentFilter installed on its backing Document
The strategy of this support class is to alter all of the objects which influence the behaviour of the JComboBox in one single context. With that achieved, it greatly reduces the cross-functional communication required to customize the behaviour of JComboBox for filtering and autocompletion.
Warning: This class must be mutated from the Swing Event Dispatch Thread. Failure to do so will result in an {@link IllegalStateException} thrown from any one of:
- {@link #install(JComboBox,EventList)}
- {@link #install(JComboBox,EventList,TextFilterator)}
- {@link #install(JComboBox,EventList,TextFilterator,Format)}
- {@link #isInstalled()}
- {@link #uninstall()}
- {@link #setCorrectsCase(boolean)}
- {@link #setStrict(boolean)}
- {@link #setBeepOnStrictViolation(boolean)}
- {@link #setSelectsTextOnFocusGain(boolean)}
- {@link #setHidesPopupOnFocusLost(boolean)}
- {@link #setFilterMode(int)}
- {@link #setFirstItem(Object)}
- {@link #removeFirstItem()}
@author James Lemieux