View Javadoc
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          // do nothing
38      }
39  
40      @Override
41      public void keyPressed(KeyEvent e) {
42          // do nothing
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  }