Clover icon

jalviewX

  1. Project Clover database Wed Oct 31 2018 15:13:58 GMT
  2. Package jalview.io.cache

File JvCacheableInputBox.java

 

Coverage histogram

../../../img/srcFileCovDistChart7.png
28% of files have more coverage

Code metrics

52
104
22
1
398
289
52
0.5
4.73
22
2.36

Classes

Class Line # Actions
JvCacheableInputBox 61 104 52 68
0.617977561.8%
 

Contributing tests

This file is covered by 4 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.io.cache;
22   
23    import jalview.bin.Cache;
24    import jalview.bin.Jalview;
25    import jalview.util.MessageManager;
26   
27    import java.awt.event.ActionEvent;
28    import java.awt.event.ActionListener;
29    import java.awt.event.FocusListener;
30    import java.awt.event.KeyAdapter;
31    import java.awt.event.KeyEvent;
32    import java.awt.event.KeyListener;
33    import java.util.ArrayList;
34    import java.util.Arrays;
35    import java.util.Collections;
36    import java.util.LinkedHashSet;
37    import java.util.List;
38    import java.util.Set;
39   
40    import javax.swing.JComboBox;
41    import javax.swing.JComponent;
42    import javax.swing.JMenuItem;
43    import javax.swing.JPopupMenu;
44    import javax.swing.JTextField;
45    import javax.swing.SwingUtilities;
46    import javax.swing.event.CaretListener;
47    import javax.swing.event.DocumentListener;
48    import javax.swing.text.JTextComponent;
49   
50    /**
51    * A class that provides an editable combobox with a memory of previous entries
52    * that may be persisted
53    *
54    * @author tcofoegbu
55    *
56    * @param <E>
57    */
58    /*
59    * (temporary?) patches to wrap a JTextField instead when running as Javascript
60    */
 
