1 package edu.jiangxin.apktoolbox.swing.extend.autocomplete;
2
3 import org.apache.commons.lang3.StringUtils;
4
5 import javax.swing.*;
6 import java.awt.*;
7 import java.awt.event.KeyEvent;
8 import java.awt.event.KeyListener;
9 import java.util.ArrayList;
10 import java.util.List;
11
12 class AutoCompleter<E> implements KeyListener {
13 private JComboBox<E> comboBox;
14 private JTextField textField;
15 private ComboBoxModel<E> comboBoxModel;
16
17 public AutoCompleter(JComboBox<E> comboBox) {
18 if (comboBox == null) {
19 throw new AutoCompleterInitException("comboBox is null");
20 }
21 this.comboBox = comboBox;
22 ComboBoxEditor comboBoxEditor = comboBox.getEditor();
23 if (comboBoxEditor == null) {
24 throw new AutoCompleterInitException("comboBoxEditor is null");
25 }
26 Component component = comboBoxEditor.getEditorComponent();
27 if (!(component instanceof JTextField)) {
28 throw new AutoCompleterInitException("component is invalid");
29 }
30 this.textField = (JTextField) component;
31 this.textField.addKeyListener(this);
32 this.comboBoxModel = comboBox.getModel();
33 }
34
35 @Override
36 public void keyTyped(KeyEvent e) {
37
38 }
39
40 @Override
41 public void keyPressed(KeyEvent e) {
42
43 }
44
45 @Override
46 public void keyReleased(KeyEvent e) {
47 char keyChar = e.getKeyChar();
48 if (Character.isAlphabetic(keyChar) || Character.isDigit(keyChar) || Character.isWhitespace(keyChar)
49 || keyChar == KeyEvent.VK_BACK_SPACE) {
50 String text = textField.getText();
51 autoComplete(text);
52 textField.setText(text);
53 }
54 }
55
56 protected void autoComplete(String text) {
57 E[] opts = getMatchingOptions(text);
58 comboBox.setModel(new DefaultComboBoxModel<>(opts));
59 if (comboBox.getItemCount() > 0) {
60 comboBox.showPopup();
61 }
62 }
63
64 @SuppressWarnings("unchecked")
65 private E[] getMatchingOptions(String text) {
66 List<E> list = new ArrayList<>();
67 ComboBoxModel<E> tmp = this.comboBoxModel;
68 for (int i = 0; i < tmp.getSize(); i++) {
69 E itemObj = tmp.getElementAt(i);
70 if (StringUtils.isEmpty(text) || StringUtils.containsIgnoreCase(itemObj.toString(), text)) {
71 list.add(itemObj);
72 }
73 }
74 return (E[]) list.toArray();
75 }
76
77 }