1 package jalview.io.cache;
3 import jalview.util.MessageManager;
6 import java.awt.Dimension;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
9 import java.util.ArrayList;
10 import java.util.Collections;
11 import java.util.LinkedHashSet;
12 import java.util.List;
15 import javax.swing.BorderFactory;
16 import javax.swing.JComboBox;
17 import javax.swing.JLabel;
18 import javax.swing.JMenuItem;
19 import javax.swing.JPanel;
20 import javax.swing.JPopupMenu;
21 import javax.swing.JTextField;
22 import javax.swing.SwingUtilities;
23 import javax.swing.text.AttributeSet;
24 import javax.swing.text.BadLocationException;
25 import javax.swing.text.PlainDocument;
27 public class JvCacheableInputBox<E> extends JComboBox<String>
30 private static final long serialVersionUID = 5774610435079326695L;
32 private String cacheKey;
34 private AppCache appCache;
36 JPanel pnlDefaultCache = new JPanel();
38 JLabel lblDefaultCacheSize = new JLabel();
40 JTextField txtDefaultCacheSize = new JTextField();
42 JPopupMenu popup = new JPopupMenu();
44 JMenuItem menuItemClearCache = new JMenuItem();
46 final static int INPUT_LIMIT = 2;
49 public JvCacheableInputBox(String cacheKey)
52 this.cacheKey = cacheKey;
54 setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
55 appCache = AppCache.getInstance();
57 appCache.initCache(cacheKey);
63 * Initialise this cache's pop-up menu
65 private void initCachePopupMenu()
67 pnlDefaultCache.setBackground(Color.WHITE);
68 pnlDefaultCache.setBorder(BorderFactory.createEmptyBorder(0, 19, 0, 0));
69 txtDefaultCacheSize.setPreferredSize(new Dimension(45, 20));
70 lblDefaultCacheSize.setText(MessageManager
71 .getString("label.default_cache_size"));
72 // Force input to accept only Integer entries up to length - INPUT_LIMIT
73 txtDefaultCacheSize.setDocument(new PlainDocument()
75 private static final long serialVersionUID = 1L;
78 public void insertString(int offs, String str, AttributeSet a)
79 throws BadLocationException
81 if (getLength() + str.length() <= INPUT_LIMIT && isInteger(str))
83 super.insertString(offs, str, a);
87 txtDefaultCacheSize.setText(appCache.getCacheLmit(cacheKey));
88 pnlDefaultCache.add(lblDefaultCacheSize);
89 pnlDefaultCache.add(txtDefaultCacheSize);
90 menuItemClearCache.setText(MessageManager
91 .getString("action.clear_cached_items"));
92 menuItemClearCache.addActionListener(new ActionListener()
95 public void actionPerformed(ActionEvent e)
97 System.out.println(">>>>> Clear cache items");
99 appCache.deleteCacheItems(cacheKey);
104 popup.insert(pnlDefaultCache, 0);
105 popup.add(menuItemClearCache);
106 setComponentPopupMenu(popup);
111 * Answers true if input text is an integer
116 private boolean isInteger(String text)
120 Integer.parseInt(text);
122 } catch (NumberFormatException e)
129 * Method called to update the cache with the last user input
131 public void updateCache()
133 SwingUtilities.invokeLater(new Runnable()
138 int cacheLimit = appCache.updateCacheLimit(cacheKey,
139 txtDefaultCacheSize.getText());
140 String userInput = getUserInput();
141 if (userInput != null && !userInput.isEmpty())
143 LinkedHashSet<String> foundCache = appCache
144 .getAllCachedItemsFor(cacheKey);
145 // remove old cache item so as to place current input at the top of
147 foundCache.remove(userInput);
148 foundCache.add(userInput);
149 appCache.putCache(cacheKey, foundCache);
152 String lastSearch = userInput;
153 if (getItemCount() > 0)
157 Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
158 List<String> reversedCacheItems = new ArrayList<String>();
159 reversedCacheItems.addAll(cacheItems);
161 Collections.reverse(reversedCacheItems);
162 if (lastSearch.isEmpty())
167 if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
169 LinkedHashSet<String> foundCache = appCache
170 .getAllCachedItemsFor(cacheKey);
171 boolean prune = reversedCacheItems.size() > cacheLimit;
173 boolean limitExceeded = false;
174 for (String cacheItem : reversedCacheItems)
176 limitExceeded = (count++ > cacheLimit);
181 foundCache.remove(cacheItem);
193 appCache.putCache(cacheKey, foundCache);
195 setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
202 * This method should be called to persist the in-memory cache when this
203 * components parent frame is closed / exited
205 public void persistCache()
207 appCache.persistCache(cacheKey);
208 appCache.updateCacheLimit(cacheKey, txtDefaultCacheSize.getText());
212 * Method to obtain input text from the cache box
216 public String getUserInput()
218 return getEditor().getItem() == null ? "" : getEditor().getItem()