label.invalid_name = Invalid Name !
label.output_seq_details = Output Sequence Details to list all database references
label.urllinks = Links
+label.default_cache_size = Default Cache Size
+action.clear_cached_items = Clear Cached Items
label.togglehidden = Show hidden regions
label.quality_descr = Alignment Quality based on Blosum62 scores
label.conservation_descr = Conservation of total alignment less than {0}% gaps
* @return
*/
public Map<String, Integer> getTempUserPrefs();
+
+ /**
+ * Returns unique key used for storing an FTSs instance cache items in the
+ * cache data structure
+ *
+ * @return
+ */
+ public String getCacheKey();
}
import jalview.gui.IProgressIndicator;
import jalview.gui.JvSwingUtils;
import jalview.gui.SequenceFetcher;
+import jalview.io.cache.JvCacheableInputBox;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
-import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.InternalFrameEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
+import javax.swing.text.JTextComponent;
/**
* This class provides the swing GUI layout for FTS Panel and implements most of
protected JButton btn_cancel = new JButton();
- protected JTextField txt_search = new JTextField(30);
+ protected JvCacheableInputBox<String> txt_search;
protected SequenceFetcher seqFetcher;
*/
private void jbInit() throws Exception
{
+
+ txt_search = new JvCacheableInputBox<String>(getCacheKey());
+ populateCmbSearchTargetOptions();
Integer width = getTempUserPrefs().get("FTSPanel.width") == null ? 800
: getTempUserPrefs().get("FTSPanel.width");
Integer height = getTempUserPrefs().get("FTSPanel.height") == null ? 400
scrl_searchResult.setPreferredSize(new Dimension(width, height));
cmb_searchTarget.setFont(new java.awt.Font("Verdana", 0, 12));
- cmb_searchTarget.addActionListener(new ActionListener()
+ cmb_searchTarget.addItemListener(new ItemListener()
{
@Override
- public void actionPerformed(ActionEvent e)
+ public void itemStateChanged(ItemEvent e)
{
- String tooltipText;
- if ("all".equalsIgnoreCase(getCmbSearchTarget().getSelectedItem()
- .toString()))
- {
- tooltipText = MessageManager.getString("label.search_all");
- }
- else if ("pdb id".equalsIgnoreCase(getCmbSearchTarget()
- .getSelectedItem().toString()))
+ if (e.getStateChange() == ItemEvent.SELECTED)
{
- tooltipText = MessageManager
- .getString("label.separate_multiple_accession_ids");
- }
- else
- {
- tooltipText = MessageManager.formatMessage(
- "label.separate_multiple_query_values",
- new Object[] { getCmbSearchTarget().getSelectedItem()
- .toString() });
+ String tooltipText;
+ if ("all".equalsIgnoreCase(getCmbSearchTarget().getSelectedItem()
+ .toString()))
+ {
+ tooltipText = MessageManager.getString("label.search_all");
+ }
+ else if ("pdb id".equalsIgnoreCase(getCmbSearchTarget()
+ .getSelectedItem().toString()))
+ {
+ tooltipText = MessageManager
+ .getString("label.separate_multiple_accession_ids");
+ }
+ else
+ {
+ tooltipText = MessageManager.formatMessage(
+ "label.separate_multiple_query_values",
+ new Object[] { getCmbSearchTarget().getSelectedItem()
+ .toString() });
+ }
+ txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ tooltipText));
+ searchAction(true);
}
- txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
- tooltipText));
- searchAction(true);
}
});
-
- populateCmbSearchTargetOptions();
+
txt_search.setFont(new java.awt.Font("Verdana", 0, 12));
- txt_search.addKeyListener(new KeyAdapter()
+ txt_search.getEditor().getEditorComponent()
+ .addKeyListener(new KeyAdapter()
{
@Override
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_ENTER)
{
- if (txt_search.getText() == null
- || txt_search.getText().isEmpty())
+ if (getTypedText() == null || getTypedText().isEmpty())
{
return;
}
if (primaryKeyName.equalsIgnoreCase(getCmbSearchTarget()
.getSelectedItem().toString()))
{
- transferToSequenceFetcher(txt_search.getText());
+ transferToSequenceFetcher(getTypedText());
}
}
}
});
-
final DeferredTextInputListener listener = new DeferredTextInputListener(
1500, new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
- if (!getTypedText().equalsIgnoreCase(lastSearchTerm))
+ String typed = getTypedText();
+ if (!typed.equalsIgnoreCase(lastSearchTerm))
{
searchAction(true);
paginatorCart.clear();
- lastSearchTerm = getTypedText();
+ lastSearchTerm = typed;
}
}
}, false);
- txt_search.getDocument().addDocumentListener(listener);
+ ((JTextComponent) txt_search.getEditor().getEditorComponent())
+ .getDocument().addDocumentListener(listener);
+
txt_search.addFocusListener(new FocusListener()
{
@Override
protected void closeAction()
{
- // System.out.println(">>>>>>>>>> closing internal frame!!!");
- // System.out.println("width : " + this.getWidth());
- // System.out.println("heigh : " + this.getHeight());
- // System.out.println("x : " + mainFrame.getX());
- // System.out.println("y : " + mainFrame.getY());
getTempUserPrefs().put("FTSPanel.width", this.getWidth());
getTempUserPrefs().put("FTSPanel.height", pnl_results.getHeight());
getTempUserPrefs().put("FTSPanel.x", mainFrame.getX());
getTempUserPrefs().put("FTSPanel.y", mainFrame.getY());
mainFrame.dispose();
+ txt_search.persistCache();
}
public class DeferredTextInputListener implements DocumentListener
{
if (previousWantedFields == null)
{
- return true;
+ return false;
}
return Arrays.equals(getFTSRestClient()
return cmb_searchTarget;
}
- public JTextField getTxtSearch()
+ public JComboBox<String> getTxtSearch()
{
return txt_search;
}
public void transferToSequenceFetcher(String ids)
{
- // mainFrame.dispose();
seqFetcher.getTextArea().setText(ids);
Thread worker = new Thread(seqFetcher);
worker.start();
@Override
public String getTypedText()
{
- return txt_search.getText().trim();
+ return txt_search.getUserInput();
}
@Override
{
lbl_blank.setVisible(!isSearchInProgress);
lbl_loading.setVisible(isSearchInProgress);
+ txt_search.setEditable(!isSearchInProgress);
}
@Override
.toString();
paginatorCart.add(idStr);
}
- // System.out.println("Paginator shopping cart size : "
- // + paginatorCart.size());
}
public void updateSummaryTableSelections()
{
e.printStackTrace();
}
- // System.out.println(">>>>>> got here : 1");
int totalRows = resultTable.getRowCount();
- // resultTable.clearSelection();
for (int row = 0; row < totalRows; row++)
{
String id = (String) resultTable.getValueAt(row, primaryKeyColIndex);
public void refreshPaginatorState()
{
- // System.out.println("resultSet count : " + resultSetCount);
- // System.out.println("offSet : " + offSet);
- // System.out.println("page limit : " + pageLimit);
setPrevPageButtonEnabled(false);
setNextPageButtonEnabled(false);
if (resultSetCount == 0 && pageLimit == 0)
mainFrame.setTitle(getFTSFrameTitle());
}
+
}
private static String defaultFTSFrameTitle = MessageManager
.getString("label.pdb_sequence_fetcher");
- private String ftsFrameTitle = defaultFTSFrameTitle;
private static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+ private static final String PDB_FTS_CACHE_KEY = "CACHE.PDB_FTS";
+
public PDBFTSPanel(SequenceFetcher seqFetcher)
{
super();
@Override
public void searchAction(boolean isFreshSearch)
{
+ mainFrame.requestFocusInWindow();
if (isFreshSearch)
{
offSet = 0;
@Override
public void run()
{
- ftsFrameTitle = defaultFTSFrameTitle;
reset();
boolean allowEmptySequence = false;
if (getTypedText().length() > 0)
.getSelectedItem()).getCode();
wantedFields = PDBFTSRestClient.getInstance()
.getAllDefaultDisplayedFTSDataColumns();
- String searchTerm = decodeSearchTerm(txt_search.getText(),
+ String searchTerm = decodeSearchTerm(getTypedText(),
searchTarget);
FTSRestRequest request = new FTSRestRequest();
refreshPaginatorState();
updateSummaryTableSelections();
}
+ txt_search.updateCache();
}
}.start();
}
e.printStackTrace();
}
int[] selectedRows = getResultTable().getSelectedRows();
- String searchTerm = txt_search.getText();
+ String searchTerm = getTypedText();
for (int summaryRow : selectedRows)
{
String idStr = getResultTable().getValueAt(summaryRow,
@Override
public String getFTSFrameTitle()
{
- return ftsFrameTitle;
+ return defaultFTSFrameTitle;
}
@Override
return tempUserPrefs;
}
+
+ @Override
+ public String getCacheKey()
+ {
+ return PDB_FTS_CACHE_KEY;
+ }
+
+
}
private static String defaultFTSFrameTitle = MessageManager
.getString("label.uniprot_sequence_fetcher");
- private String ftsFrameTitle = defaultFTSFrameTitle;
private static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+ private static final String UNIPROT_FTS_CACHE_KEY = "CACHE.UNIPROT_FTS";
+
public UniprotFTSPanel(SequenceFetcher seqFetcher)
{
super();
@Override
public void searchAction(boolean isFreshSearch)
{
+ mainFrame.requestFocusInWindow();
if (isFreshSearch)
{
offSet = 0;
@Override
public void run()
{
- ftsFrameTitle = defaultFTSFrameTitle;
reset();
- if (getTypedText().length() > 0)
+ String searchInput = getTypedText();
+ if (searchInput.length() > 0)
{
setSearchInProgress(true);
long startTime = System.currentTimeMillis();
-
+ searchInput = getTypedText();
String searchTarget = ((FTSDataColumnI) cmb_searchTarget
.getSelectedItem()).getAltCode();
-
wantedFields = UniProtFTSRestClient.getInstance()
.getAllDefaultDisplayedFTSDataColumns();
- String searchTerm = decodeSearchTerm(txt_search.getText(),
- searchTarget);
+ String searchTerm = decodeSearchTerm(searchInput, searchTarget);
FTSRestRequest request = new FTSRestRequest();
request.setFieldToSearchBy(searchTarget);
refreshPaginatorState();
updateSummaryTableSelections();
}
+ txt_search.updateCache();
}
}.start();
@Override
public String getFTSFrameTitle()
{
- return ftsFrameTitle;
+ return defaultFTSFrameTitle;
}
@Override
return tempUserPrefs;
}
+ @Override
+ public String getCacheKey()
+ {
+ return UNIPROT_FTS_CACHE_KEY;
+ }
}
package jalview.gui;
import jalview.datamodel.HiddenColumns;
+import jalview.io.cache.JvCacheableInputBox;
import jalview.schemes.AnnotationColourGradient;
import jalview.util.MessageManager;
import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
import java.util.Iterator;
import javax.swing.ButtonGroup;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
-import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
import net.miginfocom.swing.MigLayout;
if (currentSearchPanel != null)
{
-
- if (!currentSearchPanel.searchBox.getText().isEmpty())
+ if (!currentSearchPanel.searchBox.getUserInput().isEmpty())
{
- currentSearchPanel.description.setEnabled(true);
- currentSearchPanel.displayName.setEnabled(true);
- filterParams.setRegexString(currentSearchPanel.searchBox.getText());
+ filterParams.setRegexString(currentSearchPanel.searchBox
+ .getUserInput());
if (currentSearchPanel.displayName.isSelected())
{
filterParams
.addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION);
}
}
- else
- {
- currentSearchPanel.description.setEnabled(false);
- currentSearchPanel.displayName.setEnabled(false);
- }
}
av.getColumnSelection().filterAnnotations(
{
currentView = AnnotationColumnChooser.GRAPH_VIEW;
}
-
+ saveCache();
gSearchPanel.syncState();
gFurtherActionPanel.syncState();
gStructureFilterPanel.syncState();
private JCheckBox description = new JCheckBox();
- private JTextField searchBox = new JTextField(10);
+ private static final String FILTER_BY_ANN_CACHE_KEY = "CACHE.SELECT_FILTER_BY_ANNOT";
+
+ public JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<String>(
+ FILTER_BY_ANN_CACHE_KEY);
public SearchPanel(AnnotationColumnChooser aColChooser)
{
this.setBorder(new TitledBorder(MessageManager
.getString("label.search_filter")));
- JvSwingUtils.jvInitComponent(searchBox);
+ searchBox.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXX");
searchBox.setToolTipText(MessageManager
.getString("info.enter_search_text_here"));
- searchBox.getDocument().addDocumentListener(new DocumentListener()
- {
- @Override
- public void insertUpdate(DocumentEvent e)
- {
- searchStringAction();
- }
+ searchBox.getEditor().getEditorComponent()
+ .addKeyListener(new java.awt.event.KeyAdapter()
+ {
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER)
+ {
+ e.consume();
+ searchStringAction();
+ }
+ }
+ });
- @Override
- public void removeUpdate(DocumentEvent e)
- {
- searchStringAction();
- }
- @Override
- public void changedUpdate(DocumentEvent e)
- {
- searchStringAction();
- }
- });
JvSwingUtils.jvInitComponent(displayName, "label.label");
- displayName.setEnabled(false);
displayName.addActionListener(new ActionListener()
{
@Override
});
JvSwingUtils.jvInitComponent(description, "label.description");
- description.setEnabled(false);
description.addActionListener(new ActionListener()
{
@Override
aColChooser.setCurrentSearchPanel(this);
aColChooser.updateView();
updateSearchPanelToolTips();
+ searchBox.updateCache();
}
public void syncState()
displayName.setEnabled(sp.displayName.isEnabled());
displayName.setSelected(sp.displayName.isSelected());
- searchBox.setText(sp.searchBox.getText());
+ searchBox.setSelectedItem(sp.searchBox.getUserInput());
}
updateSearchPanelToolTips();
}
}
}
+ @Override
+ public void ok_actionPerformed()
+ {
+ saveCache();
+ super.ok_actionPerformed();
+ }
+
+ @Override
+ public void cancel_actionPerformed()
+ {
+ saveCache();
+ super.cancel_actionPerformed();
+ }
+
+ private void saveCache()
+ {
+ gSearchPanel.searchBox.persistCache();
+ ngSearchPanel.searchBox.persistCache();
+ gSearchPanel.searchBox.updateCache();
+ ngSearchPanel.searchBox.updateCache();
+ }
}
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.KeyStroke;
+import javax.swing.event.InternalFrameEvent;
/**
* Performs the menu option for searching the alignment, for the next or all
frame = new JInternalFrame();
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosing(InternalFrameEvent e)
+ {
+ closeAction();
+ }
+ });
addEscapeHandler();
Desktop.addInternalFrame(frame, MessageManager.getString("label.find"),
MY_WIDTH, MY_HEIGHT);
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
- textfield.requestFocus();
+ searchBox.requestFocus();
}
/**
@Override
public void actionPerformed(ActionEvent e)
{
- escapeActionPerformed();
+ closeAction();
}
});
}
- /**
- * Close the panel on Escape key press
- */
- protected void escapeActionPerformed()
- {
- setVisible(false);
- frame.dispose();
- }
/**
* Performs the 'Find Next' action.
List<SequenceI> seqs = new ArrayList<SequenceI>();
List<SequenceFeature> features = new ArrayList<SequenceFeature>();
- String searchString = textfield.getText().trim();
+ String searchString = searchBox.getEditor().getItem().toString().trim();
String desc = "Search Results";
/*
{
createFeatures.setEnabled(false);
- String searchString = textfield.getText().trim();
+ String searchString = searchBox.getUserInput().trim();
if (isInvalidSearchString(searchString))
{
seqIndex = 0;
}
}
-
+ searchBox.updateCache();
}
/**
}
return error;
}
+
+ protected void closeAction()
+ {
+ frame.setVisible(false);
+ frame.dispose();
+ searchBox.persistCache();
+ if (getFocusedViewport())
+ {
+ ap.alignFrame.requestFocus();
+ }
+ }
}
--- /dev/null
+package jalview.io.cache;
+
+
+import jalview.bin.Cache;
+
+import java.util.Hashtable;
+import java.util.LinkedHashSet;
+
+/**
+ * A singleton class used for querying and persisting cache items.
+ *
+ * @author tcnofoegbu
+ *
+ */
+public class AppCache
+{
+ public static final String DEFAULT_LIMIT = "99";
+
+ public static final String CACHE_DELIMITER = ";";
+
+ private static AppCache instance = null;
+
+ private static final String DEFAULT_LIMIT_KEY = ".DEFAULT_LIMIT";
+
+
+
+ private Hashtable<String, LinkedHashSet<String>> cacheItems;
+
+ private AppCache()
+ {
+ cacheItems = new Hashtable<String, LinkedHashSet<String>>();
+ }
+
+ /**
+ * Method to obtain all the cache items for a given cache key
+ *
+ * @param cacheKey
+ * @return
+ */
+ public LinkedHashSet<String> getAllCachedItemsFor(String cacheKey)
+ {
+ LinkedHashSet<String> foundCache = cacheItems.get(cacheKey);
+ if (foundCache == null)
+ {
+ foundCache = new LinkedHashSet<String>();
+ cacheItems.put(cacheKey, foundCache);
+ }
+ return foundCache;
+ }
+
+
+ /**
+ * Returns a singleton instance of AppCache
+ *
+ * @return
+ */
+ public static AppCache getInstance()
+ {
+ if (instance == null)
+ {
+ instance = new AppCache();
+ }
+ return instance;
+ }
+
+
+
+ /**
+ * Method for persisting cache items for a given cache key
+ *
+ * @param cacheKey
+ */
+ public void persistCache(String cacheKey)
+ {
+ LinkedHashSet<String> foundCacheItems = getAllCachedItemsFor(cacheKey);
+ StringBuffer delimitedCacheBuf = new StringBuffer();
+ for (String cacheItem : foundCacheItems)
+ {
+ delimitedCacheBuf.append(CACHE_DELIMITER).append(cacheItem);
+ }
+ if (delimitedCacheBuf.length() > 0)
+ {
+ delimitedCacheBuf.deleteCharAt(0);
+ }
+ String delimitedCacheString = delimitedCacheBuf.toString();
+
+ Cache.setProperty(cacheKey, delimitedCacheString);
+ }
+
+ /**
+ * Method for deleting cached items for a given cache key
+ *
+ * @param cacheKey
+ * the cache key
+ */
+ public void deleteCacheItems(String cacheKey)
+ {
+ cacheItems.put(cacheKey, new LinkedHashSet<String>());
+ persistCache(cacheKey);
+ }
+
+ /**
+ * Method for obtaining the preset maximum cache limit for a given cache key
+ *
+ * @param cacheKey
+ * the cache key
+ * @return the max number of items that could be cached
+ */
+ public String getCacheLimit(String cacheKey)
+ {
+ String uniqueKey = cacheKey + DEFAULT_LIMIT_KEY;
+ return Cache.getDefault(uniqueKey, DEFAULT_LIMIT);
+ }
+
+ /**
+ * Method for updating the preset maximum cache limit for a given cache key
+ *
+ * @param cacheKey
+ * the cache key
+ * @param newLimit
+ * the max number of items that could be cached for the given cache
+ * key
+ * @return
+ */
+ public int updateCacheLimit(String cacheKey, int newUserLimit)
+ {
+ String newLimit = String.valueOf(newUserLimit);
+ String uniqueKey = cacheKey + DEFAULT_LIMIT_KEY;
+ String formerLimit = getCacheLimit(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
+ *
+ * @param cacheKey
+ * the cache key
+ * @param cacheItems
+ * the items to add to the cache
+ */
+ public void putCache(String cacheKey, LinkedHashSet<String> newCacheItems)
+ {
+ cacheItems.put(cacheKey, newCacheItems);
+ }
+
+}
--- /dev/null
+package jalview.io.cache;
+
+import jalview.bin.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.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.BorderFactory;
+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<E> extends JComboBox<String>
+{
+
+ private static final long serialVersionUID = 5774610435079326695L;
+
+ private static final int INPUT_LIMIT = 2;
+
+ private static final int LEFT_BOARDER_WIDTH = 16;
+
+ private String cacheKey;
+
+ private AppCache appCache;
+
+ private JPanel pnlDefaultCache = new JPanel();
+
+ private JLabel lblDefaultCacheSize = new JLabel();
+
+ private JTextField txtDefaultCacheSize = new JTextField();
+
+ private JPopupMenu popup = new JPopupMenu();
+
+ private JMenuItem menuItemClearCache = new JMenuItem();
+
+ public JvCacheableInputBox(String newCacheKey)
+ {
+ super();
+ this.cacheKey = newCacheKey;
+ setEditable(true);
+ setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ appCache = AppCache.getInstance();
+ initCachePopupMenu();
+ initCache(newCacheKey);
+ updateCache();
+ }
+
+ /**
+ * Method for initialising cache items for a given cache key and populating
+ * the in-memory cache with persisted cache items
+ *
+ * @param cacheKey
+ */
+ private void initCache(String cacheKey)
+ {
+ // obtain persisted cache items from properties file as a delimited string
+ String delimitedCacheStr = Cache.getProperty(cacheKey);
+ if (delimitedCacheStr == null || delimitedCacheStr.isEmpty())
+ {
+ return;
+ }
+ // convert delimited cache items to a list of strings
+ List<String> persistedCacheItems = Arrays.asList(delimitedCacheStr
+ .split(AppCache.CACHE_DELIMITER));
+
+ LinkedHashSet<String> foundCacheItems = appCache
+ .getAllCachedItemsFor(cacheKey);
+ if (foundCacheItems == null)
+ {
+ foundCacheItems = new LinkedHashSet<String>();
+ }
+ // populate memory cache
+ for (String cacheItem : persistedCacheItems)
+ {
+ foundCacheItems.add(cacheItem);
+ }
+ appCache.putCache(cacheKey, foundCacheItems);
+ }
+
+ /**
+ * Initialise this cache's pop-up menu
+ */
+ private void initCachePopupMenu()
+ {
+ pnlDefaultCache.setBackground(Color.WHITE);
+ // pad panel so as to align with other menu items
+ pnlDefaultCache.setBorder(BorderFactory.createEmptyBorder(0,
+ LEFT_BOARDER_WIDTH, 0, 0));
+ txtDefaultCacheSize.setPreferredSize(new Dimension(45, 20));
+ txtDefaultCacheSize.setFont(new java.awt.Font("Verdana", 0, 12));
+ lblDefaultCacheSize.setText(MessageManager
+ .getString("label.default_cache_size"));
+ lblDefaultCacheSize.setFont(new java.awt.Font("Verdana", 0, 12));
+ // 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.addKeyListener(new java.awt.event.KeyAdapter()
+ {
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ if (e.getKeyCode() == KeyEvent.VK_ENTER)
+ {
+ e.consume();
+ updateCache();
+ closePopup();
+ }
+ }
+ });
+
+ txtDefaultCacheSize.setText(appCache.getCacheLimit(cacheKey));
+ pnlDefaultCache.add(lblDefaultCacheSize);
+ menuItemClearCache.setFont(new java.awt.Font("Verdana", 0, 12));
+ pnlDefaultCache.add(txtDefaultCacheSize);
+ 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.insert(pnlDefaultCache, 0);
+ popup.add(menuItemClearCache);
+ setComponentPopupMenu(popup);
+ add(popup);
+ }
+
+ private void closePopup()
+ {
+ popup.setVisible(false);
+ popup.transferFocus();
+ }
+
+ /**
+ * Answers true if input text is an integer
+ *
+ * @param text
+ * @return
+ */
+ static boolean isInteger(String text)
+ {
+ try
+ {
+ Integer.parseInt(text);
+ return true;
+ } catch (NumberFormatException e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Method called to update the cache with the last user input
+ */
+ public void updateCache()
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ int userLimit = txtDefaultCacheSize.getText().trim().isEmpty() ? Integer
+ .valueOf(AppCache.DEFAULT_LIMIT) : Integer
+ .valueOf(txtDefaultCacheSize.getText());
+ int cacheLimit = appCache.updateCacheLimit(cacheKey, userLimit);
+ String userInput = getUserInput();
+ if (userInput != null && !userInput.isEmpty())
+ {
+ LinkedHashSet<String> foundCache = appCache
+ .getAllCachedItemsFor(cacheKey);
+ // remove old cache item so as to place current input at the top of
+ // the result
+ foundCache.remove(userInput);
+ foundCache.add(userInput);
+ appCache.putCache(cacheKey, foundCache);
+ }
+
+ String lastSearch = userInput;
+ if (getItemCount() > 0)
+ {
+ removeAllItems();
+ }
+ Set<String> cacheItems = appCache.getAllCachedItemsFor(cacheKey);
+ List<String> reversedCacheItems = new ArrayList<String>();
+ reversedCacheItems.addAll(cacheItems);
+ cacheItems = null;
+ Collections.reverse(reversedCacheItems);
+ if (lastSearch.isEmpty())
+ {
+ addItem("");
+ }
+
+ if (reversedCacheItems != null && !reversedCacheItems.isEmpty())
+ {
+ LinkedHashSet<String> foundCache = appCache
+ .getAllCachedItemsFor(cacheKey);
+ boolean prune = reversedCacheItems.size() > cacheLimit;
+ int count = 1;
+ boolean limitExceeded = false;
+ for (String cacheItem : reversedCacheItems)
+ {
+ limitExceeded = (count++ > cacheLimit);
+ if (prune)
+ {
+ if (limitExceeded)
+ {
+ foundCache.remove(cacheItem);
+ }
+ else
+ {
+ addItem(cacheItem);
+ }
+ }
+ else
+ {
+ addItem(cacheItem);
+ }
+ }
+ appCache.putCache(cacheKey, foundCache);
+ }
+ setSelectedItem(lastSearch.isEmpty() ? "" : lastSearch);
+ }
+ });
+ }
+
+
+ /**
+ * 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);
+ int userLimit = txtDefaultCacheSize.getText().trim().isEmpty() ? Integer
+ .valueOf(AppCache.DEFAULT_LIMIT) : Integer
+ .valueOf(txtDefaultCacheSize.getText());
+ appCache.updateCacheLimit(cacheKey, userLimit);
+ }
+
+ /**
+ * Method to obtain input text from the cache box
+ *
+ * @return
+ */
+ public String getUserInput()
+ {
+ return getEditor().getItem() == null ? "" : getEditor().getItem()
+ .toString().trim();
+ }
+
+}
import jalview.io.DataSourceType;
import jalview.io.FileFormat;
import jalview.io.FormatAdapter;
+import jalview.io.cache.JvCacheableInputBox;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
+import javax.swing.text.JTextComponent;
public class GFinder extends JPanel
{
protected JButton createFeatures = new JButton();
- JScrollPane jScrollPane1 = new JScrollPane();
-
- protected JTextArea textfield = new JTextArea();
+ protected JvCacheableInputBox<String> searchBox = new JvCacheableInputBox<String>(getCacheKey());
BorderLayout mainBorderLayout = new BorderLayout();
GridLayout optionsGridLayout = new GridLayout();
+ private static final String FINDER_CACHE_KEY = "CACHE.FINDER";
+
public GFinder()
{
try
createFeatures_actionPerformed();
}
});
- textfield.setFont(new java.awt.Font("Verdana", Font.PLAIN, 12));
- textfield.setText("");
- textfield.setLineWrap(true);
- textfield.addCaretListener(new CaretListener()
+ searchBox.setFont(new java.awt.Font("Verdana", Font.PLAIN, 12));
+ ((JTextComponent) searchBox.getEditor().getEditorComponent())
+ .addCaretListener(new CaretListener()
{
@Override
public void caretUpdate(CaretEvent e)
textfield_caretUpdate(e);
}
});
- textfield.addKeyListener(new java.awt.event.KeyAdapter()
- {
- @Override
- public void keyPressed(KeyEvent e)
- {
- textfield_keyPressed(e);
- }
- });
-
+ searchBox.getEditor().getEditorComponent()
+ .addKeyListener(new java.awt.event.KeyAdapter()
+ {
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ textfield_keyPressed(e);
+ }
+ });
mainBorderLayout.setHgap(5);
mainBorderLayout.setVgap(5);
jPanel4.setLayout(borderLayout2);
this.add(jPanel2, java.awt.BorderLayout.SOUTH);
this.add(jPanel3, java.awt.BorderLayout.NORTH);
this.add(jPanel4, java.awt.BorderLayout.CENTER);
- jPanel4.add(jScrollPane1, java.awt.BorderLayout.NORTH);
- jScrollPane1.getViewport().add(textfield);
+ jPanel4.add(searchBox, java.awt.BorderLayout.NORTH);
JPanel optionsPanel = new JPanel();
jPanel4.add(optionsPanel, java.awt.BorderLayout.WEST);
}
- protected void findNext_actionPerformed(ActionEvent e)
+ protected void textfield_keyPressed(KeyEvent e)
{
+ if (e.getKeyCode() == KeyEvent.VK_ENTER)
+ {
+ if (!searchBox.isPopupVisible())
+ {
+ e.consume();
+ findNext_actionPerformed(null);
+ }
+ }
}
- protected void findAll_actionPerformed(ActionEvent e)
+ protected void findNext_actionPerformed(ActionEvent e)
{
}
- protected void textfield_keyPressed(KeyEvent e)
+ protected void findAll_actionPerformed(ActionEvent e)
{
- if (e.getKeyCode() == KeyEvent.VK_ENTER)
- {
- e.consume();
- findNext_actionPerformed(null);
- }
}
+
public void createFeatures_actionPerformed()
{
}
public void textfield_caretUpdate(CaretEvent e)
{
- if (textfield.getText().indexOf(">") > -1)
+ if (searchBox.getUserInput().indexOf(">") > -1)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
- String str = textfield.getText();
+ String str = searchBox.getUserInput();
AlignmentI al = null;
try
{
jalview.util.Comparison.GapChars, al.getSequenceAt(0)
.getSequenceAsString());
- textfield.setText(str);
}
}
});
}
}
+
+
+
+
+
+ /**
+ * Returns unique key used for storing Finder cache items in the cache data
+ * structure
+ *
+ * @return
+ */
+ public String getCacheKey()
+ {
+ return FINDER_CACHE_KEY;
+ }
+
+
+
}
import jalview.gui.JvOptionPane;
+import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
-import javax.swing.JTextField;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
assertEquals(expectedString, outcome);
}
- @Test(groups = { "External" }, timeOut = 7000)
+ @Test(groups = { "External" }, timeOut = 8000)
public void txt_search_ActionPerformedTest()
{
PDBFTSPanel searchPanel = new PDBFTSPanel(null);
JInternalFrame mainFrame = searchPanel.getMainFrame();
- JTextField txt_search = searchPanel.getTxtSearch();
+ JComboBox<String> txt_search = searchPanel.getTxtSearch();
assertTrue(mainFrame.getTitle().length() == 20);
assertTrue(mainFrame.getTitle()
.equalsIgnoreCase("PDB Sequence Fetcher"));
- txt_search.setText("ABC");
+ txt_search.setSelectedItem("ABC");
try
{
// wait for web-service to handle response
--- /dev/null
+package jalview.io.cache;
+
+import java.util.LinkedHashSet;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class AppCacheTest
+{
+ private AppCache appCache;
+
+ private static final String TEST_CACHE_KEY = "CACHE.UNIT_TEST";
+
+ private static final String TEST_FAKE_CACHE_KEY = "CACHE.UNIT_TEST_FAKE";
+
+ @BeforeClass(alwaysRun = true)
+ public void setUpCache()
+ {
+ appCache = AppCache.getInstance();
+ }
+
+ public void generateTestCacheItems()
+ {
+ LinkedHashSet<String> testCacheItems = new LinkedHashSet<String>();
+ for (int x = 0; x < 10; x++)
+ {
+ testCacheItems.add("TestCache" + x);
+ }
+ appCache.putCache(TEST_CACHE_KEY, testCacheItems);
+ appCache.persistCache(TEST_CACHE_KEY);
+ }
+
+ @Test(groups = { "Functional" })
+ public void appCacheTest()
+ {
+ LinkedHashSet<String> cacheItems = appCache
+ .getAllCachedItemsFor(TEST_FAKE_CACHE_KEY);
+ Assert.assertEquals(cacheItems.size(), 0);
+ generateTestCacheItems();
+ cacheItems = appCache.getAllCachedItemsFor(TEST_CACHE_KEY);
+ Assert.assertEquals(cacheItems.size(), 10);
+ appCache.deleteCacheItems(TEST_CACHE_KEY);
+ cacheItems = appCache.getAllCachedItemsFor(TEST_CACHE_KEY);
+ Assert.assertEquals(cacheItems.size(), 0);
+ }
+
+ @Test(groups = { "Functional" })
+ public void appCacheLimitTest()
+ {
+ String limit = appCache.getCacheLimit(TEST_CACHE_KEY);
+ Assert.assertEquals(limit, "99");
+ limit = String.valueOf(appCache.updateCacheLimit(TEST_CACHE_KEY, 20));
+ Assert.assertEquals(limit, "20");
+ limit = appCache.getCacheLimit(TEST_CACHE_KEY);
+ Assert.assertEquals(limit, "20");
+ appCache.updateCacheLimit(TEST_CACHE_KEY, 99);
+ }
+
+
+}
--- /dev/null
+package jalview.io.cache;
+
+import java.util.LinkedHashSet;
+
+import org.junit.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class JvCacheableInputBoxTest
+{
+
+ private AppCache appCache;
+
+ private static final String TEST_CACHE_KEY = "CACHE.UNIT_TEST";
+
+ private JvCacheableInputBox<String> cacheBox = new JvCacheableInputBox<String>(
+ TEST_CACHE_KEY);
+
+ @BeforeClass(alwaysRun = true)
+ private void setUpCache()
+ {
+ appCache = AppCache.getInstance();
+ }
+
+ @Test(groups = { "Functional" })
+ public void getUserInputTest()
+ {
+ String userInput = cacheBox.getUserInput();
+ Assert.assertEquals("", userInput);
+
+ String testInput = "TestInput";
+ cacheBox.addItem(testInput);
+ cacheBox.setSelectedItem(testInput);
+
+ try
+ {
+ // This 1ms delay is essential to prevent the
+ // assertion below from executing before
+ // swing thread finishes updating the combo-box
+ Thread.sleep(100);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ userInput = cacheBox.getUserInput();
+ Assert.assertEquals(testInput, userInput);
+ }
+
+ @Test(groups = { "Functional" })
+ public void updateCacheTest()
+ {
+ String testInput = "TestInput";
+ cacheBox.addItem(testInput);
+ cacheBox.setSelectedItem(testInput);
+ cacheBox.updateCache();
+ try
+ {
+ // This 1ms delay is essential to prevent the
+ // assertion below from executing before
+ // cacheBox.updateCache() finishes updating the cache
+ Thread.sleep(100);
+ } catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ LinkedHashSet<String> foundCache = appCache
+ .getAllCachedItemsFor(TEST_CACHE_KEY);
+ Assert.assertTrue(foundCache.contains(testInput));
+ }
+}