JAL-4336 set preferred dimensions for JTextBox workaround in JalviewJS
[jalview.git] / src / jalview / io / cache / JvCacheableInputBox.java
index 38079d6..be6ec37 100644 (file)
  */
 package jalview.io.cache;
 
-import jalview.bin.Cache;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
 import java.awt.Dimension;
+import java.awt.FontMetrics;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusListener;
@@ -48,6 +45,10 @@ import javax.swing.event.CaretListener;
 import javax.swing.event.DocumentListener;
 import javax.swing.text.JTextComponent;
 
+import jalview.bin.Cache;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
 /**
  * A class that provides an editable combobox with a memory of previous entries
  * that may be persisted
@@ -61,15 +62,15 @@ import javax.swing.text.JTextComponent;
  */
 public class JvCacheableInputBox<E>
 {
-  private JComboBox<String> comboBox; // used for Jalview
+  protected JComboBox<String> comboBox; // used for Jalview
 
-  private JTextField textField; // used for JalviewJS
+  protected JTextField textField; // used for JalviewJS
 
-  private static final long serialVersionUID = 5774610435079326695L;
+  protected JTextComponent textComponent; // used for both
 
-  private String cacheKey;
+  protected String cacheKey;
 
-  private AppCache appCache;
+  protected AppCache appCache;
 
   private JPopupMenu popup = new JPopupMenu();
 
@@ -77,9 +78,7 @@ public class JvCacheableInputBox<E>
 
   volatile boolean enterWasPressed = false;
 
-private String prototypeDisplayValue;
-
-private boolean isJS;
+  private String prototypeDisplayValue;
 
   /**
    * @return flag indicating if the most recent keypress was enter
@@ -90,59 +89,85 @@ private boolean isJS;
   }
 
   /**
-   * Constructor
+   * Constructor given the key to cached values, and the (approximate) length in
+   * characters of the input field
    * 
    * @param newCacheKey
+   * @param length
    */
-  public JvCacheableInputBox(String newCacheKey)
+  public JvCacheableInputBox(String newCacheKey, int length)
   {
-    super();
-    isJS = Platform.isJS();
-    this.prototypeDisplayValue = 
-            "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
-    if (isJS)
+    // super();
+    cacheKey = newCacheKey;
+    prototypeDisplayValue = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
+    if (length > 0)
     {
-      textField = new JTextField() {
-         public Dimension getPreferredSize() {
-                 return super.getPreferredSize();
-//                FontMetrics fm = getFontMetrics(getFont());
-//                     return new Dimension(fm.stringWidth(prototypeDisplayValue), fm.getHeight());
-         }
-      };
-      return;
+      StringBuilder sb = new StringBuilder();
+      for (int i = 0; i < length; i++)
+      {
+        sb.append("X");
+      }
+      setPrototypeDisplayValue(sb.toString());
     }
-
-    this.cacheKey = newCacheKey;
-    comboBox = new JComboBox<String>();
-    comboBox.setEditable(true);
-    comboBox.addKeyListener(new KeyAdapter()
+    boolean useTextField = Platform.isJS();
+    // BH 2019.03 only switch for JavaScript here
+    // SwingJS TODO implement editable combo box
+    if (useTextField)
     {
-      @Override
-      public void keyTyped(KeyEvent e)
+      appCache = null;
+      textComponent = textField = new JTextField();
+      FontMetrics fm = textField.getFontMetrics(textField.getFont());
+      textField.setPreferredSize(new Dimension(
+              fm.stringWidth(prototypeDisplayValue), fm.getHeight() + 4));
+      // {
+      // @Override
+      // public Dimension getPreferredSize() {
+      // return super.getPreferredSize();
+      //// FontMetrics fm = getFontMetrics(getFont());
+      //// return new Dimension(fm.stringWidth(prototypeDisplayValue),
+      // fm.getHeight());
+      // }
+      // };
+    }
+    else
+    {
+      appCache = AppCache.getInstance();
+      comboBox = new JComboBox<>();
+      textComponent = (JTextComponent) comboBox.getEditor()
+              .getEditorComponent();
+      comboBox.setEditable(true);
+      comboBox.addKeyListener(new KeyAdapter()
       {
-        enterWasPressed = false;
-        if (e.getKeyCode() == KeyEvent.VK_ENTER)
+        @Override
+        public void keyTyped(KeyEvent e)
         {
-          enterWasPressed = true;
+          enterWasPressed = false;
+          if (e.getKeyCode() == KeyEvent.VK_ENTER)
+          {
+            enterWasPressed = true;
+          }
+          // let event bubble up
         }
-        // let event bubble up
-      }
-    });
-    comboBox.setPrototypeDisplayValue(prototypeDisplayValue);
-    appCache = AppCache.getInstance();
-    initCachePopupMenu();
-    initCache(newCacheKey);
-    updateCache();
+      });
+      comboBox.setPrototypeDisplayValue(prototypeDisplayValue);
+      initCachePopupMenu();
+      initCache(newCacheKey);
+      updateCache();
+    }
   }
 
   /**
-   * Method for initialising cache items for a given cache key and populating the
-   * in-memory cache with persisted cache items
+   * 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)
   {
+    if (appCache == null)
+    {
+      return;
+    }
     // obtain persisted cache items from properties file as a delimited string
     String delimitedCacheStr = Cache.getProperty(cacheKey);
     if (delimitedCacheStr == null || delimitedCacheStr.isEmpty())
@@ -172,6 +197,10 @@ private boolean isJS;
    */
   private void initCachePopupMenu()
   {
+    if (appCache == null)
+    {
+      return;
+    }
     menuItemClearCache.setFont(new java.awt.Font("Verdana", 0, 12));
     menuItemClearCache
             .setText(MessageManager.getString("action.clear_cached_items"));
@@ -180,7 +209,7 @@ private boolean isJS;
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        // System.out.println(">>>>> Clear cache items");
+        // jalview.bin.Console.outPrintln(">>>>> Clear cache items");
         setSelectedItem("");
         appCache.deleteCacheItems(cacheKey);
         updateCache();
@@ -215,7 +244,7 @@ private boolean isJS;
    */
   public void updateCache()
   {
-    if (isJS)
+    if (appCache == null)
     {
       return;
     }
@@ -291,10 +320,11 @@ private boolean isJS;
    */
   public void persistCache()
   {
-    if (!isJS)
+    if (appCache == null)
     {
-      appCache.persistCache(cacheKey);
+      return;
     }
+    appCache.persistCache(cacheKey);
   }
 
   /**
@@ -304,7 +334,7 @@ private boolean isJS;
    */
   public String getUserInput()
   {
-    if (isJS)
+    if (comboBox == null)
     {
       return textField.getText().trim();
     }
@@ -314,12 +344,12 @@ private boolean isJS;
 
   public JComponent getComponent()
   {
-    return isJS ? textField : comboBox;
+    return (comboBox == null ? textField : comboBox);
   }
 
   public void addActionListener(ActionListener actionListener)
   {
-    if (isJS)
+    if (comboBox == null)
     {
       textField.addActionListener(actionListener);
     }
@@ -331,36 +361,27 @@ private boolean isJS;
 
   public void addDocumentListener(DocumentListener listener)
   {
-    if (!isJS)
-    {
-      ((JTextComponent) comboBox.getEditor().getEditorComponent())
-              .getDocument().addDocumentListener(listener);
-    }
+    textComponent.getDocument().addDocumentListener(listener);
   }
 
   public void addFocusListener(FocusListener focusListener)
   {
-    if (isJS)
-    {
-      textField.addFocusListener(focusListener);
-    }
-    else
-    {
-      comboBox.addFocusListener(focusListener);
-    }
+    textComponent.addFocusListener(focusListener);
   }
 
   public void addKeyListener(KeyListener kl)
   {
-    if (!isJS)
-    {
-      comboBox.getEditor().getEditorComponent().addKeyListener(kl);
-    }
+    textComponent.addKeyListener(kl);
+  }
+
+  public void addCaretListener(CaretListener caretListener)
+  {
+    textComponent.addCaretListener(caretListener);
   }
 
   public void setEditable(boolean b)
   {
-    if (!isJS)
+    if (comboBox != null)
     {
       comboBox.setEditable(b);
     }
@@ -368,16 +389,16 @@ private boolean isJS;
 
   public void setPrototypeDisplayValue(String string)
   {
-       this.prototypeDisplayValue = string;
-    if (!isJS)
+    prototypeDisplayValue = string;
+    if (comboBox != null)
     {
       comboBox.setPrototypeDisplayValue(string);
-    } 
+    }
   }
 
   public void setSelectedItem(String userInput)
   {
-    if (!isJS)
+    if (comboBox != null)
     {
       comboBox.setSelectedItem(userInput);
     }
@@ -385,25 +406,12 @@ private boolean isJS;
 
   public boolean isPopupVisible()
   {
-    if (!isJS)
-    {
-      return comboBox.isPopupVisible();
-    }
-    return false;
-  }
-
-  public void addCaretListener(CaretListener caretListener)
-  {
-    if (!isJS)
-    {
-      ((JTextComponent) comboBox.getEditor().getEditorComponent())
-              .addCaretListener(caretListener);
-    }
+    return (comboBox != null && comboBox.isPopupVisible());
   }
 
   public void addItem(String item)
   {
-    if (!isJS)
+    if (comboBox != null)
     {
       comboBox.addItem(item);
     }