package danielcortes.xyz.views.components; import javax.swing.*; import java.awt.*; public abstract class KeySelectionRenderer extends DefaultListCellRenderer implements JComboBox.KeySelectionManager { private long timeFactor; private long lastTime; private long time; private String prefix = ""; public KeySelectionRenderer(JComboBox comboBox) { comboBox.setRenderer(this); comboBox.setKeySelectionManager(this); Long l = (Long) UIManager.get("ComboBox.timeFactor"); timeFactor = l == null ? 1000L : l.longValue(); } public abstract String getDisplayValue(Object item); @Override public Component getListCellRendererComponent( JList list, Object item, int index, boolean isSelected, boolean hasFocus) { super.getListCellRendererComponent(list, item, index, isSelected, hasFocus); if (item != null) { setText(getDisplayValue(item)); } return this; } @Override public int selectionForKey(char aKey, ComboBoxModel model) { time = System.currentTimeMillis(); // Get the index of the currently selected item int size = model.getSize(); int startIndex = -1; Object selectedItem = model.getSelectedItem(); if (selectedItem != null) { for (int i = 0; i < size; i++) { if (selectedItem == model.getElementAt(i)) { startIndex = i; break; } } } if (time - lastTime < timeFactor) { if ((prefix.length() == 1) && (aKey == prefix.charAt(0))) { startIndex++; } else { prefix += aKey; } } else { startIndex++; prefix = "" + aKey; } lastTime = time; if (startIndex < 0 || startIndex >= size) { startIndex = 0; } int index = getNextMatch(prefix, startIndex, size, model); if (index < 0) { // wrap index = getNextMatch(prefix, 0, startIndex, model); } return index; } private int getNextMatch(String prefix, int start, int end, ComboBoxModel model) { for (int i = start; i < end; i++) { Object item = model.getElementAt(i); if (item != null) { String displayValue = getDisplayValue(item).toLowerCase(); if (displayValue.startsWith(prefix)) { return i; } } } return -1; } }