From: BobHanson Date: Wed, 8 Apr 2020 19:16:11 +0000 (-0500) Subject: reconciled with applet X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=816cd674c2769756b64c3b6cd9a8ed36f2a4b466;p=jalview.git reconciled with applet --- diff --git a/src/jalview/bin/ApplicationSingletonProvider.java b/src/jalview/bin/ApplicationSingletonProvider.java new file mode 100644 index 0000000..1b90259 --- /dev/null +++ b/src/jalview/bin/ApplicationSingletonProvider.java @@ -0,0 +1,155 @@ +/* + * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) + * Copyright (C) $$Year-Rel$$ The Jalview Authors + * + * This file is part of Jalview. + * + * Jalview is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 + * of the License, or (at your option) any later version. + * + * Jalview is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Jalview. If not, see . + * The Jalview Authors are detailed in the 'AUTHORS' file. + */ +package jalview.bin; + +import jalview.util.Platform; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +/** + * A class to hold singleton objects, whose scope (context) is + * + * This allows separation of multiple JS applets running on the same browser + * page, each with their own 'singleton' instances. + *

+ * Instance objects are held in a separate Map (keyed by Class) for each + * context. For Java, this is just a single static Map. For SwingJS, the map is + * stored as a field {@code _swingjsSingletons} of + * {@code Thread.currentThread.getThreadGroup()}, as a proxy for the applet. + *

+ * Note that when an applet is stopped, its ThreadGroup is removed, allowing any + * singleton references to be garbage collected. + * + * @author hansonr + */ +public class ApplicationSingletonProvider +{ + /** + * A tagging interface to mark classes whose singleton instances may be served + * by {@code ApplicationSingletonProvider}, giving a distinct instance per JS + * 'applet'. + *

+ * A class whose singleton should have global scope (be shared across all + * applets on a page) should not use this mechanism, but just provide + * a single instance (class static member) in the normal way. + */ + public interface ApplicationSingletonI + { + } + + /* + * Map used to hold singletons in JVM context + */ + private static Map, ApplicationSingletonI> singletons = new HashMap<>(); + + /** + * private constructor for non-instantiable class + */ + private ApplicationSingletonProvider() + { + } + + /** + * Returns the singletons map for the current context (JVM for Java, + * ThreadGroup for JS), creating the map on the first request for each JS + * ThreadGroup + * + * @return + */ + @SuppressWarnings("unchecked") + private static Map, ApplicationSingletonI> getContextMap() + { + return (Platform.isJS() + ? (Map, ApplicationSingletonI>) Platform + .getJSSingletons() + : singletons); + } + + /** + * Answers the singleton instance of the given class for the current context + * (JVM or SwingJS 'applet'). If no instance yet exists, one is created, by + * calling the class's no-argument constructor. Answers null if any error + * occurs (or occurred previously for the same class). + * + * @param c + * @return + */ + public static ApplicationSingletonI getInstance(Class c) + { + Map, ApplicationSingletonI> map = getContextMap(); + if (map.containsKey(c)) + { + /* + * singleton already created _or_ creation failed (null value stored) + */ + return map.get(c); + } + + /* + * create and save the singleton + */ + ApplicationSingletonI o = map.get(c); + try + { + Constructor con = c + .getDeclaredConstructor(); + con.setAccessible(true); + o = con.newInstance(); + } catch (IllegalAccessException | InstantiationException + | IllegalArgumentException | InvocationTargetException + | NoSuchMethodException | SecurityException e) + { + Cache.log.error("Failed to create singleton for " + c.toString() + + ", error was: " + e.toString()); + e.printStackTrace(); + } + + /* + * store the new singleton; note that a + * null value is saved if construction failed + */ + getContextMap().put(c, o); + return o; + } + + /** + * Removes the current singleton instance of the given class from the current + * application context. This has the effect of ensuring that a new instance is + * created the next time one is requested. + * + * @param c + */ + public static void removeInstance( + Class c) + { + Map, ApplicationSingletonI> map = getContextMap(); + if (map != null) + { + map.remove(c); + } + } +} diff --git a/src/jalview/bin/Cache.java b/src/jalview/bin/Cache.java index 788cb02..04add1f 100755 --- a/src/jalview/bin/Cache.java +++ b/src/jalview/bin/Cache.java @@ -20,18 +20,8 @@ */ package jalview.bin; -import jalview.datamodel.PDBEntry; -import jalview.gui.UserDefinedColours; -import jalview.schemes.ColourSchemeLoader; -import jalview.schemes.ColourSchemes; -import jalview.schemes.UserColourScheme; -import jalview.structure.StructureImportSettings; -import jalview.urls.IdOrgSettings; -import jalview.util.ColorUtils; -import jalview.util.Platform; -import jalview.ws.sifts.SiftsSettings; - import java.awt.Color; +import java.awt.Dimension; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; @@ -54,6 +44,18 @@ import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; +import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI; +import jalview.datamodel.PDBEntry; +import jalview.gui.Preferences; +import jalview.schemes.ColourSchemeLoader; +import jalview.schemes.ColourSchemes; +import jalview.schemes.UserColourScheme; +import jalview.structure.StructureImportSettings; +import jalview.urls.IdOrgSettings; +import jalview.util.ColorUtils; +import jalview.util.Platform; +import jalview.ws.sifts.SiftsSettings; + /** * Stores and retrieves Jalview Application Properties Lists and fields within * list entries are separated by '|' symbols unless otherwise stated (|) clauses @@ -208,8 +210,26 @@ import org.apache.log4j.SimpleLayout; * @author $author$ * @version $Revision$ */ -public class Cache +public class Cache implements ApplicationSingletonI { + + private Cache() + { + // private singleton + } + + /** + * In Java, this will be a static field instance, which will be + * application-specific; in JavaScript it will be an applet-specific instance + * tied to the applet's ThreadGroup. + * + * @return + */ + public static Cache getInstance() + { + return (Cache) ApplicationSingletonProvider.getInstance(Cache.class); + } + /** * property giving log4j level for CASTOR loggers */ @@ -266,7 +286,9 @@ public class Cache public static Logger log; /** Jalview Properties */ - public static Properties applicationProperties = new Properties() + // BH 2019.05.08 was static + @SuppressWarnings("serial") + public Properties applicationProperties = new Properties() { // override results in properties output in alphabetical order @Override @@ -277,7 +299,8 @@ public class Cache }; /** Default file is ~/.jalview_properties */ - static String propertiesFile; + // BH 2020 private, not static + private String propertiesFile; private static boolean propsAreReadOnly = Platform.isJS(); @@ -333,17 +356,22 @@ public class Cache */ public static void loadProperties(String propsFile) { + getInstance().loadPropertiesImpl(propsFile); + } + + private void loadPropertiesImpl(String propsFile) + { propertiesFile = propsFile; if (propsFile == null && !propsAreReadOnly) { propertiesFile = System.getProperty("user.home") + File.separatorChar + ".jalview_properties"; - } - else - { - // don't corrupt the file we've been given. - propsAreReadOnly = true; - } + } + else + { + // don't corrupt the file we've been given. + propsAreReadOnly = true; + } if (propertiesFile == null) { // BH 2019 @@ -397,7 +425,8 @@ public class Cache } // LOAD THE AUTHORS FROM THE authors.props file - String authorDetails = resolveResourceURLFor("/authors.props"); + String authorDetails = (Platform.isJS() ? null + : resolveResourceURLFor("/authors.props")); try { @@ -415,9 +444,9 @@ public class Cache } if (authorDetails == null) { - applicationProperties.remove("AUTHORS"); - applicationProperties.remove("AUTHORFNAMES"); - applicationProperties.remove("YEAR"); + applicationProperties.remove("AUTHORS"); + applicationProperties.remove("AUTHORFNAMES"); + applicationProperties.remove("YEAR"); } loadBuildProperties(false); @@ -436,12 +465,12 @@ public class Cache jalview.bin.Cache.getDefault("sifts_cache_threshold_in_days", DEFAULT_CACHE_THRESHOLD_IN_DAYS)); - IdOrgSettings.setUrl(getDefault("ID_ORG_HOSTURL", + IdOrgSettings.setUrl(getDefault(Preferences.ID_ORG_HOSTURL, "http://www.jalview.org/services/identifiers")); IdOrgSettings.setDownloadLocation(ID_ORG_FILE); StructureImportSettings.setDefaultStructureFileFormat(jalview.bin.Cache - .getDefault("PDB_DOWNLOAD_FORMAT", PDB_DOWNLOAD_FORMAT)); + .getDefault(Preferences.PDB_DOWNLOAD_FORMAT, PDB_DOWNLOAD_FORMAT)); StructureImportSettings .setDefaultPDBFileParser(DEFAULT_PDB_FILE_PARSER); // StructureImportSettings @@ -526,55 +555,55 @@ public class Cache false); } - /** - * construct a resource URL for the given absolute resource pathname - * - * @param resourcePath - * @return - */ - private static String resolveResourceURLFor(String resourcePath) - { - String url = null; - if (Platform.isJS() || !Cache.class.getProtectionDomain() - .getCodeSource().getLocation().toString().endsWith(".jar")) + /** + * construct a resource URL for the given absolute resource pathname + * + * @param resourcePath + * @return + */ + private static String resolveResourceURLFor(String resourcePath) { - try + String url = null; + if (Platform.isJS() || !Cache.class.getProtectionDomain() + .getCodeSource().getLocation().toString().endsWith(".jar")) { - url = Cache.class.getResource(resourcePath).toString(); - } catch (Exception ex) + try + { + url = Cache.class.getResource(resourcePath).toString(); + } catch (Exception ex) + { + System.err.println("Failed to resolve resource " + resourcePath + ": " + + ex.getMessage()); + } + } + else { - System.err.println("Failed to resolve resource " + resourcePath + ": " - + ex.getMessage()); + url = "jar:".concat(Cache.class.getProtectionDomain().getCodeSource() + .getLocation().toString().concat("!" + resourcePath)); } + return url; } - else - { - url = "jar:".concat(Cache.class.getProtectionDomain().getCodeSource() - .getLocation().toString().concat("!" + resourcePath)); - } - return url; - } - public static void loadBuildProperties(boolean reportVersion) - { - String codeInstallation = getProperty("INSTALLATION"); - boolean printVersion = codeInstallation == null; - - /* - * read build properties - from the Jalview jar for a Java distribution, - * or from codebase file in test or JalviewJS context - */ - try + public static void loadBuildProperties(boolean reportVersion) { + String codeInstallation = getProperty("INSTALLATION"); + boolean printVersion = codeInstallation == null; + + /* + * read build properties - from the Jalview jar for a Java distribution, + * or from codebase file in test or JalviewJS context + */ + try + { String buildDetails = resolveResourceURLFor("/.build_properties"); URL localJarFileURL = new URL(buildDetails); - InputStream in = localJarFileURL.openStream(); - applicationProperties.load(in); - in.close(); - } catch (Exception ex) - { - System.out.println("Error reading build details: " + ex); - applicationProperties.remove("VERSION"); + InputStream in = localJarFileURL.openStream(); + getInstance().applicationProperties.load(in); + in.close(); + } catch (Exception ex) + { + System.out.println("Error reading build details: " + ex); + getInstance().applicationProperties.remove("VERSION"); } String codeVersion = getProperty("VERSION"); codeInstallation = getProperty("INSTALLATION"); @@ -598,7 +627,8 @@ public class Cache } } - private static void deleteBuildProperties() + // BH 2020 was static + private void deleteBuildProperties() { applicationProperties.remove("LATEST_VERSION"); applicationProperties.remove("VERSION"); @@ -620,31 +650,47 @@ public class Cache */ public static String getProperty(String key) { - String prop = applicationProperties.getProperty(key); - if (prop == null && Platform.isJS()) - { - prop = applicationProperties.getProperty(Platform.getUniqueAppletID() - + "_" + JS_PROPERTY_PREFIX + key); - } - return prop; + return getInstance().applicationProperties.getProperty(key); + +// old, original idea: +// String prop = applicationProperties.getProperty(key); +// if (prop == null && Platform.isJS()) +// { +// prop = applicationProperties.getProperty(Platform.getUniqueAppletID() +// + "_" + JS_PROPERTY_PREFIX + key); +// } +// return prop; + } + + //These methods are used when checking if the saved preference is different + // to the default setting + /** - * These methods are used when checking if the saved preference is different - * to the default setting + * Returns the boolean property value for the given property name. If the + * value is absent then the default value is returned instead. + * + * @param property + * @param def + * @return */ - public static boolean getDefault(String property, boolean def) { String string = getProperty(property); - if (string != null) - { - def = Boolean.valueOf(string).booleanValue(); - } - - return def; + // BH simplification only + return string == null ? def : Boolean.parseBoolean(string); } + /** + * Returns the integer property value for the given property name. If the + * value is absent, or malformed (not an integer), then the default value is + * returned instead. + * + * @param property + * @param def + * @return + */ public static int getDefault(String property, int def) { String string = getProperty(property); @@ -652,7 +698,9 @@ public class Cache { try { - def = Integer.parseInt(string); + // BH simplification only + + return Integer.parseInt(string); } catch (NumberFormatException e) { System.out.println("Error parsing int property '" + property @@ -664,8 +712,12 @@ public class Cache } /** - * Answers the value of the given property, or the supplied default value if + * Returns the value of the given property, or the supplied default value if * the property is not set + * + * @param property + * @param def + * @return */ public static String getDefault(String property, String def) { @@ -685,11 +737,44 @@ public class Cache */ public static Object setProperty(String key, String obj) { + return getInstance().setPropertyImpl(key, obj, true); + } + + /** + * + * Sets a property value for the running application, without saving it to the + * properties file. + * + * Replaces direct call to Cache.applicationProperties.setProperty + * + * Used extensively in AppletParams and Preferences.ok_actionPerformed + * + * + * @param key + * @param obj + */ + public static void setPropertyNoSave(String key, String obj) + { + getInstance().setPropertyImpl(key, obj, false); + } + + + /** + * Sets a property value, and optionally also saves the current properties to + * file + * + * @param key + * @param obj + * @param andSave + * @return + */ + private Object setPropertyImpl(String key, String obj, boolean andSave) + { Object oldValue = null; try { oldValue = applicationProperties.setProperty(key, obj); - if (propertiesFile != null && !propsAreReadOnly) + if (andSave && !propsAreReadOnly && propertiesFile != null) { FileOutputStream out = new FileOutputStream(propertiesFile); applicationProperties.store(out, "---JalviewX Properties File---"); @@ -704,21 +789,58 @@ public class Cache } /** - * remove the specified property from the jalview properties file + * Removes the specified property from the jalview properties file * - * @param string + * @param key */ - public static void removeProperty(String string) + public static void removeProperty(String key) { - applicationProperties.remove(string); - saveProperties(); + getInstance().removePropertyImpl(key, true); } /** - * save the properties to the jalview properties path + * Removes the named property for the running application, without saving the + * properties file. + * + * Called by Preferences.ok_actionPerformed specifically for SEQUENCE_LINKS and STORED_LINKS. + * + * + * @param key + */ + public static void removePropertyNoSave(String key) + { + getInstance().removePropertyImpl(key, false); + } + + /** + * Removes the named property, and optionally saves the current properties to + * file + * + * @param key + * @param andSave + */ + private void removePropertyImpl(String key, boolean andSave) + { + applicationProperties.remove(key); + if (andSave) + { + savePropertiesImpl(); + } + } + + /** + * Saves the current properties to file */ public static void saveProperties() { + getInstance().savePropertiesImpl(); + } + + /** + * save the properties to the jalview properties path + */ + private void savePropertiesImpl() + { if (!propsAreReadOnly) { try @@ -733,10 +855,17 @@ public class Cache } } + private final static int UNTESTED = -1; + + private final static int TRUE = 1; + + private final static int FALSE = 0; + /** * internal vamsas class discovery state */ - private static int vamsasJarsArePresent = -1; + private static int vamsasJarsArePresent = (Platform.isJS() ? FALSE + : UNTESTED); /** * Searches for vamsas client classes on class path. @@ -745,7 +874,7 @@ public class Cache */ public static boolean vamsasJarsPresent() { - if (vamsasJarsArePresent == -1) + if (vamsasJarsArePresent == UNTESTED) { try { @@ -754,7 +883,7 @@ public class Cache { jalview.bin.Cache.log.debug( "Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)"); - vamsasJarsArePresent = 1; + vamsasJarsArePresent = TRUE; Logger lvclient = Logger.getLogger("uk.ac.vamsas"); lvclient.setLevel(Level.toLevel(Cache .getDefault("logs.Vamsas.Level", Level.INFO.toString()))); @@ -765,17 +894,18 @@ public class Cache } } catch (Exception e) { - vamsasJarsArePresent = 0; + vamsasJarsArePresent = FALSE; jalview.bin.Cache.log.debug("Vamsas Classes are not present"); } } - return (vamsasJarsArePresent > 0); + return (vamsasJarsArePresent == TRUE); } /** * internal vamsas class discovery state */ - private static int groovyJarsArePresent = -1; + private static int groovyJarsArePresent = (Platform.isJS() ? FALSE + : UNTESTED); /** * Searches for vamsas client classes on class path. @@ -784,7 +914,7 @@ public class Cache */ public static boolean groovyJarsPresent() { - if (groovyJarsArePresent == -1) + if (groovyJarsArePresent == UNTESTED) { try { @@ -793,7 +923,7 @@ public class Cache { jalview.bin.Cache.log.debug( "Found Groovy (groovy.lang.GroovyObject can be loaded)"); - groovyJarsArePresent = 1; + groovyJarsArePresent = TRUE; Logger lgclient = Logger.getLogger("groovy"); lgclient.setLevel(Level.toLevel(Cache .getDefault("logs.Groovy.Level", Level.INFO.toString()))); @@ -804,15 +934,15 @@ public class Cache } } catch (Error e) { - groovyJarsArePresent = 0; + groovyJarsArePresent = FALSE; jalview.bin.Cache.log.debug("Groovy Classes are not present", e); } catch (Exception e) { - groovyJarsArePresent = 0; + groovyJarsArePresent = FALSE; jalview.bin.Cache.log.debug("Groovy Classes are not present"); } } - return (groovyJarsArePresent > 0); + return (groovyJarsArePresent == TRUE); } /** @@ -821,15 +951,18 @@ public class Cache */ protected static Object tracker = null; - protected static Class trackerfocus = null; + protected static Class trackerfocus = null; - protected static Class jgoogleanalyticstracker = null; + protected static Class jgoogleanalyticstracker = null; /** * Initialise the google tracker if it is not done already. */ public static void initGoogleTracker() { + + // TODO: SwingJS JavaScript tracker? + if (tracker == null) { if (jgoogleanalyticstracker == null) @@ -942,7 +1075,10 @@ public class Cache } /** - * get the user's default colour if available + * Returns the Color value of the given property's value, or the supplied + * default colour if no property is found, or it cannot be parsed to a colour. + * Colours are normally saved as hex rgb values, though other formats may be + * parseable. * * @param property * @param defcolour @@ -965,6 +1101,22 @@ public class Cache } /** + * Stores a colour as a Jalview property, converted to hex values for rgb. + * Properties are not saved to file. + * + * + * + * Used extensively in Preferences.ok_actionPerformed + * + * @param property + * @param colour + */ + public static void setColourPropertyNoSave(String property, Color colour) + { + setPropertyNoSave(property, jalview.util.Format.getHexString(colour)); + } + + /** * store a colour as a Jalview user default property * * @param property @@ -977,6 +1129,7 @@ public class Cache /** * Stores a formatted date in a jalview property, using a fixed locale. + * Updated properties are written out to the properties file. * * @param propertyName * @param date @@ -1053,11 +1206,11 @@ public class Cache } if (value == null || value.trim().length() < 1) { - Cache.applicationProperties.remove(propName); + getInstance().applicationProperties.remove(propName); } else { - Cache.applicationProperties.setProperty(propName, value); + getInstance().applicationProperties.setProperty(propName, value); } } @@ -1102,13 +1255,15 @@ public class Cache { if (coloursFound.toString().length() > 1) { - setProperty(UserDefinedColours.USER_DEFINED_COLOURS, + // BH moved to Preferences for consistency + setProperty(Preferences.USER_DEFINED_COLOURS, coloursFound.toString()); } else { - applicationProperties - .remove(UserDefinedColours.USER_DEFINED_COLOURS); + // BH moved to Preferences for consistency + getInstance().applicationProperties + .remove(Preferences.USER_DEFINED_COLOURS); } } } @@ -1174,4 +1329,40 @@ public class Cache // eg 'built from Source' or update channel return jalview.bin.Cache.getDefault("INSTALLATION", "unknown"); } + + /** + * retrieve a dimension, such as for Jmol + * + * @param property + * @param def + * @return + */ + public static Dimension getDefaultDim(String property, Dimension def) + { + String s = getProperty(property); + if (s != null) + { + if (s.indexOf(',') < 0) + { + s = s.trim().replace(' ', ','); + if (s.indexOf(',') < 0) + { + s += "," + s; + } + } + try + { + int pt = s.indexOf(","); + return new Dimension(Integer.parseInt(s.substring(0, pt)), + Integer.parseInt(s.substring(pt + 1))); + } catch (NumberFormatException e) + { + System.out.println("Error parsing Dimension property '" + property + + "' with value '" + s + "'"); + } + } + return def; + } + + } diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java index 04b83a3..6d46ce7 100755 --- a/src/jalview/gui/Preferences.java +++ b/src/jalview/gui/Preferences.java @@ -38,6 +38,7 @@ import jalview.urls.UrlLinkTableModel; import jalview.urls.api.UrlProviderFactoryI; import jalview.urls.api.UrlProviderI; import jalview.urls.desktop.DesktopUrlProviderFactory; +import jalview.util.BrowserLauncher; import jalview.util.MessageManager; import jalview.util.Platform; import jalview.util.UrlConstants; @@ -81,8 +82,12 @@ import ext.edu.ucsf.rbvi.strucviz2.StructureManager; * @author $author$ * @version $Revision$ */ +@SuppressWarnings("serial") public class Preferences extends GPreferences { + + // original to develop + public static final String ENABLE_SPLIT_FRAME = "ENABLE_SPLIT_FRAME"; public static final String SCALE_PROTEIN_TO_CDNA = "SCALE_PROTEIN_TO_CDNA"; @@ -123,13 +128,119 @@ public class Preferences extends GPreferences private static final int MAX_FONT_SIZE = 30; + // new for applet + + public static final String ALLOW_UNPUBLISHED_PDB_QUERYING = "ALLOW_UNPUBLISHED_PDB_QUERYING"; + + public static final String ANNOTATIONCOLOUR_MAX = "ANNOTATIONCOLOUR_MAX"; + + public static final String ANNOTATIONCOLOUR_MIN = "ANNOTATIONCOLOUR_MIN"; + + public static final String ANTI_ALIAS = "ANTI_ALIAS"; + + public static final String AUTO_CALC_CONSENSUS = "AUTO_CALC_CONSENSUS"; + + public static final String AUTOASSOCIATE_PDBANDSEQS = "AUTOASSOCIATE_PDBANDSEQS"; + + public static final String BLOSUM62_PCA_FOR_NUCLEOTIDE = "BLOSUM62_PCA_FOR_NUCLEOTIDE"; + + public static final String CENTRE_COLUMN_LABELS = "CENTRE_COLUMN_LABELS"; + + public static final String DBREFFETCH_USEPICR = "DBREFFETCH_USEPICR"; + + public static final String FIGURE_AUTOIDWIDTH = "FIGURE_AUTOIDWIDTH"; + + public static final String FIGURE_FIXEDIDWIDTH = "FIGURE_FIXEDIDWIDTH"; + + public static final String FOLLOW_SELECTIONS = "FOLLOW_SELECTIONS"; + + public static final String FONT_NAME = "FONT_NAME"; + + public static final String FONT_SIZE = "FONT_SIZE"; + + public static final String FONT_STYLE = "FONT_STYLE"; + + public static final String GAP_SYMBOL = "GAP_SYMBOL"; + + public static final String HIDE_INTRONS = "HIDE_INTRONS"; + + public static final String ID_ITALICS = "ID_ITALICS"; + + public static final String ID_ORG_HOSTURL = "ID_ORG_HOSTURL"; + + public static final String MAP_WITH_SIFTS = "MAP_WITH_SIFTS"; + + public static final String NOQUESTIONNAIRES = "NOQUESTIONNAIRES"; + + public static final String NORMALISE_CONSENSUS_LOGO = "NORMALISE_CONSENSUS_LOGO"; + + public static final String NORMALISE_LOGO = "NORMALISE_LOGO"; + + public static final String PAD_GAPS = "PAD_GAPS"; + + public static final String PDB_DOWNLOAD_FORMAT = "PDB_DOWNLOAD_FORMAT"; + + public static final String QUESTIONNAIRE = "QUESTIONNAIRE"; + + public static final String RELAXEDSEQIDMATCHING = "RELAXEDSEQIDMATCHING"; + + public static final String RIGHT_ALIGN_IDS = "RIGHT_ALIGN_IDS"; + + public static final String SHOW_ANNOTATIONS = "SHOW_ANNOTATIONS"; + + public static final String SHOW_CONSENSUS = "SHOW_CONSENSUS"; + + public static final String SHOW_CONSENSUS_HISTOGRAM = "SHOW_CONSENSUS_HISTOGRAM"; + + public static final String SHOW_CONSENSUS_LOGO = "SHOW_CONSENSUS_LOGO"; + + public static final String SHOW_CONSERVATION = "SHOW_CONSERVATION"; + + public static final String SHOW_DBREFS_TOOLTIP = "SHOW_DBREFS_TOOLTIP"; + + public static final String SHOW_GROUP_CONSENSUS = "SHOW_GROUP_CONSENSUS"; + + public static final String SHOW_GROUP_CONSERVATION = "SHOW_GROUP_CONSERVATION"; + + public static final String SHOW_IDENTITY = "SHOW_IDENTITY"; + + public static final String SHOW_FULLSCREEN = "SHOW_FULLSCREEN"; + + public static final String SHOW_JVSUFFIX = "SHOW_JVSUFFIX"; + + public static final String SHOW_NPFEATS_TOOLTIP = "SHOW_NPFEATS_TOOLTIP"; + + public static final String SHOW_OVERVIEW = "SHOW_OVERVIEW"; + + public static final String SHOW_QUALITY = "SHOW_QUALITY"; + + public static final String SHOW_UNCONSERVED = "SHOW_UNCONSERVED"; + + public static final String SORT_ALIGNMENT = "SORT_ALIGNMENT"; + + public static final String SORT_BY_TREE = "SORT_BY_TREE"; + + public static final String STRUCTURE_DIMENSIONS = "STRUCTURE_DIMENSIONS"; + + public static final String UNIPROT_DOMAIN = "UNIPROT_DOMAIN"; + + public static final String USE_FULL_SO = "USE_FULL_SO"; + + public static final String USER_DEFINED_COLOURS = "USER_DEFINED_COLOURS"; + + public static final String WRAP_ALIGNMENT = "WRAP_ALIGNMENT"; + + + public static final Dimension DEFAULT_STRUCTURE_DIMENSIONS = new Dimension( + 600, 600); + /** * Holds name and link separated with | character. Sequence ID must be * $SEQUENCE_ID$ or $SEQUENCE_ID=/.possible | chars ./=$ */ - public static UrlProviderI sequenceUrlLinks; + public static UrlProviderI sequenceUrlLinks; // must be nonfinal for test - public static UrlLinkTableModel dataModel; + public final static UrlLinkTableModel dataModel; /** * Holds name and link separated with | character. Sequence IDS and Sequences @@ -139,7 +250,8 @@ public class Preferences extends GPreferences * (TODO: proper escape for using | to separate ids or sequences */ - public static List groupURLLinks; + public static final List groupURLLinks; // not implemented + static { // get links selected to be in the menu (SEQUENCE_LINKS) @@ -165,7 +277,7 @@ public class Preferences extends GPreferences * .properties file as '|' separated strings */ - groupURLLinks = new ArrayList<>(); + groupURLLinks = new ArrayList<>(); // not implemented } JInternalFrame frame; @@ -200,11 +312,16 @@ public class Preferences extends GPreferences wsPrefs = new WsPreferences(); wsTab.add(wsPrefs, BorderLayout.CENTER); } - int width = 500, height = 450; + int width = 700, height = 510; // BH 2019.07.12 added 60 to height and 40 to + // width (for Visual check boxes and Links + // "Double Click" header) + // BH 2019.09.24 added 20 to width + // (structure panel was too small anyway, and I added a default dimension + // for Jmol if (Platform.isAMacAndNotJS()) { width = 570; - height = 480; + height = 540; // BH 2019.07.12 added 30 } Desktop.addInternalFrame(frame, @@ -214,30 +331,30 @@ public class Preferences extends GPreferences /* * Set Visual tab defaults */ - seqLimit.setSelected(Cache.getDefault("SHOW_JVSUFFIX", true)); - rightAlign.setSelected(Cache.getDefault("RIGHT_ALIGN_IDS", false)); - fullScreen.setSelected(Cache.getDefault("SHOW_FULLSCREEN", false)); - annotations.setSelected(Cache.getDefault("SHOW_ANNOTATIONS", true)); - - conservation.setSelected(Cache.getDefault("SHOW_CONSERVATION", true)); - quality.setSelected(Cache.getDefault("SHOW_QUALITY", true)); - identity.setSelected(Cache.getDefault("SHOW_IDENTITY", true)); - openoverv.setSelected(Cache.getDefault("SHOW_OVERVIEW", false)); + seqLimit.setSelected(Cache.getDefault(SHOW_JVSUFFIX, true)); + rightAlign.setSelected(Cache.getDefault(RIGHT_ALIGN_IDS, false)); + fullScreen.setSelected(Cache.getDefault(SHOW_FULLSCREEN, false)); + annotations.setSelected(Cache.getDefault(SHOW_ANNOTATIONS, true)); + + conservation.setSelected(Cache.getDefault(SHOW_CONSERVATION, true)); + quality.setSelected(Cache.getDefault(SHOW_QUALITY, true)); + identity.setSelected(Cache.getDefault(SHOW_IDENTITY, true)); + openoverv.setSelected(Cache.getDefault(SHOW_OVERVIEW, false)); showUnconserved - .setSelected(Cache.getDefault("SHOW_UNCONSERVED", false)); + .setSelected(Cache.getDefault(SHOW_UNCONSERVED, false)); showOccupancy.setSelected(Cache.getDefault(SHOW_OCCUPANCY, false)); showGroupConsensus - .setSelected(Cache.getDefault("SHOW_GROUP_CONSENSUS", false)); + .setSelected(Cache.getDefault(SHOW_GROUP_CONSENSUS, false)); showGroupConservation.setSelected( - Cache.getDefault("SHOW_GROUP_CONSERVATION", false)); + Cache.getDefault(SHOW_GROUP_CONSERVATION, false)); showConsensHistogram.setSelected( - Cache.getDefault("SHOW_CONSENSUS_HISTOGRAM", true)); + Cache.getDefault(SHOW_CONSENSUS_HISTOGRAM, true)); showConsensLogo - .setSelected(Cache.getDefault("SHOW_CONSENSUS_LOGO", false)); + .setSelected(Cache.getDefault(SHOW_CONSENSUS_LOGO, false)); showNpTooltip - .setSelected(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true)); + .setSelected(Cache.getDefault(SHOW_NPFEATS_TOOLTIP, true)); showDbRefTooltip - .setSelected(Cache.getDefault("SHOW_DBREFS_TOOLTIP", true)); + .setSelected(Cache.getDefault(SHOW_DBREFS_TOOLTIP, true)); String[] fonts = java.awt.GraphicsEnvironment .getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); @@ -255,28 +372,28 @@ public class Preferences extends GPreferences fontStyleCB.addItem("bold"); fontStyleCB.addItem("italic"); - fontNameCB.setSelectedItem(Cache.getDefault("FONT_NAME", "SansSerif")); - fontSizeCB.setSelectedItem(Cache.getDefault("FONT_SIZE", "10")); + fontNameCB.setSelectedItem(Cache.getDefault(FONT_NAME, "SansSerif")); + fontSizeCB.setSelectedItem(Cache.getDefault(FONT_SIZE, "10")); fontStyleCB.setSelectedItem( - Cache.getDefault("FONT_STYLE", Font.PLAIN + "")); + Cache.getDefault(FONT_STYLE, Font.PLAIN + "")); - smoothFont.setSelected(Cache.getDefault("ANTI_ALIAS", true)); + smoothFont.setSelected(Cache.getDefault(ANTI_ALIAS, false)); scaleProteinToCdna .setSelected(Cache.getDefault(SCALE_PROTEIN_TO_CDNA, false)); - idItalics.setSelected(Cache.getDefault("ID_ITALICS", true)); + idItalics.setSelected(Cache.getDefault(ID_ITALICS, true)); - wrap.setSelected(Cache.getDefault("WRAP_ALIGNMENT", false)); + wrap.setSelected(Cache.getDefault(WRAP_ALIGNMENT, false)); gapSymbolCB.addItem("-"); gapSymbolCB.addItem("."); - gapSymbolCB.setSelectedItem(Cache.getDefault("GAP_SYMBOL", "-")); + gapSymbolCB.setSelectedItem(Cache.getDefault(GAP_SYMBOL, "-")); sortby.addItem("No sort"); sortby.addItem("Id"); sortby.addItem("Pairwise Identity"); - sortby.setSelectedItem(Cache.getDefault("SORT_ALIGNMENT", "No sort")); + sortby.setSelectedItem(Cache.getDefault(SORT_ALIGNMENT, "No sort")); sortAnnBy.addItem(SequenceAnnotationOrder.NONE.toString()); sortAnnBy @@ -317,9 +434,9 @@ public class Preferences extends GPreferences newProp = Cache.getDefault(DEFAULT_COLOUR_NUC, null); nucColour.setSelectedItem(newProp != null ? newProp : oldProp); minColour.setBackground( - Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange)); + Cache.getDefaultColour(ANNOTATIONCOLOUR_MIN, Color.orange)); maxColour.setBackground( - Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red)); + Cache.getDefaultColour(ANNOTATIONCOLOUR_MAX, Color.red)); /* * Set overview panel defaults @@ -349,6 +466,10 @@ public class Preferences extends GPreferences addTempFactor.setEnabled(structSelected); structViewer.setSelectedItem( Cache.getDefault(STRUCTURE_DISPLAY, ViewerType.JMOL.name())); + Dimension d = Cache.getDefaultDim(STRUCTURE_DIMENSIONS, + DEFAULT_STRUCTURE_DIMENSIONS); + String s = d.width + "," + d.height; + structureDimensions.setText(s); chimeraPath.setText(Cache.getDefault(CHIMERA_PATH, "")); chimeraPath.addActionListener(new ActionListener() { @@ -359,7 +480,7 @@ public class Preferences extends GPreferences } }); - if (Cache.getDefault("MAP_WITH_SIFTS", false)) + if (Cache.getDefault(MAP_WITH_SIFTS, false)) { siftsMapping.setSelected(true); } @@ -369,7 +490,7 @@ public class Preferences extends GPreferences } SiftsSettings - .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false)); + .setMapWithSifts(Cache.getDefault(MAP_WITH_SIFTS, false)); /* * Set Connections tab defaults @@ -505,7 +626,7 @@ public class Preferences extends GPreferences usagestats.setSelected(Cache.getDefault("USAGESTATS", false)); // note antisense here: default is true questionnaire - .setSelected(Cache.getProperty("NOQUESTIONNAIRES") == null); + .setSelected(Cache.getProperty(NOQUESTIONNAIRES) == null); versioncheck.setSelected(Cache.getDefault("VERSION_CHECK", true)); /* @@ -514,10 +635,10 @@ public class Preferences extends GPreferences setupOutputCombo(epsRendering, "EPS_RENDERING"); setupOutputCombo(htmlRendering, "HTML_RENDERING"); setupOutputCombo(svgRendering, "SVG_RENDERING"); - autoIdWidth.setSelected(Cache.getDefault("FIGURE_AUTOIDWIDTH", false)); + autoIdWidth.setSelected(Cache.getDefault(FIGURE_AUTOIDWIDTH, false)); userIdWidth.setEnabled(!autoIdWidth.isSelected()); userIdWidthlabel.setEnabled(!autoIdWidth.isSelected()); - Integer wi = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH"); + Integer wi = Cache.getIntegerProperty(FIGURE_FIXEDIDWIDTH); userIdWidth.setText(wi == null ? "" : wi.toString()); // TODO: refactor to use common enum via FormatAdapter and allow extension // for new flat file formats @@ -536,9 +657,9 @@ public class Preferences extends GPreferences * Set Editing tab defaults */ autoCalculateConsCheck - .setSelected(Cache.getDefault("AUTO_CALC_CONSENSUS", true)); - padGaps.setSelected(Cache.getDefault("PAD_GAPS", false)); - sortByTree.setSelected(Cache.getDefault("SORT_BY_TREE", false)); + .setSelected(Cache.getDefault(AUTO_CALC_CONSENSUS, true)); + padGaps.setSelected(Cache.getDefault(PAD_GAPS, false)); + sortByTree.setSelected(Cache.getDefault(SORT_BY_TREE, false)); annotations_actionPerformed(null); // update the display of the annotation // settings @@ -547,7 +668,11 @@ public class Preferences extends GPreferences /* * Set Backups tab defaults */ - loadLastSavedBackupsOptions(); + if (!Platform.isJS()) + { + loadLastSavedBackupsOptions(); + } + } /** @@ -600,65 +725,64 @@ public class Preferences extends GPreferences /* * Save Visual settings */ - Cache.applicationProperties.setProperty("SHOW_JVSUFFIX", + Cache.setPropertyNoSave(SHOW_JVSUFFIX, Boolean.toString(seqLimit.isSelected())); - Cache.applicationProperties.setProperty("RIGHT_ALIGN_IDS", + Cache.setPropertyNoSave(RIGHT_ALIGN_IDS, Boolean.toString(rightAlign.isSelected())); - Cache.applicationProperties.setProperty("SHOW_FULLSCREEN", + Cache.setPropertyNoSave(SHOW_FULLSCREEN, Boolean.toString(fullScreen.isSelected())); - Cache.applicationProperties.setProperty("SHOW_OVERVIEW", + Cache.setPropertyNoSave(SHOW_OVERVIEW, Boolean.toString(openoverv.isSelected())); - Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS", + Cache.setPropertyNoSave(SHOW_ANNOTATIONS, Boolean.toString(annotations.isSelected())); - Cache.applicationProperties.setProperty("SHOW_CONSERVATION", + Cache.setPropertyNoSave(SHOW_CONSERVATION, Boolean.toString(conservation.isSelected())); - Cache.applicationProperties.setProperty("SHOW_QUALITY", + Cache.setPropertyNoSave(SHOW_QUALITY, Boolean.toString(quality.isSelected())); - Cache.applicationProperties.setProperty("SHOW_IDENTITY", + Cache.setPropertyNoSave(SHOW_IDENTITY, Boolean.toString(identity.isSelected())); - Cache.applicationProperties.setProperty("GAP_SYMBOL", + Cache.setPropertyNoSave(GAP_SYMBOL, gapSymbolCB.getSelectedItem().toString()); - Cache.applicationProperties.setProperty("FONT_NAME", + Cache.setPropertyNoSave(FONT_NAME, fontNameCB.getSelectedItem().toString()); - Cache.applicationProperties.setProperty("FONT_STYLE", + Cache.setPropertyNoSave(FONT_STYLE, fontStyleCB.getSelectedItem().toString()); - Cache.applicationProperties.setProperty("FONT_SIZE", + Cache.setPropertyNoSave(FONT_SIZE, fontSizeCB.getSelectedItem().toString()); - Cache.applicationProperties.setProperty("ID_ITALICS", + Cache.setPropertyNoSave(ID_ITALICS, Boolean.toString(idItalics.isSelected())); - Cache.applicationProperties.setProperty("SHOW_UNCONSERVED", + Cache.setPropertyNoSave(SHOW_UNCONSERVED, Boolean.toString(showUnconserved.isSelected())); - Cache.applicationProperties.setProperty(SHOW_OCCUPANCY, + Cache.setPropertyNoSave(SHOW_OCCUPANCY, Boolean.toString(showOccupancy.isSelected())); - Cache.applicationProperties.setProperty("SHOW_GROUP_CONSENSUS", + Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, Boolean.toString(showGroupConsensus.isSelected())); - Cache.applicationProperties.setProperty("SHOW_GROUP_CONSERVATION", + Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, Boolean.toString(showGroupConservation.isSelected())); - Cache.applicationProperties.setProperty("SHOW_CONSENSUS_HISTOGRAM", + Cache.setPropertyNoSave(SHOW_CONSENSUS_HISTOGRAM, Boolean.toString(showConsensHistogram.isSelected())); - Cache.applicationProperties.setProperty("SHOW_CONSENSUS_LOGO", + Cache.setPropertyNoSave(SHOW_CONSENSUS_LOGO, Boolean.toString(showConsensLogo.isSelected())); - Cache.applicationProperties.setProperty("ANTI_ALIAS", + Cache.setPropertyNoSave(ANTI_ALIAS, Boolean.toString(smoothFont.isSelected())); - Cache.applicationProperties.setProperty(SCALE_PROTEIN_TO_CDNA, + Cache.setPropertyNoSave(SCALE_PROTEIN_TO_CDNA, Boolean.toString(scaleProteinToCdna.isSelected())); - Cache.applicationProperties.setProperty("SHOW_NPFEATS_TOOLTIP", + Cache.setPropertyNoSave(SHOW_NPFEATS_TOOLTIP, Boolean.toString(showNpTooltip.isSelected())); - Cache.applicationProperties.setProperty("SHOW_DBREFS_TOOLTIP", + Cache.setPropertyNoSave(SHOW_DBREFS_TOOLTIP, Boolean.toString(showDbRefTooltip.isSelected())); - Cache.applicationProperties.setProperty("WRAP_ALIGNMENT", + Cache.setPropertyNoSave(WRAP_ALIGNMENT, Boolean.toString(wrap.isSelected())); - Cache.applicationProperties.setProperty("STARTUP_FILE", - startupFileTextfield.getText()); - Cache.applicationProperties.setProperty("SHOW_STARTUP_FILE", + Cache.setPropertyNoSave("STARTUP_FILE", startupFileTextfield.getText()); + Cache.setPropertyNoSave("SHOW_STARTUP_FILE", Boolean.toString(startupCheckbox.isSelected())); - Cache.applicationProperties.setProperty("SORT_ALIGNMENT", + Cache.setPropertyNoSave(SORT_ALIGNMENT, sortby.getSelectedItem().toString()); // convert description of sort order to enum name for save @@ -666,98 +790,102 @@ public class Preferences extends GPreferences .forDescription(sortAnnBy.getSelectedItem().toString()); if (annSortOrder != null) { - Cache.applicationProperties.setProperty(SORT_ANNOTATIONS, - annSortOrder.name()); + Cache.setPropertyNoSave(SORT_ANNOTATIONS, annSortOrder.name()); } final boolean showAutocalcFirst = sortAutocalc.getSelectedIndex() == 0; - Cache.applicationProperties.setProperty(SHOW_AUTOCALC_ABOVE, + Cache.setPropertyNoSave(SHOW_AUTOCALC_ABOVE, Boolean.valueOf(showAutocalcFirst).toString()); /* * Save Colours settings */ - Cache.applicationProperties.setProperty(DEFAULT_COLOUR_PROT, + Cache.setPropertyNoSave(DEFAULT_COLOUR_PROT, protColour.getSelectedItem().toString()); - Cache.applicationProperties.setProperty(DEFAULT_COLOUR_NUC, + Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC, nucColour.getSelectedItem().toString()); - Cache.setColourProperty("ANNOTATIONCOLOUR_MIN", + Cache.setColourPropertyNoSave(ANNOTATIONCOLOUR_MIN, minColour.getBackground()); - Cache.setColourProperty("ANNOTATIONCOLOUR_MAX", + Cache.setColourPropertyNoSave(ANNOTATIONCOLOUR_MAX, maxColour.getBackground()); /* * Save Overview settings */ - Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground()); - Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground()); - Cache.applicationProperties.setProperty(USE_LEGACY_GAP, + Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground()); + Cache.setColourPropertyNoSave(HIDDEN_COLOUR, + hiddenColour.getBackground()); + Cache.setPropertyNoSave(USE_LEGACY_GAP, Boolean.toString(useLegacyGap.isSelected())); - Cache.applicationProperties.setProperty(SHOW_OV_HIDDEN_AT_START, + Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START, Boolean.toString(showHiddenAtStart.isSelected())); /* * Save Structure settings */ - Cache.applicationProperties.setProperty(ADD_TEMPFACT_ANN, + Cache.setPropertyNoSave(ADD_TEMPFACT_ANN, Boolean.toString(addTempFactor.isSelected())); - Cache.applicationProperties.setProperty(ADD_SS_ANN, + Cache.setPropertyNoSave(ADD_SS_ANN, Boolean.toString(addSecondaryStructure.isSelected())); - Cache.applicationProperties.setProperty(USE_RNAVIEW, + Cache.setPropertyNoSave(USE_RNAVIEW, Boolean.toString(useRnaView.isSelected())); - Cache.applicationProperties.setProperty(STRUCT_FROM_PDB, + Cache.setPropertyNoSave(STRUCT_FROM_PDB, Boolean.toString(structFromPdb.isSelected())); - Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, + Cache.setPropertyNoSave(STRUCTURE_DISPLAY, structViewer.getSelectedItem().toString()); + Cache.setPropertyNoSave(STRUCTURE_DIMENSIONS, + structureDimensions.getText()); // BH 2019.07.12 Cache.setOrRemove(CHIMERA_PATH, chimeraPath.getText()); - Cache.applicationProperties.setProperty("MAP_WITH_SIFTS", + Cache.setPropertyNoSave(MAP_WITH_SIFTS, Boolean.toString(siftsMapping.isSelected())); SiftsSettings.setMapWithSifts(siftsMapping.isSelected()); /* * Save Output settings */ - Cache.applicationProperties.setProperty("EPS_RENDERING", + Cache.setPropertyNoSave("EPS_RENDERING", ((OptionsParam) epsRendering.getSelectedItem()).getCode()); - Cache.applicationProperties.setProperty("HTML_RENDERING", + Cache.setPropertyNoSave("HTML_RENDERING", ((OptionsParam) htmlRendering.getSelectedItem()).getCode()); - Cache.applicationProperties.setProperty("SVG_RENDERING", + Cache.setPropertyNoSave("SVG_RENDERING", ((OptionsParam) svgRendering.getSelectedItem()).getCode()); - /* - * Save Connections settings + if (!Platform.isJS()) + /** + * @j2sNative */ - Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText()); - - jalview.util.BrowserLauncher.resetBrowser(); + { + // Java only + // Save Connections settings + Cache.setOrRemove("DEFAULT_BROWSER", defaultBrowser.getText()); + BrowserLauncher.resetBrowser(); + } // save user-defined and selected links String menuLinks = sequenceUrlLinks.writeUrlsAsString(true); if (menuLinks.isEmpty()) { - Cache.applicationProperties.remove("SEQUENCE_LINKS"); + Cache.removePropertyNoSave("SEQUENCE_LINKS"); } else { - Cache.applicationProperties.setProperty("SEQUENCE_LINKS", - menuLinks.toString()); + Cache.setPropertyNoSave("SEQUENCE_LINKS", menuLinks.toString()); } String nonMenuLinks = sequenceUrlLinks.writeUrlsAsString(false); if (nonMenuLinks.isEmpty()) { - Cache.applicationProperties.remove("STORED_LINKS"); + Cache.removePropertyNoSave("STORED_LINKS"); } else { - Cache.applicationProperties.setProperty("STORED_LINKS", - nonMenuLinks.toString()); + Cache.setPropertyNoSave("STORED_LINKS", nonMenuLinks.toString()); } - Cache.applicationProperties.setProperty("DEFAULT_URL", + Cache.setPropertyNoSave("DEFAULT_URL", sequenceUrlLinks.getPrimaryUrlId()); - Cache.applicationProperties.setProperty("USE_PROXY", + Cache.setPropertyNoSave("USE_PROXY", Boolean.toString(useProxy.isSelected())); Cache.setOrRemove("PROXY_SERVER", proxyServerTB.getText()); @@ -784,52 +912,51 @@ public class Preferences extends GPreferences } if (!questionnaire.isSelected()) { - Cache.setProperty("NOQUESTIONNAIRES", "true"); + Cache.setProperty(NOQUESTIONNAIRES, "true"); } else { // special - made easy to edit a property file to disable questionnaires // by just adding the given line - Cache.removeProperty("NOQUESTIONNAIRES"); + Cache.removeProperty(NOQUESTIONNAIRES); } /* * Save Output settings */ - Cache.applicationProperties.setProperty("BLC_JVSUFFIX", + Cache.setPropertyNoSave("BLC_JVSUFFIX", Boolean.toString(blcjv.isSelected())); - Cache.applicationProperties.setProperty("CLUSTAL_JVSUFFIX", + Cache.setPropertyNoSave("CLUSTAL_JVSUFFIX", Boolean.toString(clustaljv.isSelected())); - Cache.applicationProperties.setProperty("FASTA_JVSUFFIX", + Cache.setPropertyNoSave("FASTA_JVSUFFIX", Boolean.toString(fastajv.isSelected())); - Cache.applicationProperties.setProperty("MSF_JVSUFFIX", + Cache.setPropertyNoSave("MSF_JVSUFFIX", Boolean.toString(msfjv.isSelected())); - Cache.applicationProperties.setProperty("PFAM_JVSUFFIX", + Cache.setPropertyNoSave("PFAM_JVSUFFIX", Boolean.toString(pfamjv.isSelected())); - Cache.applicationProperties.setProperty("PILEUP_JVSUFFIX", + Cache.setPropertyNoSave("PILEUP_JVSUFFIX", Boolean.toString(pileupjv.isSelected())); - Cache.applicationProperties.setProperty("PIR_JVSUFFIX", + Cache.setPropertyNoSave("PIR_JVSUFFIX", Boolean.toString(pirjv.isSelected())); - Cache.applicationProperties.setProperty("PIR_MODELLER", + Cache.setPropertyNoSave("PIR_MODELLER", Boolean.toString(modellerOutput.isSelected())); - Cache.applicationProperties.setProperty("EXPORT_EMBBED_BIOJSON", + Cache.setPropertyNoSave("EXPORT_EMBBED_BIOJSON", Boolean.toString(embbedBioJSON.isSelected())); jalview.io.PIRFile.useModellerOutput = modellerOutput.isSelected(); - Cache.applicationProperties.setProperty("FIGURE_AUTOIDWIDTH", + Cache.setPropertyNoSave("FIGURE_AUTOIDWIDTH", Boolean.toString(autoIdWidth.isSelected())); userIdWidth_actionPerformed(); - Cache.applicationProperties.setProperty("FIGURE_FIXEDIDWIDTH", - userIdWidth.getText()); + Cache.setPropertyNoSave("FIGURE_FIXEDIDWIDTH", userIdWidth.getText()); /* * Save Editing settings */ - Cache.applicationProperties.setProperty("AUTO_CALC_CONSENSUS", + Cache.setPropertyNoSave(AUTO_CALC_CONSENSUS, Boolean.toString(autoCalculateConsCheck.isSelected())); - Cache.applicationProperties.setProperty("SORT_BY_TREE", + Cache.setPropertyNoSave(SORT_BY_TREE, Boolean.toString(sortByTree.isSelected())); - Cache.applicationProperties.setProperty("PAD_GAPS", + Cache.setPropertyNoSave(PAD_GAPS, Boolean.toString(padGaps.isSelected())); if (!Platform.isJS()) @@ -837,31 +964,31 @@ public class Preferences extends GPreferences wsPrefs.updateAndRefreshWsMenuConfig(false); } - /* - * Save Backups settings - */ - Cache.applicationProperties.setProperty(BackupFiles.ENABLED, - Boolean.toString(enableBackupFiles.isSelected())); + /* + * Save Backups settings + */ + Cache.setPropertyNoSave(BackupFiles.ENABLED, + Boolean.toString(enableBackupFiles.isSelected())); int preset = getComboIntStringKey(backupfilesPresetsCombo); - Cache.applicationProperties.setProperty(BackupFiles.NS + "_PRESET", Integer.toString(preset)); + Cache.setPropertyNoSave(BackupFiles.NS + "_PRESET", + Integer.toString(preset)); if (preset == BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM) { BackupFilesPresetEntry customBFPE = getBackupfilesCurrentEntry(); BackupFilesPresetEntry.backupfilesPresetEntriesValues.put( BackupFilesPresetEntry.BACKUPFILESSCHEMECUSTOM, customBFPE); - Cache.applicationProperties - .setProperty(BackupFilesPresetEntry.CUSTOMCONFIG, - customBFPE.toString()); + Cache.setPropertyNoSave(BackupFilesPresetEntry.CUSTOMCONFIG, + customBFPE.toString()); } BackupFilesPresetEntry savedBFPE = BackupFilesPresetEntry.backupfilesPresetEntriesValues .get(preset); - Cache.applicationProperties.setProperty( - BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString()); + Cache.setPropertyNoSave(BackupFilesPresetEntry.SAVEDCONFIG, + savedBFPE.toString()); Cache.saveProperties(); - Desktop.instance.doConfigureStructurePrefs(); + Desktop.getInstance().doConfigureStructurePrefs(); try { frame.setClosed(true); @@ -870,6 +997,43 @@ public class Preferences extends GPreferences } } + public static void setAppletDefaults() + { + + // http://www.jalview.org/old/v2_8/examples/appletParameters.html + + // showConservation true or false Default is true. + // showQuality true or false Default is true. + // showConsensus true or false Default is true. + // showFeatureSettings true or false Shows the feature settings window when + // startin + // showTreeBootstraps true or false (default is true) show or hide branch + // bootstraps + // showTreeDistances true or false (default is true) show or hide branch + // lengths + // showUnlinkedTreeNodes true or false (default is false) indicate if + // unassociated nodes should be highlighted in the tree view + // showUnconserved true of false (default is false) When true, only gaps and + // symbols different to the consensus sequence ions of the alignment + // showGroupConsensus true of false (default is false) When true, shows + // consensus annotation row for any groups on the alignment. (since 2.7) + // showGroupConservation true of false (default is false) When true, shows + // amino-acid property conservation annotation row for any groups on the + // showConsensusHistogram true of false (default is true) When true, shows + // the percentage occurence of the consensus symbol for each column as a + // showSequenceLogo true of false (default is false) When true, shows a + // sequence logo above the consensus sequence (overlaid above the Consensus + + Cache.setPropertyNoSave(SHOW_CONSERVATION, "true"); + Cache.setPropertyNoSave(SHOW_QUALITY, "false"); + Cache.setPropertyNoSave(SHOW_CONSENSUS, "true"); + Cache.setPropertyNoSave(SHOW_UNCONSERVED, "false"); + Cache.setPropertyNoSave(SHOW_GROUP_CONSERVATION, "false"); + Cache.setPropertyNoSave(SHOW_GROUP_CONSENSUS, "false"); + + // TODO -- just a start here + } + /** * Do any necessary validation before saving settings. Return focus to the * first tab which fails validation. @@ -894,7 +1058,8 @@ public class Preferences extends GPreferences } /** - * DOCUMENT ME! + * Opens a file browser, and if a file is chosen, sets its path as the text of + * the 'startup file' text field */ @Override public void startupFileTextfield_mouseClicked() @@ -914,8 +1079,10 @@ public class Preferences extends GPreferences FileFormatI format = chooser.getSelectedFormat(); if (format != null) { - Cache.applicationProperties.setProperty("DEFAULT_FILE_FORMAT", - format.getName()); + /* + * saving properties to file is deferred to the 'OK' action + */ + Cache.setPropertyNoSave("DEFAULT_FILE_FORMAT", format.getName()); } startupFileTextfield .setText(chooser.getSelectedFile().getAbsolutePath()); @@ -972,7 +1139,7 @@ public class Preferences extends GPreferences boolean valid = false; while (!valid) { - if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link, + if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link, MessageManager.getString("label.new_sequence_url_link"), JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION) @@ -1024,7 +1191,7 @@ public class Preferences extends GPreferences boolean valid = false; while (!valid) { - if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link, + if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link, MessageManager.getString("label.edit_sequence_url_link"), JvOptionPane.OK_CANCEL_OPTION, -1, null) == JvOptionPane.OK_OPTION) @@ -1111,6 +1278,11 @@ public class Preferences extends GPreferences super.showunconserved_actionPerformed(e); } + /** + * not implemented -- returns empty list + * + * @return + */ public static List getGroupURLLinks() { return groupURLLinks; @@ -1197,7 +1369,7 @@ public class Preferences extends GPreferences } catch (NumberFormatException x) { userIdWidth.setText(""); - JvOptionPane.showInternalMessageDialog(Desktop.desktop, + JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), MessageManager .getString("warn.user_defined_width_requirements"), MessageManager.getString("label.invalid_id_column_width"), @@ -1216,14 +1388,14 @@ public class Preferences extends GPreferences * Returns true if chimera path is to a valid executable, else show an error * dialog. */ - private boolean validateChimeraPath() + protected boolean validateChimeraPath() { if (chimeraPath.getText().trim().length() > 0) { File f = new File(chimeraPath.getText()); if (!f.canExecute()) { - JvOptionPane.showInternalMessageDialog(Desktop.desktop, + JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), MessageManager.getString("label.invalid_chimera_path"), MessageManager.getString("label.invalid_name"), JvOptionPane.ERROR_MESSAGE); @@ -1262,7 +1434,7 @@ public class Preferences extends GPreferences if (!found) { String[] options = { "OK", "Help" }; - int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop, + int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(), JvSwingUtils.wrapTooltip(true, MessageManager.getString("label.chimera_missing")), "", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE, @@ -1335,7 +1507,7 @@ public class Preferences extends GPreferences } } - private class UrlListSelectionHandler implements ListSelectionListener + protected class UrlListSelectionHandler implements ListSelectionListener { @Override @@ -1343,36 +1515,40 @@ public class Preferences extends GPreferences { ListSelectionModel lsm = (ListSelectionModel) e.getSource(); - int index = lsm.getMinSelectionIndex(); - if (index == -1) - { - // no selection, so disable delete/edit buttons - editLink.setEnabled(false); - deleteLink.setEnabled(false); - return; - } - int modelIndex = linkUrlTable.convertRowIndexToModel(index); + updateValueChanged(lsm.getMinSelectionIndex()); + } + } - // enable/disable edit and delete link buttons - if (((UrlLinkTableModel) linkUrlTable.getModel()) - .isRowDeletable(modelIndex)) - { - deleteLink.setEnabled(true); - } - else - { - deleteLink.setEnabled(false); - } + public void updateValueChanged(int index) + { + if (index == -1) + { + // no selection, so disable delete/edit buttons + editLink.setEnabled(false); + deleteLink.setEnabled(false); + return; + } + int modelIndex = linkUrlTable.convertRowIndexToModel(index); - if (((UrlLinkTableModel) linkUrlTable.getModel()) - .isRowEditable(modelIndex)) - { - editLink.setEnabled(true); - } - else - { - editLink.setEnabled(false); - } + // enable/disable edit and delete link buttons + if (((UrlLinkTableModel) linkUrlTable.getModel()) + .isRowDeletable(modelIndex)) + { + deleteLink.setEnabled(true); + } + else + { + deleteLink.setEnabled(false); + } + + if (((UrlLinkTableModel) linkUrlTable.getModel()) + .isRowEditable(modelIndex)) + { + editLink.setEnabled(true); + } + else + { + editLink.setEnabled(false); } } } diff --git a/src/jalview/io/BackupFiles.java b/src/jalview/io/BackupFiles.java index 06c2fc9..1abe4d7 100644 --- a/src/jalview/io/BackupFiles.java +++ b/src/jalview/io/BackupFiles.java @@ -518,7 +518,7 @@ public class BackupFiles MessageManager.getString("label.delete"), MessageManager.getString("label.rename") }; - confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop, + confirmButton = JvOptionPane.showOptionDialog(Desktop.getDesktop(), messageSB.toString(), MessageManager.getString("label.backupfiles_confirm_delete"), JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE, @@ -538,7 +538,7 @@ public class BackupFiles MessageManager.getString("label.delete"), MessageManager.getString("label.keep") }; - confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop, + confirmButton = JvOptionPane.showOptionDialog(Desktop.getDesktop(), messageSB.toString(), MessageManager.getString("label.backupfiles_confirm_delete"), JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE, @@ -573,7 +573,7 @@ public class BackupFiles Long.toString(df.length()) })); } - int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop, + int confirmButton = JvOptionPane.showConfirmDialog(Desktop.getDesktop(), messageSB.toString(), MessageManager .getString("label.backupfiles_confirm_delete"), @@ -662,7 +662,7 @@ public class BackupFiles "label.backupfiles_confirm_save_new_saved_file_not_ok")); } - int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop, + int confirmButton = JvOptionPane.showConfirmDialog(Desktop.getDesktop(), messageSB.toString(), MessageManager .getString("label.backupfiles_confirm_save_file"), diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java index 6de3888..a59d62f 100755 --- a/src/jalview/jbgui/GPreferences.java +++ b/src/jalview/jbgui/GPreferences.java @@ -180,6 +180,8 @@ public class GPreferences extends JPanel protected JComboBox structViewer = new JComboBox<>(); + protected JTextField structureDimensions = new JTextField(); + protected JTextField chimeraPath = new JTextField(); protected ButtonGroup mappingMethod = new ButtonGroup(); @@ -1289,6 +1291,7 @@ public class GPreferences extends JPanel structViewer.addItem(ViewerType.JMOL.name()); structViewer.addItem(ViewerType.CHIMERA.name()); structViewer.addActionListener(new ActionListener() + { @Override public void actionPerformed(ActionEvent e) @@ -1299,6 +1302,20 @@ public class GPreferences extends JPanel }); structureTab.add(structViewer); + // BH 2019.07.12 + ypos += lineSpacing; + JLabel dimLabel = new JLabel(); + dimLabel.setFont(new java.awt.Font("SansSerif", 0, 11)); + dimLabel.setHorizontalAlignment(SwingConstants.LEFT); + dimLabel.setText( + MessageManager.getString("label.structure_dimensions")); + dimLabel.setBounds(new Rectangle(10, ypos, 140, height)); + structureTab.add(dimLabel); + + structureDimensions.setFont(LABEL_FONT); + structureDimensions.setBounds(new Rectangle(160, ypos, 120, height)); + structureTab.add(structureDimensions); + ypos += lineSpacing; JLabel pathLabel = new JLabel(); pathLabel.setFont(new java.awt.Font("SansSerif", 0, 11)); @@ -1603,11 +1620,17 @@ public class GPreferences extends JPanel fontLabel.setHorizontalAlignment(SwingConstants.RIGHT); fontLabel.setText(MessageManager.getString("label.font")); fontSizeCB.setFont(LABEL_FONT); - fontSizeCB.setBounds(new Rectangle(320, 112, 65, 23)); + fontSizeCB.setBounds(new Rectangle(320, 115, 65, 23)); // BH 2019.09.24 y + // added 3 pixels for + // Java/Windows fontStyleCB.setFont(LABEL_FONT); - fontStyleCB.setBounds(new Rectangle(382, 112, 80, 23)); + fontStyleCB.setBounds(new Rectangle(382, 115, 80, 23)); // BH 2019.09.24 y + // added 3 pixels + // for Java/Windows fontNameCB.setFont(LABEL_FONT); - fontNameCB.setBounds(new Rectangle(172, 112, 147, 23)); + fontNameCB.setBounds(new Rectangle(172, 115, 147, 23)); // BH 2019.09.24 y + // added 3 pixels + // for Java/Windows gapSymbolCB.setFont(LABEL_FONT); gapSymbolCB.setBounds(new Rectangle(172, 215, 69, 23)); DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); @@ -1652,7 +1675,18 @@ public class GPreferences extends JPanel sortAutocalc.setBounds(new Rectangle(290, 285, 165, 21)); JPanel annsettingsPanel = new JPanel(); - annsettingsPanel.setBounds(new Rectangle(173, 13, 320, 96)); + annsettingsPanel.setBounds(new Rectangle(173, 13, 330, 100)); // BH + // 2019.09.24 + // SwingJS + // needs a few + // more + // pixels. + // Java needs + // a bit more + // in height + // on Windows + // OS + // Was 320, 96 annsettingsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); annsettingsPanel.setBorder(new EtchedBorder()); visualTab.add(annsettingsPanel); @@ -2056,12 +2090,12 @@ public class GPreferences extends JPanel backupsSetOptions( BackupFilesPresetEntry.backupfilesPresetEntriesValues .get(key)); - } - else - { + } + else + { Cache.log.error( "Preset '" + value + "' [key:" + key + "] not implemented"); - } + } // Custom options will now be enabled when the customiseCheckbox is checked // (performed above) @@ -2078,7 +2112,7 @@ public class GPreferences extends JPanel e = (IntKeyStringValueEntry) backupfilesPresetsCombo2 .getSelectedItem(); } catch (Exception ex) - { + { Cache.log.error( "Problem casting Combo entry to IntKeyStringValueEntry."); e = null; @@ -2097,7 +2131,7 @@ public class GPreferences extends JPanel { e = (IntKeyStringValueEntry) backupfilesPresetsCombo2.getItemAt(i); } catch (Exception ex) - { + { Cache.log.error( "Problem casting Combo entry to IntKeyStringValueEntry. Skipping item. "); continue; @@ -2256,7 +2290,7 @@ public class GPreferences extends JPanel boolean ret = false; String warningMessage = MessageManager .getString("label.warning_confirm_change_reverse"); - int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop, + int confirm = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(), warningMessage, MessageManager.getString("label.change_increment_decrement"), JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);