forked from nus-cs2103-AY1920S1/addressbook-level3
/
AutoComplete.java
151 lines (140 loc) · 5.68 KB
/
AutoComplete.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package seedu.revision.ui;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javafx.geometry.Side;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import seedu.revision.logic.commands.main.AddCommand;
import seedu.revision.logic.commands.main.ClearCommand;
import seedu.revision.logic.commands.main.DeleteCommand;
import seedu.revision.logic.commands.main.EditCommand;
import seedu.revision.logic.commands.main.ExitCommand;
import seedu.revision.logic.commands.main.FindCommand;
import seedu.revision.logic.commands.main.HelpCommand;
import seedu.revision.logic.commands.main.HistoryCommand;
import seedu.revision.logic.commands.main.ListCommand;
import seedu.revision.logic.commands.main.RestoreCommand;
import seedu.revision.logic.commands.main.StartCommand;
import seedu.revision.logic.commands.main.StatsCommand;
/**
* This class is a TextField which implements an "autocomplete" functionality.
* Entries based on Command_Usage.
* @@author ShaunNgTX
*/
public class AutoComplete extends TextField {
/** Entries based on Command_Usage. */
private static final SortedSet<String> entries = new TreeSet<>();
private static final SortedSet<String> entriesWithFixedCommand = new TreeSet<>();
/** The popup of Auto-Complete list. */
private ContextMenu popUpEntries;
private boolean isFixedCommand;
/**
* Constructor for autocomplete.
*/
public AutoComplete() {
super();
this.setEntries();
this.setEntriesWithFixedCommand();
this.isFixedCommand = false;
popUpEntries = new ContextMenu();
textProperty().addListener((observableValue, s, s2) -> {
if (getText().length() == 0) {
popUpEntries.hide();
} else {
for (String subItems : entriesWithFixedCommand) {
if (isContain(subItems, getText())) {
isFixedCommand = true;
}
}
if (isFixedCommand) {
popUpEntries.hide();
} else {
popUpEntries.hide();
LinkedList<String> searchResult = new LinkedList<>();
searchResult.addAll(entries.subSet(getText(), getText() + Character.MAX_VALUE));
populatePopup(searchResult);
if (!popUpEntries.isShowing()) {
popUpEntries.show(AutoComplete.this, Side.BOTTOM, 20, 0);
}
}
}
isFixedCommand = false;
});
focusedProperty().addListener((observableValue, aBoolean, aBoolean2) ->
popUpEntries.hide());
}
/**
* Get the existing set of autocomplete entries.
* Basically the respective command words.
*/
private void setEntries() {
entries.add(AddCommand.COMPLETE_COMMAND);
entries.add(ClearCommand.COMMAND_WORD);
entries.add(DeleteCommand.COMMAND_WORD);
entries.add(EditCommand.COMMAND_WORD);
entries.add(ExitCommand.COMMAND_WORD);
entries.add(FindCommand.COMMAND_WORD);
entries.add(ListCommand.COMMAND_WORD);
entries.add(ListCommand.COMPLETE_COMMAND_DIFF);
entries.add(ListCommand.COMPLETE_COMMAND_CAT);
entries.add(HelpCommand.COMMAND_WORD);
entries.add(RestoreCommand.COMMAND_WORD);
entries.add(StartCommand.COMMAND_AUTOCOMPLETE);
entries.add(StartCommand.COMMAND_AUTOCOMPLETE_NORMAL);
entries.add(StartCommand.COMMAND_AUTOCOMPLETE_ARCADE);
entries.add(StartCommand.COMMAND_AUTOCOMPLETE_CUSTOM);
entries.add(HistoryCommand.COMMAND_WORD);
entries.add(StatsCommand.COMMAND_WORD);
}
/**
* Set another entries to remove the double enter problem.
*/
private void setEntriesWithFixedCommand() {
entriesWithFixedCommand.add(ClearCommand.COMMAND_WORD);
entriesWithFixedCommand.add(ExitCommand.COMMAND_WORD);
entriesWithFixedCommand.add(ListCommand.COMMAND_WORD);
entriesWithFixedCommand.add(HelpCommand.COMMAND_WORD);
entriesWithFixedCommand.add(RestoreCommand.COMMAND_WORD);
entriesWithFixedCommand.add(HistoryCommand.COMMAND_WORD);
}
/**
* Populate the entry set with the given search results.
* @param searchResult The set of matching strings.
*/
private void populatePopup(List<String> searchResult) {
List<CustomMenuItem> menuItems = new LinkedList<>();
int maxEntries = 10;
int count = Math.min(searchResult.size(), maxEntries);
// Most probably won't exceed 10 but just in case.
for (int i = 0; i < count; i++) {
final String result = searchResult.get(i);
Label entryLabel = new Label(result);
CustomMenuItem item = new CustomMenuItem(entryLabel, true);
item.setOnAction(actionEvent -> {
setText(result);
popUpEntries.hide();
});
menuItems.add(item);
}
popUpEntries.getItems().clear();
popUpEntries.getItems().addAll(menuItems);
}
/**
*
* @param source String that you comparing to.
* @param subItem String that you using to compare.
* @return True if subItem is in source, false otherwise.
*/
private static boolean isContain(String source, String subItem) {
String pattern = "\\b" + subItem + "\\b";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(source);
return m.find();
}
}