-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathComboBoxAutoComplete.java
87 lines (77 loc) · 2.6 KB
/
ComboBoxAutoComplete.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package org.fxapps;
import java.text.Normalizer;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Tooltip;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Window;
/**
*
* Uses a combobox tooltip as the suggestion for auto complete and updates the
* combo box itens accordingly <br />
* It does not work with space, space and escape cause the combobox to hide and
* clean the filter ... Send me a PR if you want it to work with all characters
* -> It should be a custom controller - I KNOW!
*
* @author wsiqueir
*
* @param <T>
*/
public class ComboBoxAutoComplete<T> {
private ComboBox<T> cmb;
String filter = "";
private ObservableList<T> originalItems;
public ComboBoxAutoComplete(ComboBox<T> cmb) {
this.cmb = cmb;
originalItems = FXCollections.observableArrayList(cmb.getItems());
cmb.setTooltip(new Tooltip());
cmb.setOnKeyPressed(this::handleOnKeyPressed);
cmb.setOnHidden(this::handleOnHiding);
}
public void handleOnKeyPressed(KeyEvent e) {
ObservableList<T> filteredList = FXCollections.observableArrayList();
KeyCode code = e.getCode();
if (code.isLetterKey()) {
filter += e.getText();
}
if (code == KeyCode.BACK_SPACE && filter.length() > 0) {
filter = filter.substring(0, filter.length() - 1);
cmb.getItems().setAll(originalItems);
}
if (code == KeyCode.ESCAPE) {
filter = "";
}
if (filter.length() == 0) {
filteredList = originalItems;
cmb.getTooltip().hide();
} else {
Stream<T> itens = cmb.getItems().stream();
String txtUsr = unaccent(filter.toString().toLowerCase());
itens.filter(el -> unaccent(el.toString().toLowerCase()).contains(txtUsr)).forEach(filteredList::add);
cmb.getTooltip().setText(txtUsr);
Window stage = cmb.getScene().getWindow();
double posX = stage.getX() + cmb.getBoundsInParent().getMinX();
double posY = stage.getY() + cmb.getBoundsInParent().getMinY();
cmb.getTooltip().show(stage, posX, posY);
cmb.show();
}
cmb.getItems().setAll(filteredList);
}
public void handleOnHiding(Event e) {
filter = "";
cmb.getTooltip().hide();
T s = cmb.getSelectionModel().getSelectedItem();
cmb.getItems().setAll(originalItems);
cmb.getSelectionModel().select(s);
}
private String unaccent(String s) {
String temp = Normalizer.normalize(s, Normalizer.Form.NFD);
Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
return pattern.matcher(temp).replaceAll("");
}
}