Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
AutoCompletion.java
Go to the documentation of this file.
1 package org.sleuthkit.autopsy.guicomponentutils;
2 
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.FocusAdapter;
6 import java.awt.event.FocusEvent;
7 import java.awt.event.FocusListener;
8 import java.awt.event.KeyAdapter;
9 import java.awt.event.KeyEvent;
10 import java.awt.event.KeyListener;
11 import java.beans.PropertyChangeEvent;
12 import java.beans.PropertyChangeListener;
13 import javax.swing.ComboBoxEditor;
14 import javax.swing.ComboBoxModel;
15 import javax.swing.JComboBox;
16 import javax.swing.text.AttributeSet;
17 import javax.swing.text.BadLocationException;
18 import javax.swing.text.JTextComponent;
19 import javax.swing.text.PlainDocument;
20 
21 
22 /*
23  * This code is taken from http://www.orbital-computer.de/JComboBox/source/AutoCompletion.java
24  * Author: Thomas Bierhance
25  * This work is hereby released into the Public Domain. To view a copy of the
26  * public domain dedication, visit
27  * http://creativecommons.org/licenses/publicdomain/
28  */
29 public class AutoCompletion extends PlainDocument {
30 
31  private static final long serialVersionUID = 1L;
32 
33  private JComboBox<?> comboBox;
34  private ComboBoxModel<?> model;
35  private JTextComponent editor;
36 // flag to indicate if setSelectedItem has been called
37 // subsequent calls to remove/insertString should be ignored
38  private boolean selecting = false;
39  private boolean hidePopupOnFocusLoss;
40  private boolean hitBackspace = false;
41  private boolean hitBackspaceOnSelection;
42 
43  private KeyListener editorKeyListener;
44  private FocusListener editorFocusListener;
45 
46  public AutoCompletion(final JComboBox<?> comboBox) {
47  this.comboBox = comboBox;
48  model = comboBox.getModel();
49  comboBox.addActionListener(new ActionListener() {
50  @Override
51  public void actionPerformed(ActionEvent e) {
52  if (!selecting) {
54  }
55  }
56  });
57  comboBox.addPropertyChangeListener(new PropertyChangeListener() {
58  @Override
59  public void propertyChange(PropertyChangeEvent e) {
60  if (e.getPropertyName().equals("editor")) {
61  configureEditor((ComboBoxEditor) e.getNewValue());
62  }
63  if (e.getPropertyName().equals("model")) {
64  model = (ComboBoxModel) e.getNewValue();
65  }
66  }
67  });
68  editorKeyListener = new KeyAdapter() {
69  @Override
70  public void keyPressed(KeyEvent e) {
71  if (comboBox.isDisplayable()) {
72  comboBox.setPopupVisible(true);
73  }
74  hitBackspace = false;
75  switch (e.getKeyCode()) {
76  // determine if the pressed key is backspace (needed by the remove method)
77  case KeyEvent.VK_BACK_SPACE:
78  hitBackspace = true;
79  hitBackspaceOnSelection = editor.getSelectionStart() != editor.getSelectionEnd();
80  break;
81  // ignore delete key
82  case KeyEvent.VK_DELETE:
83  e.consume();
84  comboBox.getToolkit().beep();
85  break;
86  }
87  }
88  };
89  // Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out
90  hidePopupOnFocusLoss = System.getProperty("java.version").startsWith("1.5");
91  // Highlight whole text when gaining focus
92  editorFocusListener = new FocusAdapter() {
93  @Override
94  public void focusGained(FocusEvent e) {
96  }
97 
98  @Override
99  public void focusLost(FocusEvent e) {
100  // Workaround for Bug 5100422 - Hide Popup on focus loss
101  if (hidePopupOnFocusLoss) {
102  comboBox.setPopupVisible(false);
103  }
104  }
105  };
106  configureEditor(comboBox.getEditor());
107  // Handle initially selected object
108  Object selected = comboBox.getSelectedItem();
109  if (selected != null) {
110  setText(selected.toString());
111  }
113  }
114 
115  public static void enable(JComboBox<?> comboBox) {
116  // has to be editable
117  comboBox.setEditable(true);
118  // change the editor's document
119  new AutoCompletion(comboBox);
120  }
121 
122  void configureEditor(ComboBoxEditor newEditor) {
123  if (editor != null) {
124  editor.removeKeyListener(editorKeyListener);
125  editor.removeFocusListener(editorFocusListener);
126  }
127 
128  if (newEditor != null) {
129  editor = (JTextComponent) newEditor.getEditorComponent();
130  editor.addKeyListener(editorKeyListener);
131  editor.addFocusListener(editorFocusListener);
132  editor.setDocument(this);
133  }
134  }
135 
136  public void remove(int offs, int len) throws BadLocationException {
137  // return immediately when selecting an item
138  if (selecting) {
139  return;
140  }
141  if (hitBackspace) {
142  // user hit backspace => move the selection backwards
143  // old item keeps being selected
144  if (offs > 0) {
145  if (hitBackspaceOnSelection) {
146  offs--;
147  }
148  } else {
149  // User hit backspace with the cursor positioned on the start => beep
150  comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
151  }
153  } else {
154  super.remove(offs, len);
155  }
156  }
157 
158  @Override
159  public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
160  // return immediately when selecting an item
161  if (selecting) {
162  return;
163  }
164  // insert the string into the document
165  super.insertString(offs, str, a);
166  // lookup and select a matching item
167  Object item = lookupItem(getText(0, getLength()));
168  if (item != null) {
169  setSelectedItem(item);
170  } else {
171  // keep old item selected if there is no match
172  item = comboBox.getSelectedItem();
173  // imitate no insert (later on offs will be incremented by str.length(): selection won't move forward)
174  offs = offs - str.length();
175  // provide feedback to the user that his input has been received but can not be accepted
176  comboBox.getToolkit().beep(); // when available use: UIManager.getLookAndFeel().provideErrorFeedback(comboBox);
177  }
178  setText(item.toString());
179  // select the completed part
180  highlightCompletedText(offs + str.length());
181  }
182 
183  private void setText(String text) {
184  try {
185  // remove all text and insert the completed string
186  super.remove(0, getLength());
187  super.insertString(0, text, null);
188  } catch (BadLocationException e) {
189  throw new RuntimeException(e.toString());
190  }
191  }
192 
193  private void highlightCompletedText(int start) {
194  editor.setCaretPosition(getLength());
195  editor.moveCaretPosition(start);
196  }
197 
198  private void setSelectedItem(Object item) {
199  selecting = true;
200  model.setSelectedItem(item);
201  selecting = false;
202  }
203 
204  private Object lookupItem(String pattern) {
205  Object selectedItem = model.getSelectedItem();
206  // only search for a different item if the currently selected does not match
207  if (selectedItem != null && startsWithIgnoreCase(selectedItem.toString(), pattern)) {
208  return selectedItem;
209  } else {
210  // iterate over all items
211  for (int i = 0, n = model.getSize(); i < n; i++) {
212  Object currentItem = model.getElementAt(i);
213  // current item starts with the pattern?
214  if (currentItem != null && startsWithIgnoreCase(currentItem.toString(), pattern)) {
215  return currentItem;
216  }
217  }
218  }
219  // no item starts with the pattern => return null
220  return null;
221  }
222 
223 // checks if str1 starts with str2 - ignores case
224  private boolean startsWithIgnoreCase(String str1, String str2) {
225  return str1.toUpperCase().startsWith(str2.toUpperCase());
226  }
227 
228 }
void insertString(int offs, String str, AttributeSet a)
boolean startsWithIgnoreCase(String str1, String str2)

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.