Oi pessoal.
Encontrei o seguinte código pra autocomplete numa JComboBox:
import java.awt.AWTKeyStroke;
import java.awt.KeyboardFocusManager;
import java.awt.event.*;
import java.text.Normalizer;
import java.util.*;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.text.*;
public class AutoCompleteComboBox extends JComboBox implements JComboBox.KeySelectionManager {
private String searchFor;
private long lap;
private boolean pressionado = false; //indica se as setas para cima ou para baixo foram pressionadas
public class CBDocument extends PlainDocument {
@Override
public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
if (isPopupVisible()) //se o popup estiver visível ao digitar
setPopupVisible(false); //fecha, caso contrário a pesquisa não funciona
if (str == null)
return;
super.insertString(offset, str, a);
if (!isPopupVisible() && str.length() != 0)
fireActionEvent();
}
}
public AutoCompleteComboBox2() {
lap = new java.util.Date().getTime(); //recupera o tempo atual
setKeySelectionManager(this); //utilizado para pesquisar na comboBox
final JTextField tf;
//faz a tecla ENTER se comportar como a tecla TAB:
Set<AWTKeyStroke> keystrokes = getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
Set<AWTKeyStroke> newKeystrokes = new HashSet<AWTKeyStroke>(keystrokes);
newKeystrokes.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_ENTER, 0));
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, newKeystrokes);
if (getEditor() != null) {
tf = (JTextField) getEditor().getEditorComponent();
if (tf != null) {
tf.setDocument(new CBDocument());
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 38 || e.getKeyCode() == 40) { //se pressionar a seta para cima ou a seta para baixo
setPopupVisible(true);
pressionado = true;
} else //se pressionar qualquer outra tecla
{
pressionado = false;
}
}
});
tf.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
tf.selectAll();
}
});
addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
pressionado=true; //indica que vai cancelar o evento actionPerformed
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
});
addActionListener(new ActionListener() { //adiciona o evento à combobox
@Override
public void actionPerformed(ActionEvent evt) {
if (pressionado) //se pressionou a seta para cima ou para baixo, ou abriu o popup, cancela o evento actionPerformed e apenas alterna entre os itens
return;
JTextField tf = (JTextField) getEditor().getEditorComponent(); //textField que é o editor da combobox
String text = tf.getText(); //texto digitado na combobox
ComboBoxModel aModel = getModel(); //modelo da combobox
String current; //item da combobox
String temp = Normalizer.normalize(text, Normalizer.Form.NFD); //remove a acentuação do texto digitado
Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); //remove acentos e 'ç'
String textNormalizado = pattern.matcher(temp).replaceAll("").toLowerCase(); //recebe o texto normalizado digitado na combobox
String temp2; //normaliza o item da combobox
String itemNormalizado; //recebe o item da combobox normalizado
for (int i = 0; i < aModel.getSize(); i++) { //percorre os itens da comboBox
current = aModel.getElementAt(i).toString(); //recebe o item da iteração
temp2 = Normalizer.normalize(current, Normalizer.Form.NFD); //remove a acentuação do item da iteração
itemNormalizado = pattern.matcher(temp2).replaceAll("").toLowerCase(); //recebe o item da iteração normalizado
if (itemNormalizado.startsWith(textNormalizado)) {
System.out.println("entrou aqui igual");
tf.setText(current); //atribui o item à combobox
tf.setSelectionStart(text.length());
tf.setSelectionEnd(current.length());
setSelectedIndex(i); //foca a lista no item encontrado
break;
}
}
}
});
}
}
}
@Override
public int selectionForKey(char aKey, ComboBoxModel aModel) {
long now = new java.util.Date().getTime();
if (searchFor != null && aKey == KeyEvent.VK_BACK_SPACE && searchFor.length() > 0) {
searchFor = searchFor.substring(0, searchFor.length() - 1);
} else {
if (lap + 1000 < now) { //se o próximo caracter inserido foi digitado a menos de 1 segundo atrás
searchFor = "" + aKey; //acrescenta o caracter na pesquisa
} else {
searchFor = searchFor + aKey;
}
}
lap = now;
String current;
for (int i = 0; i < aModel.getSize(); i++) {
current = aModel.getElementAt(i).toString().toLowerCase();
if (current.toLowerCase().startsWith(searchFor.toLowerCase())) {
return i;
}
}
return -1;
}
@Override
public void fireActionEvent() {
super.fireActionEvent();
}
}
Para usar esse código, basta fazer:
JComboBox comboBox=new AutoCompleteComboBox();
UIManager.setLookAndFeel(new com.jgoodies.looks.plastic.PlasticXPLookAndFeel());
[img]http://image.bayimg.com/ialboaadp.jpg[/img]
Agora utilizando o L&F PlasticXPLookAndFeel, o item já aparece completo e não me deixa usar o autocomplete:
[img]http://image.bayimg.com/aalckaadp.jpg[/img]
Se alguém tiver uma ideia pra me ajudar, desde já agradeço.