combobox jump to typed char
The simplest form of a filter combo box would be as the code below. But it would need more work to refine it. Also, if the list is huge, as in your case, there might be a performance issues as we are looping thru' the entire collection on each key press.
public class FilterComboBox extends ComboBox< String > {
private ObservableList< String > items;
private class KeyHandler implements EventHandler< KeyEvent > {
private SingleSelectionModel< String > sm;
private String s;
public KeyHandler() {
sm = getSelectionModel();
s = "";
}
@Override
public void handle( KeyEvent event ) {
// handle non alphanumeric keys like backspace, delete etc
if( event.getCode() == KeyCode.BACK_SPACE && s.length()>0)
s = s.substring( 0, s.length() - 1 );
else s += event.getText();
if( s.length() == 0 ) {
sm.selectFirst();
return;
}
System.out.println( s );
for( String item: items ) {
if( item.startsWith( s ) ) sm.select( item );
}
}
}
public FilterComboBox( ObservableList< String > items ) {
super( items );
this.items = items;
setOnKeyReleased( new KeyHandler() );
}
}
Wouldn't code like this be sufficient?
comboBox.setOnKeyReleased(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
String s = jumpTo(event.getText(), comboBox.getValue(), comboBox.getItems());
if (s != null) {
comboBox.setValue(s);
}
}
});
...
static String jumpTo(String keyPressed, String currentlySelected, List<String> items) {
String key = keyPressed.toUpperCase();
if (key.matches("^[A-Z]$")) {
// Only act on letters so that navigating with cursor keys does not
// try to jump somewhere.
boolean letterFound = false;
boolean foundCurrent = currentlySelected == null;
for (String s : items) {
if (s.toUpperCase().startsWith(key)) {
letterFound = true;
if (foundCurrent) {
return s;
}
foundCurrent = s.equals(currentlySelected);
}
}
if (letterFound) {
return jumpTo(keyPressed, null, items);
}
}
return null;
}
This will jump to the first item when you press a letter. If you press that letter again, it jumps to the next item starting with that letter, wrapping back to the first if there are no more items starting with that letter.