Class AppProperties<T extends AppExtension>
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 older releases of swing-extras (1.8 and prior), 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.
Customizing the generated PropertiesDialog
When you invoke showPropertiesDialog(), this class will generate a default PropertiesDialog
for you, and then show it to the user. But what if you want to customize
the generated dialog before it's shown to the user? For example, you might want to make
it larger than the default size, or add extra padding around the FormPanels, or customize
the ActionPanel if it's an ActionPanelPropertiesDialog. You can do all of that by
overriding the propertiesDialogCreated() method, which is invoked after the dialog is created but before
it's shown to the user.
Refer to the swing-extras documentation for more information on how AppProperties works, and how applications can take full advantage of its features!
- Since:
- swing-extras 1.8, 2024-12-30
- Author:
- scorbo2
-
Field Summary
Fields -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAppProperties(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. -
Method Summary
Modifier and TypeMethodDescriptionprotected abstract List<AbstractProperty> Override this to specify whatever properties your application needs.Allows direct access to the underlying PropertiesManager, in case you need to interact directly with it (for example, to invoke generateUnrenderedFormPanels()).booleanisExtensionEnabled(String extName, boolean defaultValue) Reports whether the named extension is currently enabled.voidload()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().static StringOffers a peek directly into the given props file without going through the usual loading mechanism.protected voidSubclasses can override this method to make adjustments to the PropertiesDialog after it's created, but before it's shown to the user.voidRe-initializes the underlying PropertiesManager instance from scratch.voidsave()If you have specific extra 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.voidsetExtensionEnabled(String extName, boolean value) Enables or disables the specified extension.booleanshowExtensionDialog(Window owner) Generates and shows an ExtensionManagerDialog to allow the user to view all currently loaded extensions, and to enable or disable them.booleanshowExtensionDialog(Window owner, UpdateManager updateManager) Generates and shows an ExtensionManagerDialog to allow the user to view all currently loaded extensions, and to enable or disable them.booleanshowPropertiesDialog(Frame owner) Generates and shows a PropertiesDialog to allow the user to view or change any of the current properties.booleanshowPropertiesDialog(Frame owner, Alignment alignment) Generates and shows a PropertiesDialog to allow the user to view or change any of the current properties.
-
Field Details
-
propsManager
-
extManager
-
-
Constructor Details
-
AppProperties
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
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, an 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 extra 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.But consider adding non-exposed properties for this purpose instead:
IntegerProperty windowWidth = new IntegerProperty("window.width", "Window width",800); IntegerProperty windowHeight = new IntegerProperty("window.height", "Window height",600); windowWidth.setExposed(false); // prevents showing in PropertiesDialog windowHeight.setExposed(false); // prevents showing in PropertiesDialogThat way, your non-exposed properties will be loaded and saved automatically via the normal mechanism, while still being hidden from the user in the PropertiesDialog. And, you would no longer need to override this method.
-
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
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.Note: Descendant classes can customize the PropertiesDialog before it is shown to the user! See the propertiesDialogCreated() method for details.
- 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
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.Note: Descendant classes can customize the PropertiesDialog before it is shown to the user! See the propertiesDialogCreated() method for details.
- 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!
-
propertiesDialogCreated
Subclasses can override this method to make adjustments to the PropertiesDialog after it's created, but before it's shown to the user. For example:@Override protected void propertiesDialogCreated(PropertiesDialog dialog) { dialog.setSize(800, 600); // make larger than default dialog.setMinimumSize(new Dimension(600, 400)); // but not smaller than this dialog.setBorderMargin(20); // add lots of extra padding around the FormPanels // If we're showing an ActionPanel, we can customize it here: if (dialog instanceof ActionPanelPropertiesDialog) { ActionPanelPropertiesDialog apd = (ActionPanelPropertiesDialog) dialog; apd.getActionPanel().getColorOptions().setFromTheme(ColorTheme.DARK); } }You can also get access to generated FormField instances using PropertiesDialog.findFormField(), if you want to make specific adjustments to the starting state of those form fields. However, it's better practice to add a FormFieldGenerationListener to your AbstractProperty instances for that purpose.
- Parameters:
dialog- The PropertiesDialog that was just created, but has not yet been shown to the user.
-
showExtensionDialog
Generates and shows an ExtensionManagerDialog to allow the user to view all currently loaded extensions, and to enable or disable them.Note: dynamic extension discovery and download will be disabled and hidden. Use showExtensionDialog(Window, UpdateManager) instead if you want this feature.
- 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!
-
showExtensionDialog
Generates and shows an ExtensionManagerDialog to allow the user to view all currently loaded extensions, and to enable or disable them. Additionally, the given UpdateManager will be queried to find and show a list of extensions available for download. The user can download new extensions or update existing ones using the "available" tab on the dialog. -
isExtensionEnabled
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 fully qualified 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
Enables or disables the specified extension. We will also update ExtensionManager, if we have one.- Parameters:
extName- The fully qualified class name of the extension to enable/disablevalue- The new enabled status for that extension.
-
createInternalProperties
Override this to specify whatever properties your application needs. This method will be invoked automatically upon creation, and whenever AppProperties is re-initialized.- Returns:
- A List of zero or more AbstractProperty instances.
-
reinitialize
public void reinitialize()Re-initializes 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. You can invoke it again later if you have manually added, removed, enabled, or disabled extensions, so that the list of properties is fully re-initialized 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.
-