// ComboBoxCompleter package org.javamoney.examples.ez.common.utility; import static java.awt.event.KeyEvent.CHAR_UNDEFINED; import static java.awt.event.KeyEvent.VK_DOWN; import static java.awt.event.KeyEvent.VK_ENTER; import static java.awt.event.KeyEvent.VK_LEFT; import static java.awt.event.KeyEvent.VK_RIGHT; import static java.awt.event.KeyEvent.VK_UP; import static java.lang.Character.isISOControl; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JComboBox; import javax.swing.JTextField; /** * This class facilitates automatically completing the text being typed in a * combo box's editor with the first match found in the combo box's items list. */ public final class ComboBoxCompleter { /** * Constructs a new completer. * * @param comboBox The combo box to monitor. */ public ComboBoxCompleter(JComboBox comboBox) { this(comboBox, false, false); } /** * Constructs a new completer. * * @param comboBox The combo box to monitor. * @param caseSensitive Whether or not to use case sensitive comparing. * @param useTypedText Whether or not to use the text that is typed or the * text of the items. */ public ComboBoxCompleter(JComboBox comboBox, boolean caseSensitive, boolean useTypedText) { setComboBox(comboBox); setIsCaseSensitive(caseSensitive); setUsesTypedText(useTypedText); // Add listeners. getTextField().addKeyListener(new KeyController()); } /** * This method returns true if case sensitive comparing is in effect, otherwise * false. * * @return true or false. */ public boolean isCaseSensitive() { return itsIsCaseSensitive; } /** * This method sets the whether or not to use sensitive comparing. * * @param value true or false. */ public void setIsCaseSensitive(boolean value) { itsIsCaseSensitive = value; } /** * This method sets whether or not to use the text that is typed or the text * of the items. * * @param value true or false. */ public void setUsesTypedText(boolean value) { itsUsesTypedText = value; } /** * This method returns true if the text that is typed should be used when * completing, otherwise false. * * @return true or false. */ public boolean usesTypedText() { return itsUsesTypedText; } ////////////////////////////////////////////////////////////////////////////// // Start of private methods. ////////////////////////////////////////////////////////////////////////////// /* * This method iterates all the items in the combo box and compares each * item's text to the current text in the combo box's editor until a match is * found. If a match is found, then the combo box's editor's text will be * completed to that of the item's text. The text that was added from the * item's text will be highlighted. */ private void findFirstMatchAndComplete() { JTextField field = getTextField(); String text = field.getText(); // Only iterate if there is some text to compare with. if(text.length() != 0) { boolean match = false; for(int index = 0; index < getComboBox().getItemCount(); ++index) { String item = getComboBox().getItemAt(index).toString(); if(isCaseSensitive() == true) { match = item.startsWith(text); } else { match = item.toLowerCase().startsWith(text.toLowerCase()); } if(match == true) { // Display the item's actual text or as is typed? if(usesTypedText() == true) { field.setText(text + item.substring(text.length())); } else { field.setText(item); } // Highlight added text. field.setCaretPosition(item.length()); field.moveCaretPosition(text.length()); break; } } } } private JComboBox getComboBox() { return itsComboBox; } private JTextField getTextField() { return (JTextField)getComboBox().getEditor().getEditorComponent(); } private static boolean isValidKey(int key) { boolean result = false; // Control or arrow keys are invalid. if(isISOControl(key) == false && key != CHAR_UNDEFINED) { if(key != VK_LEFT && key != VK_RIGHT && key != VK_UP && key != VK_DOWN) { result = true; } } return result; } private void processKey(int key) { if(isValidKey(key) == true) { findFirstMatchAndComplete(); } else if(key == VK_ENTER) { JTextField field = getTextField(); // Remove any highlighting. field.setCaretPosition(field.getText().length()); } } private void setComboBox(JComboBox comboBox) { itsComboBox = comboBox; } ////////////////////////////////////////////////////////////////////////////// // Start of inner classes. ////////////////////////////////////////////////////////////////////////////// private class KeyController extends KeyAdapter { @Override public void keyReleased(KeyEvent event) { processKey(event.getKeyCode()); } } ////////////////////////////////////////////////////////////////////////////// // Start of class members. ////////////////////////////////////////////////////////////////////////////// private JComboBox itsComboBox; private boolean itsIsCaseSensitive; private boolean itsUsesTypedText; }