Class PropertiesDialog

All Implemented Interfaces:
ImageObserver, MenuContainer, Serializable, Accessible, RootPaneContainer, WindowConstants
Direct Known Subclasses:
ActionPanelPropertiesDialog, TabPanePropertiesDialog

public abstract class PropertiesDialog extends JDialog
PropertiesDialog can display and allow editing of a list of AbstractProperty instances. The design is very flexible, allowing you to use categories and subcategories to organize your properties. There are two basic choices for the layout of this dialog:
  • "Classic" style: this organizes properties into a tabbed pane, with each property category getting its own tab.
  • "Action panel" style: this organizes properties into an ActionPanel on the left for navigation, with subcategories displayed in FormPanels on the right.

PropertiesDialog instances can be created manually, but it's generally better to go through AppProperties for managing your application's properties. The AppProperties class (or an application-specific derived instance) can handle auto-generating the PropertiesDialog for you.

Since:
swing-extras 1.8, 2024-12-30
Author:
scorbo2
See Also:
  • Field Details

  • Constructor Details

    • PropertiesDialog

      protected PropertiesDialog(Window owner, String title, List<AbstractProperty> properties)
      Use the static factory methods to create a new PropertiesDialog instance.
      Parameters:
      owner - The Window that owns this dialog. This is used to center the dialog over the owner.
      title - The title to show in the dialog header.
      properties - The list of properties that this dialog is meant to edit. Ideally, not empty or null.
  • Method Details

    • createClassicDialog

      public static PropertiesDialog createClassicDialog(Window owner, String title, List<AbstractProperty> properties, boolean alwaysShowSubcategoryLabels)
      Creates and returns a "classic"-style PropertiesDialog, where each top-level category is represented as a tab in a tabbed pane, and subcategories are separated by header labels. This was the only style of PropertiesDialog in releases predating 2.8, and is offered here as an option for applications that don't want to switch to the new style.
      Parameters:
      owner - The Window that owns this dialog. This is used to center the dialog over the owner.
      title - The title to show in the dialog header.
      properties - The list of properties that this dialog is meant to edit. Ideally, not empty or null.
      alwaysShowSubcategoryLabels - Whether to show subcategory header labels even in the case where there's only one subcategory for a given category.
      Returns:
      A new PropertiesDialog instance with the "classic" tabbed pane style.
    • createActionPanelDialog

      public static PropertiesDialog createActionPanelDialog(Window owner, String title, List<AbstractProperty> properties, boolean addPanelHeaders)
      Returns a new PropertiesDialog instance with the "action panel" style, where properties are grouped into ActionGroups and laid out in an ActionPanel rather than a tabbed pane. This style was introduced in swing-extras 2.8, but is not mandatory - use createClassicDialog if you want to stick with the old style.

      You can get direct access to the ActionPanel for styling purposes by invoking getActionPanel() on the returned instance, with a class cast:

           PropertiesDialog dialog = PropertiesDialog.createActionPanelDialog(owner, title, properties);
           ActionPanel actionPanel = ((ActionPanelPropertiesDialog)dialog).getActionPanel();
       

      Panel headers - In the ActionPanel style, you have the option to add header labels to each FormPanel. These headers will be generated based on the subcategory name. If your layout is self-explanatory, or you've already added your own LabelProperty instances, you can suppress these auto-generated header labels by setting addPanelHeaders to false.

      Parameters:
      owner - The Window that owns this dialog. This is used to center the dialog over the owner.
      title - The title to show in the dialog header.
      properties - The list of properties that this dialog is meant to edit. Ideally, not empty or null.
      addPanelHeaders - Whether to add header labels to each FormPanel in the ActionPanel.
      Returns:
      A new PropertiesDialog instance with the "action panel" style.
    • setAlignment

      public PropertiesDialog setAlignment(Alignment alignment)
      Sets the preferred FormPanel alignment for all FormPanels on this dialog. Can be invoked either before or after showing the dialog.
      Parameters:
      alignment - The preferred alignment to use for all FormPanels on this dialog. Cannot be null.
      Returns:
      This PropertiesDialog instance, for chaining.
    • setBorderMargin

      public PropertiesDialog setBorderMargin(int margin)
      Sets the preferred border margin for all FormPanels on this dialog. Can be invoked either before or after showing the dialog.
      Parameters:
      margin - The preferred border margin to use for all FormPanels on this dialog. Cannot be negative.
      Returns:
      This PropertiesDialog instance, for chaining.
    • populateFormPanels

      protected abstract void populateFormPanels()
      Subclasses must implement this to populate the formPanels list with the FormPanels to be used in this dialog. You have access to the following class properties:
      • properties: the list of properties that this dialog is meant to edit.
      • categories: the list of categories represented in the properties list.
      • subcategoriesByCategory: a map of category name to list of subcategories for that category.
      • formPanels: the (already created, but empty) List of formPanels to be populated.

      Subclasses can decide how to break up the properties list into FormPanels as they see fit. The simplest example would be to simply put everything inline in one big FormPanel. A smarter example might be to use a tabbed pane with a tab for each category, or an ActionPanel with action groups for each category.

    • initLayout

      protected abstract void initLayout()
      Sets up the layout of this dialog and populates formPanelList with the FormPanels to be used in this dialog. Descendant classes must implement this method. The expectation is that the subclass will populate the BorderLayout.CENTER region, but subclasses are also free to install something else in the NORTH, EAST, or WEST regions if they wish. The SOUTH region is reserved for our button panel.
    • makeFormPanelVisible

      protected abstract void makeFormPanelVisible(FormPanel formPanel)
      This will be invoked by our validation method in the case where a form validation error occurs. Descendant classes must implement this method to make the given FormPanel visible to the user, so that they can see the validation errors and fix them. The details of how to do this will depend on how FormPanels are presented in this dialog, so it is left up to descendant classes.
      Parameters:
      formPanel - The FormPanel that contains validation errors that the user needs to fix.
    • setVisible

      public void setVisible(boolean visible)
      Overridden to update our position if the owner window moves.
      Overrides:
      setVisible in class Dialog
      Parameters:
      visible - Whether to show or hide the dialog.
    • dispose

      public void dispose()
      Overridden so we can dispose our KeyStrokeManager when we're done.
      Overrides:
      dispose in class Window
    • wasOkayed

      public boolean wasOkayed()
      Reports whether this dialog was closed via the OK button, meaning that the form was validated and all values are acceptable.
      Returns:
      true if the form was validated and closed via the OK button, false otherwise.
    • findFormField

      public FormField findFormField(String identifier)
      Returns the FormField with the given identifier if it exists anywhere on this dialog. Note that this method will return the first FormField that it finds with the given identifier. It shouldn't be possible to have multiple FormFields with the same identifier, but if this does happen, then all such fields after the first one found will be ignored by this method.
      Parameters:
      identifier - The string identifier of the field in question.
      Returns:
      A FormField instance representing that field, or null if not found.
    • validateFormAndClose

      protected void validateFormAndClose()
      Invoked by the OK button. Validates all FormPanels, and if any of them fail validation, makes the first one with errors visible.
    • buildButtonPanel

      protected JPanel buildButtonPanel()
      Builds the ok/cancel button panel at the bottom. Currently not configurable.