From 53e3890428beabca3cdb44b90ad8e1c294d58768 Mon Sep 17 00:00:00 2001 From: tcofoegbu Date: Thu, 20 Apr 2017 17:41:50 +0100 Subject: [PATCH] JAL-2484 added improvement to enable clearing cache items and configuring maximum cache limit --- src/jalview/fts/core/GFTSPanel.java | 3 +- src/jalview/gui/Finder.java | 3 +- src/jalview/io/cache/AppCache.java | 23 +++++ src/jalview/io/cache/JvCacheableInputBox.java | 118 ++++++++++++++++++++++++- 4 files changed, 142 insertions(+), 5 deletions(-) diff --git a/src/jalview/fts/core/GFTSPanel.java b/src/jalview/fts/core/GFTSPanel.java index 99192a6..8b04959 100644 --- a/src/jalview/fts/core/GFTSPanel.java +++ b/src/jalview/fts/core/GFTSPanel.java @@ -28,7 +28,6 @@ import jalview.gui.Desktop; import jalview.gui.IProgressIndicator; import jalview.gui.JvSwingUtils; import jalview.gui.SequenceFetcher; -import jalview.io.cache.AppCache; import jalview.io.cache.JvCacheableInputBox; import jalview.util.MessageManager; @@ -651,7 +650,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI getTempUserPrefs().put("FTSPanel.x", mainFrame.getX()); getTempUserPrefs().put("FTSPanel.y", mainFrame.getY()); mainFrame.dispose(); - AppCache.getInstance().persistCache(getCacheKey()); + txt_search.persistCache(); } public class DeferredTextInputListener implements DocumentListener diff --git a/src/jalview/gui/Finder.java b/src/jalview/gui/Finder.java index 5ca62b3..0f8bb5e 100755 --- a/src/jalview/gui/Finder.java +++ b/src/jalview/gui/Finder.java @@ -24,7 +24,6 @@ import jalview.datamodel.SearchResultMatchI; import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceI; -import jalview.io.cache.AppCache; import jalview.jbgui.GFinder; import jalview.util.MessageManager; import jalview.viewmodel.AlignmentViewport; @@ -387,6 +386,6 @@ public class Finder extends GFinder protected void closeAction() { frame.dispose(); - AppCache.getInstance().persistCache(getCacheKey()); + searchBox.persistCache(); } } diff --git a/src/jalview/io/cache/AppCache.java b/src/jalview/io/cache/AppCache.java index 9f9a25b..8ed33e6 100644 --- a/src/jalview/io/cache/AppCache.java +++ b/src/jalview/io/cache/AppCache.java @@ -20,6 +20,10 @@ public class AppCache private Hashtable> cacheItems; + private static final String DEFAULT_LIMIT_KEY = ".DEFAULT_LIMIT"; + + private static final String DEFAULT_LIMIT = "99"; + private static final String CACHE_DELIMITER = ";"; private AppCache() @@ -115,6 +119,25 @@ public class AppCache persistCache(cacheKey); } + public String getCacheLmit(String cacheKey) + { + String uniqueKey = cacheKey + DEFAULT_LIMIT_KEY; + return Cache.getDefault(uniqueKey, DEFAULT_LIMIT); + } + + public int updateCacheLimit(String cacheKey, String newLimit) + { + String uniqueKey = cacheKey + DEFAULT_LIMIT_KEY; + String formerLimit = getCacheLmit(cacheKey); + if (newLimit != null && !newLimit.isEmpty() + && !formerLimit.equals(newLimit)) + { + Cache.setProperty(uniqueKey, newLimit); + formerLimit = newLimit; + } + return Integer.valueOf(formerLimit); + } + /** * Method for inserting cache items for given cache key into the cache data * structure diff --git a/src/jalview/io/cache/JvCacheableInputBox.java b/src/jalview/io/cache/JvCacheableInputBox.java index 55254c5..3eb193e 100644 --- a/src/jalview/io/cache/JvCacheableInputBox.java +++ b/src/jalview/io/cache/JvCacheableInputBox.java @@ -1,5 +1,11 @@ package jalview.io.cache; +import jalview.util.MessageManager; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedHashSet; @@ -7,7 +13,15 @@ import java.util.List; import java.util.Set; import javax.swing.JComboBox; +import javax.swing.JLabel; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.JTextField; import javax.swing.SwingUtilities; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; public class JvCacheableInputBox extends JComboBox { @@ -18,6 +32,20 @@ public class JvCacheableInputBox extends JComboBox private AppCache appCache; + JPanel pnlDefaultCache = new JPanel(); + + JLabel lblDefaultCacheSize = new JLabel(); + + JTextField txtDefaultCacheSize = new JTextField(); + + JPopupMenu popup = new JPopupMenu(); + + JMenuItem menuItemClearCache = new JMenuItem(); + + final static int INPUT_LIMIT = 2; + + final static String SPACE = " "; + public JvCacheableInputBox(String cacheKey) { super(); @@ -25,12 +53,61 @@ public class JvCacheableInputBox extends JComboBox setEditable(true); setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"); appCache = AppCache.getInstance(); + initCachePopupMenu(); appCache.initCache(cacheKey); updateCache(); } /** + * Initialise this cache's pop-up menu + */ + private void initCachePopupMenu() + { + add(popup); + setComponentPopupMenu(popup); + pnlDefaultCache.setBackground(Color.WHITE); + txtDefaultCacheSize.setPreferredSize(new Dimension(45, 20)); + lblDefaultCacheSize.setText(SPACE + + MessageManager.getString("label.default_cache_size")); + // Force input to accept only Integer entries up to length - INPUT_LIMIT + txtDefaultCacheSize.setDocument(new PlainDocument() + { + private static final long serialVersionUID = 1L; + + @Override + public void insertString(int offs, String str, AttributeSet a) + throws BadLocationException + { + if (getLength() + str.length() <= INPUT_LIMIT && isInteger(str)) + { + super.insertString(offs, str, a); + } + } + }); + txtDefaultCacheSize.setText(appCache.getCacheLmit(cacheKey)); + pnlDefaultCache.add(lblDefaultCacheSize); + pnlDefaultCache.add(txtDefaultCacheSize); + popup.insert(pnlDefaultCache, 0); + + menuItemClearCache.setText(MessageManager + .getString("action.clear_cached_items")); + menuItemClearCache.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + System.out.println(">>>>> Clear cache items"); + setSelectedItem(""); + appCache.deleteCacheItems(cacheKey); + updateCache(); + } + }); + + popup.add(menuItemClearCache); + } + + /** * Answers true if input text is an integer * * @param text @@ -58,6 +135,8 @@ public class JvCacheableInputBox extends JComboBox @Override public void run() { + int cacheLimit = appCache.updateCacheLimit(cacheKey, + txtDefaultCacheSize.getText()); String userInput = getUserInput(); if (userInput != null && !userInput.isEmpty()) { @@ -84,12 +163,34 @@ public class JvCacheableInputBox extends JComboBox { addItem(""); } + if (reversedCacheItems != null && !reversedCacheItems.isEmpty()) { + LinkedHashSet foundCache = appCache + .getAllCachedItemsFor(cacheKey); + boolean prune = reversedCacheItems.size() > cacheLimit; + int count = 1; + boolean limitExceeded = false; for (String cacheItem : reversedCacheItems) { - addItem(cacheItem); + limitExceeded = (count++ > cacheLimit); + if (prune) + { + if (limitExceeded) + { + foundCache.remove(cacheItem); + } + else + { + addItem(cacheItem); + } + } + else + { + addItem(cacheItem); + } } + appCache.putCache(cacheKey, foundCache); } setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch); } @@ -97,6 +198,21 @@ public class JvCacheableInputBox extends JComboBox } + /** + * This method should be called to persist the in-memory cache when this + * components parent frame is closed / exited + */ + public void persistCache() + { + appCache.persistCache(cacheKey); + appCache.updateCacheLimit(cacheKey, txtDefaultCacheSize.getText()); + } + + /** + * Method to obtain input text from the cache box + * + * @return + */ public String getUserInput() { return getEditor().getItem() == null ? "" : getEditor().getItem() -- 1.7.10.2