Skip to content

Commit c6efe36

Browse files
authored
Add files via upload
1 parent c3804de commit c6efe36

File tree

1 file changed

+148
-0
lines changed

1 file changed

+148
-0
lines changed

source/KeySelectionRenderer.java

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import java.awt.*;
2+
import javax.swing.*;
3+
import javax.swing.plaf.basic.*;
4+
5+
/*
6+
* This class can be used as the renderer and KeySelectionManager for an
7+
* Object added to the ComboBoxModel.
8+
*
9+
* The class must be extended and the getDisplayValue() method must be
10+
* implemented. This method will return a String to be rendered in the
11+
* JComboBox. The same String will be used to do key selection of an
12+
* item in the ComboBoxModel.
13+
*/
14+
abstract class KeySelectionRenderer extends BasicComboBoxRenderer
15+
implements JComboBox.KeySelectionManager
16+
{
17+
// Used by the KeySelectionManager implementation to determine when to
18+
// start a new search or append typed character to the existing search.
19+
20+
private long timeFactor;
21+
private long lastTime;
22+
private long time;
23+
private String prefix = "";
24+
25+
public KeySelectionRenderer(JComboBox comboBox)
26+
{
27+
comboBox.setRenderer( this );
28+
comboBox.setKeySelectionManager( this );
29+
30+
Long l = (Long)UIManager.get("ComboBox.timeFactor");
31+
timeFactor = l == null ? 1000L : l.longValue();
32+
}
33+
34+
/**
35+
* This method must be implemented in the extended class.
36+
*
37+
* @param item an item from the ComboBoxModel
38+
* @returns a String containing the text to be rendered for this item.
39+
*/
40+
public abstract String getDisplayValue(Object item);
41+
42+
// Implement the renderer
43+
44+
@Override
45+
public Component getListCellRendererComponent(
46+
JList list, Object item, int index, boolean isSelected, boolean hasFocus)
47+
{
48+
super.getListCellRendererComponent(list, item, index, isSelected, hasFocus);
49+
50+
if (item != null)
51+
{
52+
setText( getDisplayValue(item) );
53+
}
54+
55+
return this;
56+
}
57+
58+
// Implement the KeySelectionManager
59+
60+
@Override
61+
public int selectionForKey(char aKey, ComboBoxModel model)
62+
{
63+
time = System.currentTimeMillis();
64+
65+
// Get the index of the currently selected item
66+
67+
int size = model.getSize();
68+
int startIndex = -1;
69+
Object selectedItem = model.getSelectedItem();
70+
71+
if (selectedItem != null)
72+
{
73+
for (int i = 0; i < size; i++)
74+
{
75+
if ( selectedItem == model.getElementAt(i) )
76+
{
77+
startIndex = i;
78+
break;
79+
}
80+
}
81+
}
82+
83+
// Determine the "prefix" to be used when searching the model. The
84+
// prefix can be a single letter or multiple letters depending on how
85+
// fast the user has been typing and on which letter has been typed.
86+
87+
if (time - lastTime < timeFactor)
88+
{
89+
if((prefix.length() == 1) && (aKey == prefix.charAt(0)))
90+
{
91+
// Subsequent same key presses move the keyboard focus to the next
92+
// object that starts with the same letter.
93+
startIndex++;
94+
}
95+
else
96+
{
97+
prefix += aKey;
98+
}
99+
}
100+
else
101+
{
102+
startIndex++;
103+
prefix = "" + aKey;
104+
}
105+
106+
lastTime = time;
107+
108+
// Search from the current selection and wrap when no match is found
109+
110+
if (startIndex < 0 || startIndex >= size)
111+
{
112+
startIndex = 0;
113+
}
114+
115+
int index = getNextMatch(prefix, startIndex, size, model);
116+
117+
if (index < 0)
118+
{
119+
// wrap
120+
index = getNextMatch(prefix, 0, startIndex, model);
121+
}
122+
123+
return index;
124+
}
125+
126+
/*
127+
** Find the index of the item in the model that starts with the prefix.
128+
*/
129+
private int getNextMatch(String prefix, int start, int end, ComboBoxModel model)
130+
{
131+
for (int i = start; i < end; i++ )
132+
{
133+
Object item = model.getElementAt(i);
134+
135+
if (item != null)
136+
{
137+
String displayValue = getDisplayValue( item ).toLowerCase();
138+
139+
if (displayValue.startsWith(prefix))
140+
{
141+
return i;
142+
}
143+
}
144+
}
145+
146+
return -1;
147+
}
148+
}

0 commit comments

Comments
 (0)