61    public class JvCacheableInputBox<E>
62    {
63    private JComboBox<String> comboBox; // used for Jalview
64   
65    private JTextField textField; // used for JalviewJS
66   
67    private static final long serialVersionUID = 5774610435079326695L;
68   
69    private String cacheKey;
70   
71    private AppCache appCache;
72   
73    private JPopupMenu popup = new JPopupMenu();
74   
75    private JMenuItem menuItemClearCache = new JMenuItem();
76   
77    volatile boolean enterWasPressed = false;
78   
79    /**
80    * @return flag indicating if the most recent keypress was enter
81    */
 
82  0 toggle public boolean wasEnterPressed()
83    {
84  0 return enterWasPressed;
85    }
86   
87    /**
88    * Constructor
89    *
90    * @param newCacheKey
91    */
 
92  4 toggle public JvCacheableInputBox(String newCacheKey)
93    {
94  4 super();
95  4 if (Jalview.isJS())
96    {
97  0 textField = new JTextField();
98  0 return;
99    }
100   
101  4 this.cacheKey = newCacheKey;
102  4 comboBox = new JComboBox<String>();
103  4 comboBox.setEditable(true);
104  4 comboBox.addKeyListener(new KeyAdapter()
105    {
 
106  0 toggle @Override
107    public void keyTyped(KeyEvent e)
108    {
109  0 enterWasPressed = false;
110  0 if (e.getKeyCode() == KeyEvent.VK_ENTER)
111    {
112  0 enterWasPressed = true;
113    }
114    // let event bubble up
115    }
116    });
117  4 comboBox.setPrototypeDisplayValue(
118    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
119  4 appCache = AppCache.getInstance();
120  4 initCachePopupMenu();
121  4 initCache(newCacheKey);
122  4 updateCache();
123    }
124   
125    /**
126    * Method for initialising cache items for a given cache key and populating the
127    * in-memory cache with persisted cache items
128    *
129    * @param cacheKey
130    */
 
131  4 toggle private void initCache(String cacheKey)
132    {
133    // obtain persisted cache items from properties file as a delimited string
134  4 String delimitedCacheStr = Cache.getProperty(cacheKey);
135  4 if (delimitedCacheStr == null || delimitedCacheStr.isEmpty())
136    {
137  4 return;
138    }
139    // convert delimited cache items to a list of strings
140  0 List<String> persistedCacheItems = Arrays
141    .asList(delimitedCacheStr.split(AppCache.CACHE_DELIMITER));
142   
143  0 LinkedHashSet<String> foundCacheItems = appCache
144    .getAllCachedItemsFor(cacheKey);
145  0 if (foundCacheItems == null)
146    {
147  0 foundCacheItems = new LinkedHashSet<>();
148    }
149    // populate memory cache
150  0 for (String cacheItem : persistedCacheItems)
151    {
152  0 foundCacheItems.add(cacheItem);
153    }
154  0 appCache.putCache(cacheKey, foundCacheItems);
155    }
156   
157    /**
158    * Initialise this cache's pop-up menu
159    */
 
160  4 toggle private void initCachePopupMenu()
161    {
162  4 menuItemClearCache.setFont(new java.awt.Font("Verdana", 0, 12));
163  4 menuItemClearCache
164    .setText(MessageManager.getString("action.clear_cached_items"));
165  4 menuItemClearCache.addActionListener(new ActionListener()
166    {
 
167  0 toggle @Override
168    public void actionPerformed(ActionEvent e)
169    {
170    // System.out.println(">>>>> Clear cache items");
171  0 setSelectedItem("");
172  0 appCache.deleteCacheItems(cacheKey);
173  0 updateCache();
174    }
175    });
176   
177  4 popup.add(menuItemClearCache);
178  4 comboBox.setComponentPopupMenu(popup);
179  4 comboBox.add(popup);
180    }
181   
182    /**
183    * Answers true if input text is an integer
184    *
185    * @param text
186    * @return
187    */
 
188  0 toggle static boolean isInteger(String text)
189    {
190  0 try
191    {
192  0 Integer.parseInt(text);
193  0 return true;
194    } catch (NumberFormatException e)
195    {
196  0 return false;
197    }
198    }
199   
200    /**
201    * Method called to update the cache with the last user input
202    */
 
203  7 toggle public void updateCache()
204    {
205  7 if (Jalview.isJS())
206    {
207  0 return;
208    }
209  7 SwingUtilities.invokeLater(new Runnable()
210    {
 
211  7 toggle @Override
212    public void run()
213    {
214  7 int cacheLimit = Integer.parseInt(appCache.getCacheLimit(cacheKey));
215  7 String userInput = getUserInput();
216  7 if (userInput != null && !userInput.isEmpty())
217    {
218  1 LinkedHashSet<String> foundCache = appCache
219    .getAllCachedItemsFor(cacheKey);
220    // remove old cache item so as to place current input at the top of
221    // the result
222  1 foundCache.remove(userInput);
223  1 foundCache.add(userInput);
224  1 appCache.putCache(cacheKey, foundCache);
225    }
226   
227  7 String lastSearch = userInput;
228  7 if (comboBox.getItemCount() > 0)
229    {
230  3 comboBox.removeAllItems();
231    }
232  7 Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
233  7 List<String> reversedCacheItems = new ArrayList<>();
234  7 reversedCacheItems.addAll(cacheItems);
235  7 cacheItems = null;
236  7 Collections.reverse(reversedCacheItems);
237  7 if (lastSearch.isEmpty())
238    {
239  6 comboBox.addItem("");
240    }
241   
242  7 if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
243    {
244  1 LinkedHashSet<String> foundCache = appCache
245    .getAllCachedItemsFor(cacheKey);
246  1 boolean prune = reversedCacheItems.size() > cacheLimit;
247  1 int count = 1;
248  1 boolean limitExceeded = false;
249  1 for (String cacheItem : reversedCacheItems)
250    {
251  1 limitExceeded = (count++ > cacheLimit);
252  1 if (prune)
253    {
254  0 if (limitExceeded)
255    {
256  0 foundCache.remove(cacheItem);
257    }
258    else
259    {
260  0 comboBox.addItem(cacheItem);
261    }
262    }
263    else
264    {
265  1 comboBox.addItem(cacheItem);
266    }
267    }
268  1 appCache.putCache(cacheKey, foundCache);
269    }
270  7 setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
271    }
272    });
273    }
274   
275    /**
276    * This method should be called to persist the in-memory cache when this
277    * components parent frame is closed / exited
278    */
 
279  2 toggle public void persistCache()
280    {
281  2 if (!Jalview.isJS())
282    {
283  2 appCache.persistCache(cacheKey);
284    }
285    }
286   
287    /**
288    * Returns the trimmed text in the input field
289    *
290    * @return
291    */
 
292  9 toggle public String getUserInput()
293    {
294  9 if (Jalview.isJS())
295    {
296  0 return textField.getText().trim();
297    }
298  9 Object item = comboBox.getEditor().getItem();
299  9 return item == null ? "" : item.toString().trim();
300    }
301   
 
302  7 toggle public JComponent getComponent()
303    {
304  7 return Jalview.isJS() ? textField : comboBox;
305    }
306   
 
307  1 toggle public void addActionListener(ActionListener actionListener)
308    {
309  1 if (Jalview.isJS())
310    {
311  0 textField.addActionListener(actionListener);
312    }
313    else
314    {
315  1 comboBox.addActionListener(actionListener);
316    }
317    }
318   
 
319  1 toggle public void addDocumentListener(DocumentListener listener)
320    {
321  1 if (!Jalview.isJS())
322    {
323  1 ((JTextComponent) comboBox.getEditor().getEditorComponent())
324    .getDocument().addDocumentListener(listener);
325    }
326    }
327   
 
328  3 toggle public void addFocusListener(FocusListener focusListener)
329    {
330  3 if (Jalview.isJS())
331    {
332  0 textField.addFocusListener(focusListener);
333    }
334    else
335    {
336  3 comboBox.addFocusListener(focusListener);
337    }
338    }
339   
 
340  3 toggle public void addKeyListener(KeyListener kl)
341    {
342  3 if (!Jalview.isJS())
343    {
344  3 comboBox.getEditor().getEditorComponent().addKeyListener(kl);
345    }
346    }
347   
 
348  0 toggle public void setEditable(boolean b)
349    {
350  0 if (!Jalview.isJS())
351    {
352  0 comboBox.setEditable(b);
353    }
354    }
355   
 
356  2 toggle public void setPrototypeDisplayValue(String string)
357    {
358  2 if (!Jalview.isJS())
359    {
360  2 comboBox.setPrototypeDisplayValue(string);
361    }
362    }
363   
 
364  9 toggle public void setSelectedItem(String userInput)
365    {
366  9 if (!Jalview.isJS())
367    {
368  9 comboBox.setSelectedItem(userInput);
369    }
370    }
371   
 
372  0 toggle public boolean isPopupVisible()
373    {
374  0 if (!Jalview.isJS())
375    {
376  0 return comboBox.isPopupVisible();
377    }
378  0 return false;
379    }
380   
 
381  0 toggle public void addCaretListener(CaretListener caretListener)
382    {
383  0 if (!Jalview.isJS())
384    {
385  0 ((JTextComponent) comboBox.getEditor().getEditorComponent())
386    .addCaretListener(caretListener);
387    }
388    }
389   
 
390  2 toggle public void addItem(String item)
391    {
392  2 if (!Jalview.isJS())
393    {
394  2 comboBox.addItem(item);
395    }
396    }
397   
398    }