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 // pad panel so as to align with other menu items
69 pnlDefaultCache.setBorder(BorderFactory.createEmptyBorder(0, 19, 0, 0));
70 txtDefaultCacheSize.setPreferredSize(new Dimension(45, 20));
71 lblDefaultCacheSize.setText(MessageManager
72 .getString("label.default_cache_size"));
73 // Force input to accept only Integer entries up to length - INPUT_LIMIT
74 txtDefaultCacheSize.setDocument(new PlainDocument()
76 private static final long serialVersionUID = 1L;
79 public void insertString(int offs, String str, AttributeSet a)
80 throws BadLocationException
82 if (getLength() + str.length() <= INPUT_LIMIT && isInteger(str))
84 super.insertString(offs, str, a);
88 txtDefaultCacheSize.setText(appCache.getCacheLmit(cacheKey));
89 pnlDefaultCache.add(lblDefaultCacheSize);
90 pnlDefaultCache.add(txtDefaultCacheSize);
91 menuItemClearCache.setText(MessageManager
92 .getString("action.clear_cached_items"));
93 menuItemClearCache.addActionListener(new ActionListener()
96 public void actionPerformed(ActionEvent e)
98 System.out.println(">>>>> Clear cache items");
100 appCache.deleteCacheItems(cacheKey);
105 popup.insert(pnlDefaultCache, 0);
106 popup.add(menuItemClearCache);
107 setComponentPopupMenu(popup);
112 * Answers true if input text is an integer
117 static boolean isInteger(String text)
121 Integer.parseInt(text);
123 } catch (NumberFormatException e)
130 * Method called to update the cache with the last user input
132 public void updateCache()
134 SwingUtilities.invokeLater(new Runnable()
139 int cacheLimit = appCache.updateCacheLimit(cacheKey,
140 txtDefaultCacheSize.getText());
141 String userInput = getUserInput();
142 if (userInput != null && !userInput.isEmpty())
144 LinkedHashSet<String> foundCache = appCache
145 .getAllCachedItemsFor(cacheKey);
146 // remove old cache item so as to place current input at the top of
148 foundCache.remove(userInput);
149 foundCache.add(userInput);
150 appCache.putCache(cacheKey, foundCache);
153 String lastSearch = userInput;
154 if (getItemCount() > 0)
158 Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
159 List<String> reversedCacheItems = new ArrayList<String>();
160 reversedCacheItems.addAll(cacheItems);
162 Collections.reverse(reversedCacheItems);
163 if (lastSearch.isEmpty())
168 if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
170 LinkedHashSet<String> foundCache = appCache
171 .getAllCachedItemsFor(cacheKey);
172 boolean prune = reversedCacheItems.size() > cacheLimit;
174 boolean limitExceeded = false;
175 for (String cacheItem : reversedCacheItems)
177 limitExceeded = (count++ > cacheLimit);
182 foundCache.remove(cacheItem);
194 appCache.putCache(cacheKey, foundCache);
196 setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
203 * This method should be called to persist the in-memory cache when this
204 * components parent frame is closed / exited
206 public void persistCache()
208 appCache.persistCache(cacheKey);
209 appCache.updateCacheLimit(cacheKey, txtDefaultCacheSize.getText());
213 * Method to obtain input text from the cache box
217 public String getUserInput()
219 return getEditor().getItem() == null ? "" : getEditor().getItem()