2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.io.cache;
23 import jalview.bin.Cache;
24 import jalview.util.MessageManager;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.awt.event.KeyEvent;
29 import java.awt.event.KeyListener;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collections;
33 import java.util.LinkedHashSet;
34 import java.util.List;
37 import javax.swing.JComboBox;
38 import javax.swing.JMenuItem;
39 import javax.swing.JPopupMenu;
40 import javax.swing.SwingUtilities;
42 public class JvCacheableInputBox<E> extends JComboBox<String>
45 private static final long serialVersionUID = 5774610435079326695L;
47 private static final int LEFT_BOARDER_WIDTH = 16;
49 private String cacheKey;
51 private AppCache appCache;
53 private JPopupMenu popup = new JPopupMenu();
55 private JMenuItem menuItemClearCache = new JMenuItem();
57 volatile boolean enterWasPressed = false;
60 * @return flag indicating if the most recent keypress was enter
62 public boolean wasEnterPressed()
64 return enterWasPressed;
67 public JvCacheableInputBox(String newCacheKey)
70 this.cacheKey = newCacheKey;
72 addKeyListener(new KeyListener()
76 public void keyTyped(KeyEvent e)
78 enterWasPressed = false;
79 if (e.getKeyCode() == KeyEvent.VK_ENTER)
81 enterWasPressed = true;
83 // let event bubble up
87 public void keyReleased(KeyEvent e)
89 // TODO Auto-generated method stub
94 public void keyPressed(KeyEvent e)
96 // TODO Auto-generated method stub
100 setPrototypeDisplayValue(
101 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
102 appCache = AppCache.getInstance();
103 initCachePopupMenu();
104 initCache(newCacheKey);
109 * Method for initialising cache items for a given cache key and populating the
110 * in-memory cache with persisted cache items
114 private void initCache(String cacheKey)
116 // obtain persisted cache items from properties file as a delimited string
117 String delimitedCacheStr = Cache.getProperty(cacheKey);
118 if (delimitedCacheStr == null || delimitedCacheStr.isEmpty())
122 // convert delimited cache items to a list of strings
123 List<String> persistedCacheItems = Arrays
124 .asList(delimitedCacheStr.split(AppCache.CACHE_DELIMITER));
126 LinkedHashSet<String> foundCacheItems = appCache
127 .getAllCachedItemsFor(cacheKey);
128 if (foundCacheItems == null)
130 foundCacheItems = new LinkedHashSet<>();
132 // populate memory cache
133 for (String cacheItem : persistedCacheItems)
135 foundCacheItems.add(cacheItem);
137 appCache.putCache(cacheKey, foundCacheItems);
141 * Initialise this cache's pop-up menu
143 private void initCachePopupMenu()
145 menuItemClearCache.setFont(new java.awt.Font("Verdana", 0, 12));
147 .setText(MessageManager.getString("action.clear_cached_items"));
148 menuItemClearCache.addActionListener(new ActionListener()
151 public void actionPerformed(ActionEvent e)
153 // System.out.println(">>>>> Clear cache items");
155 appCache.deleteCacheItems(cacheKey);
160 popup.add(menuItemClearCache);
161 setComponentPopupMenu(popup);
166 * Answers true if input text is an integer
171 static boolean isInteger(String text)
175 Integer.parseInt(text);
177 } catch (NumberFormatException e)
184 * Method called to update the cache with the last user input
186 public void updateCache()
188 SwingUtilities.invokeLater(new Runnable()
193 int cacheLimit = Integer.parseInt(appCache.getCacheLimit(cacheKey));
194 String userInput = getUserInput();
195 if (userInput != null && !userInput.isEmpty())
197 LinkedHashSet<String> foundCache = appCache
198 .getAllCachedItemsFor(cacheKey);
199 // remove old cache item so as to place current input at the top of
201 foundCache.remove(userInput);
202 foundCache.add(userInput);
203 appCache.putCache(cacheKey, foundCache);
206 String lastSearch = userInput;
207 if (getItemCount() > 0)
211 Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
212 List<String> reversedCacheItems = new ArrayList<>();
213 reversedCacheItems.addAll(cacheItems);
215 Collections.reverse(reversedCacheItems);
216 if (lastSearch.isEmpty())
221 if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
223 LinkedHashSet<String> foundCache = appCache
224 .getAllCachedItemsFor(cacheKey);
225 boolean prune = reversedCacheItems.size() > cacheLimit;
227 boolean limitExceeded = false;
228 for (String cacheItem : reversedCacheItems)
230 limitExceeded = (count++ > cacheLimit);
235 foundCache.remove(cacheItem);
247 appCache.putCache(cacheKey, foundCache);
249 setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
255 * This method should be called to persist the in-memory cache when this
256 * components parent frame is closed / exited
258 public void persistCache()
260 appCache.persistCache(cacheKey);
264 * Method to obtain input text from the cache box
268 public String getUserInput()
270 return getEditor().getItem() == null ? ""
271 : getEditor().getItem().toString().trim();