1 | sbool AutoComboBox3_handleTab = true;
|
2 |
|
3 | sclass AutoComboBox3 extends JComboBox<S> {
|
4 | F1<S, Collection<S>> entryMaker; // called (serially) in non-AWT thread
|
5 | ReliableSingleThread rst = new(r { update2() });
|
6 | S textBehindModel;
|
7 |
|
8 | *() { this(null); }
|
9 |
|
10 | *(F1<S, Collection<S>> *entryMaker) {
|
11 | setSelectedIndex(-1);
|
12 | setEditable(true);
|
13 | JTextField text = cast this.getEditor().getEditorComponent();
|
14 | text.setFocusable(true);
|
15 |
|
16 | text.addKeyListener(new KeyAdapter {
|
17 | public void /*keyPressed*/keyReleased(KeyEvent key) {
|
18 | if (key.getKeyCode() == KeyEvent.VK_ENTER) ret;
|
19 |
|
20 | if (key.getKeyCode() == KeyEvent.VK_ESCAPE) { hidePopup(); ret; }
|
21 |
|
22 | if (AutoComboBox3_handleTab && key.getKeyCode() == KeyEvent.VK_TAB /*&& key.getModifiers() == 0*/) {
|
23 | //_print("Have tab event (modifiers=" + key.getModifiers() + ")");
|
24 | if (key.getModifiers() == 0 && isPopupVisible()) {
|
25 | setSelectedIndex(0); // accept item
|
26 | hidePopup();
|
27 | } else // standard tab behavior
|
28 | swing_standardTabBehavior(key);
|
29 |
|
30 | ret;
|
31 | }
|
32 |
|
33 | JTextField tf = cast getEditor().getEditorComponent();
|
34 | if (tf.getCaretPosition() != l(tf.getText())) ret;
|
35 |
|
36 | update();
|
37 | }
|
38 | });
|
39 |
|
40 | if (AutoComboBox3_handleTab)
|
41 | text.setFocusTraversalKeysEnabled(false);
|
42 | }
|
43 |
|
44 | Collection<S> getSuggestions(S text) {
|
45 | ret callF(entryMaker, text);
|
46 | }
|
47 |
|
48 | JTextField textField() {
|
49 | ret (JTextField) getEditor().getEditorComponent();
|
50 | }
|
51 |
|
52 | void update {
|
53 | if (neq(getText(textField()), textBehindModel))
|
54 | rst.trigger();
|
55 | }
|
56 |
|
57 | bool setTextBehindModel(fS text) {
|
58 | ret swing(func -> Bool {
|
59 | if (eq(text, textBehindModel)) false;
|
60 | textBehindModel = text;
|
61 | true;
|
62 | });
|
63 | }
|
64 |
|
65 | void update2 {
|
66 | fS text = getText(textField());
|
67 | if (!setTextBehindModel(text)) ret;
|
68 | try {
|
69 | final Vector list = new Vector(getSuggestions(text));
|
70 | swing {
|
71 | if (nempty(list)) {
|
72 | S currentText = getText(textField());
|
73 | setModel(new DefaultComboBoxModel(list));
|
74 | setTextBehindModel(text);
|
75 | setSelectedIndex(-1);
|
76 | textField().setText(currentText);
|
77 | showPopup();
|
78 | } else
|
79 | hidePopup();
|
80 | }
|
81 | } catch print e {
|
82 | setTextBehindModel(null);
|
83 | }
|
84 | }
|
85 | } |