1 package nl.tudelft.goal.ut2004.visualizer.gui.widgets;
2
3 import java.awt.Component;
4 import java.awt.event.ActionListener;
5 import java.awt.event.KeyAdapter;
6 import java.awt.event.KeyEvent;
7 import java.util.List;
8
9 import javax.swing.ComboBoxEditor;
10 import javax.swing.JComboBox;
11 import javax.swing.JTextField;
12 import javax.swing.SwingUtilities;
13
14 class SuggestionFieldEditor implements ComboBoxEditor {
15
16 private final JTextField textField;
17 private final SuggestionModel model;
18 private int nextSuggestionIndex = 0;
19 private final JComboBox combobox;
20
21 public SuggestionFieldEditor(JComboBox combobox, SuggestionModel model) {
22 this.textField = new JTextField();
23 this.model = model;
24 this.combobox = combobox;
25 this.textField.addKeyListener(new Listener());
26 }
27
28 private class Listener extends KeyAdapter {
29
30 @Override
31 public void keyPressed(final KeyEvent e) {
32
33 SwingUtilities.invokeLater(new Runnable() {
34 @Override
35 public void run() {
36 updateSuggestion(isAutoCompletionRequest(e));
37 }
38 });
39 }
40 }
41
42 private boolean isAutoCompletionRequest(KeyEvent e) {
43 return e.isControlDown() && e.getKeyChar() == ' ';
44 }
45
46 private void updateSuggestion(boolean complete) {
47
48
49 combobox.hidePopup();
50
51 String query = getUnselectedText();
52
53
54
55 List<String> suggestions = model.sugestFor(query);
56
57
58 if (suggestions.size() > 0
59
60
61 && (isQueryEdited(query) || complete)) {
62 nextSuggestionIndex %= suggestions.size();
63 String suggestion = suggestions.get(nextSuggestionIndex++);
64
65 updateCompletion(complete, query, suggestion);
66
67 } else {
68
69 nextSuggestionIndex = 0;
70 }
71
72
73
74 combobox.showPopup();
75 }
76
77 private String previousQuery = null;
78
79
80
81
82
83
84 private boolean isQueryEdited(String query) {
85 boolean edited = previousQuery != null
86 && query.length() > previousQuery.length()
87 && query.startsWith(previousQuery);
88
89 previousQuery = query;
90 return edited;
91 }
92
93
94
95
96
97
98
99
100
101
102
103
104 private void updateCompletion(boolean showSuggestion, String query,
105 String suggestion) {
106
107
108 if (showSuggestion
109
110 || (suggestion.startsWith(query) && query.length() > 0)) {
111
112 textField.setText(suggestion);
113
114
115
116 if (suggestion.startsWith(query)) {
117 textField.select(query.length(), suggestion.length());
118 }
119
120 else {
121 textField.select(suggestion.indexOf(query) + query.length(),
122 suggestion.length());
123 }
124 }
125 }
126
127
128
129
130
131
132
133
134 private String getUnselectedText() {
135
136 String selected = textField.getSelectedText();
137 String fullText = textField.getText();
138
139
140 if (selected != null && fullText.endsWith(selected)) {
141 return fullText.substring(0, fullText.indexOf(selected));
142 }
143
144
145 return fullText;
146 }
147
148 @Override
149 public Component getEditorComponent() {
150 return textField;
151 }
152
153 @Override
154 public Object getItem() {
155 return model.getItem(textField.getText());
156 }
157
158 @Override
159 public void removeActionListener(ActionListener l) {
160 textField.removeActionListener(l);
161 }
162
163 @Override
164 public void addActionListener(ActionListener l) {
165 textField.addActionListener(l);
166
167 }
168
169 @Override
170 public void selectAll() {
171 textField.selectAll();
172 }
173
174 @Override
175 public void setItem(Object item) {
176 if (item != null) {
177 textField.setText(item.toString());
178 } else {
179 textField.setText("");
180 }
181 }
182
183 }