Class AppProperties<T extends AppExtension>

java.lang.Object
ca.corbett.extensions.AppProperties<T>

public abstract class AppProperties<T extends AppExtension> extends Object
This class encapsulates a PropertiesManager and an ExtensionManager together into one handy utility that client projects can use more easily than the old approach of having the client projects maintain these things separately.

Enabling and disabling
Both this class and ExtensionManager have methods for enabling and disabling an extension. But ExtensionManager knows nothing about this class. This class therefore tries to automatically reconcile these status flags across the two classes, and generally you shouldn't need to worry about it. If an extension is enabled or disabled in ExtensionManager, this class will notice the change and will enable or disable all extension properties as needed. This means that you shouldn't see properties from disabled extensions in the PropertiesDialog, but the values for them will still be saved and loaded to the propsFile. When you re-enable an extension, either in this class or in ExtensionManager, then its properties will once again show up in the PropertiesDialog.

Loading and saving
Unlike sc-util 1.8, there's nothing wonky that client apps need to do in order to load AppProperties and Extensions. You can simply invoke load() in this class and it will all just work. Any extensions that were disabled the last time you invoked save() will be correctly loaded in a disabled state - this means that their property values will be loaded correctly, but they won't show up in the PropertiesDialog until the extension is enabled again.

Since:
2024-12-30
Author:
scorbo2
  • Field Details

    • propsManager

      protected PropertiesManager propsManager
    • extManager

      protected final ExtensionManager<T extends AppExtension> extManager
    • propertiesDialogInitialWidth

      protected int propertiesDialogInitialWidth
    • propertiesDialogInitialHeight

      protected int propertiesDialogInitialHeight
    • propertiesDialogMinimumWidth

      protected int propertiesDialogMinimumWidth
    • propertiesDialogMinimumHeight

      protected int propertiesDialogMinimumHeight
  • Constructor Details

    • AppProperties

      protected AppProperties(String appName, File propsFile, ExtensionManager<T> extManager)
      If your application has an ExtensionManager, you can supply it here and this class will handle loading and saving properties for all enabled extensions.
      Parameters:
      appName - The name of this application.
      propsFile - A File in which properties will be stored for this application.
      extManager - An instance of your ExtensionManager implementation.
  • Method Details

    • peek

      public static String peek(File propsFile, String propName)
      Offers a peek directly into the given props file without going through the usual loading mechanism. This allows direct access to properties (in String form only) exactly as they currently exist in the given props file. This can be useful in rare cases where an extension needs to know a property value in order to initialize some other property value. The normal load mechanism prevents this because property values cannot be read until the AppProperties instance is fully initialized, leading to a circular problem.

      If the value does not exist or an error occurs while reading the props file, empty string is returned.

      Parameters:
      propsFile - The properties file to read.
      propName - The fully qualified name of the property in question.
      Returns:
      The raw value in String form as it exists in the props file at the time of this call. May be empty.
    • load

      public void load()
      If you want to take some action after props are loaded (for example, to set window dimensions or other ui state), you can override this method and put your updates AFTER you invoke super load().
    • save

      public void save()
      If you have specific properties you wish to set on save (window dimensions or other variable stuff), you can override this method and invoke super save() AFTER you have updated your property values.
    • getPropertiesManager

      public PropertiesManager getPropertiesManager()
      Allows direct access to the underlying PropertiesManager, in case you need to interact directly with it (for example, to invoke generateUnrenderedFormPanels()).
      Returns:
      The underlying PropertiesManager instance.
    • showPropertiesDialog

      public boolean showPropertiesDialog(Frame owner)
      Generates and shows a PropertiesDialog to allow the user to view or change any of the current properties. If the user okays the dialog, changes are automatically saved.
      Parameters:
      owner - The owning Frame (so we can make the dialog modal to that Frame).
      Returns:
      true if the user OK'd the dialog and changes were made - reload your UI!
    • showPropertiesDialog

      public boolean showPropertiesDialog(Frame owner, Alignment alignment)
      Generates and shows a PropertiesDialog to allow the user to view or change any of the current properties. If the user okays the dialog, changes are automatically saved.
      Parameters:
      owner - The owning Frame (so we can make the dialog modal to that Frame).
      alignment - How the FormPanels should align themselves.
      Returns:
      true if the user OK'd the dialog and changes were made - reload your UI!
    • showExtensionDialog

      public boolean showExtensionDialog(Frame owner)
      Generates and shows an ExtensionManagerDialog to allow the user to view all currently loaded extensions, and to enable or disable them.
      Parameters:
      owner - The owning Frame (so we can make the dialog modal to that Frame).
      Returns:
      true if the user OK'd the dialog and changes were made - reload your UI!
    • isExtensionEnabled

      public boolean isExtensionEnabled(String extName, boolean defaultValue)
      Reports whether the named extension is currently enabled. If no such extension is found, this will return whatever defaultValue you specify. Note: this is shorthand for propsManager.getPropertiesInstance().getBoolean("extension.enabled."+extName, defaultValue);

      Note: enabled status is stored in the ExtensionManager as well as here. In the case of a discrepancy, the ExtensionManager will be considered the source of truth. That means that this method might have the side effect of enabling/disabling an extension here in AppProperties if we check and find that ExtensionManager's answer doesn't match ours.

      Parameters:
      extName - The class name of the extension to check.
      defaultValue - A value to return if the status can't be found.
      Returns:
      Whether the named extension is enabled.
    • setExtensionEnabled

      public void setExtensionEnabled(String extName, boolean value)
      Enables or disables the specified extension. We will also update ExtensionManager, if we have one.
      Parameters:
      extName - The class name of the extension to enable/disable
      value - The new enabled status for that extension.
    • createInternalProperties

      protected abstract List<AbstractProperty> createInternalProperties()
      Override this to specify whatever properties your application needs. This method will be invoked automatically upon creation.
      Returns:
      A List of zero or more AbstractProperty instances.
    • reinitialize

      public void reinitialize()
      Reinitializes the underlying PropertiesManager instance from scratch. This means both invoking our abstract createInternalProperties() method and also interrogating our ExtensionManager to get a list of all extension-supplied properties. This method is invoked automatically on initial creation, but you can invoke it again later if you have manually added, removed, enabled, or disabled extensions, so that the list of properties is fully reinitialized to reflect the new state of things.

      For an example of why you might want to do this, consider an extension that supplies a bunch of options, some of which may appear as selectable options inside our own createInternalProperties(). For example, we have a dropdown of available application themes, but we only have one or two built-in themes. The list of additional themes is extension-supplied. If we disable that extension at runtime, we want to regenerate our combo box (which is created in createInternalProperties()) such that it no longer shows the extension-supplied options. Similarly, when we re-enable that extension later, we need to regenerate that combo box again so that the list of extension-supplied themes once again appear as selectable options.

      Basically, whenever the list of currently loaded and extensions changes, it's a good idea to reinitialize() this class to reflect those changes. (And, of course, to reload your UI, as there may be many other changes throughout your app as a result of enabling or disabling extensions).

      Note this method will end by invoking load() again to pick up whatever values were previously persisted.