Class ValidationGroup

java.lang.Object
org.netbeans.validation.api.ui.ValidationItem
org.netbeans.validation.api.ui.ValidationGroup
Direct Known Subclasses:
SwingValidationGroup

public class ValidationGroup extends ValidationItem
A ValidationGroup logically groups a set of GUI-components, such as text fields, lists, tables, comboboxes etc, each validated by one or more validators (such as the built-in ones provided by the framework in StringValidators).

Note: If you are validating Swing components, you will probably want to use SwingValidationGroup which contains convenience add methods for common Swing components, and performs Swing-specific threading correctness checks.

A ValidationGroup is typically associated with a panel containing GUI-components (such as a JPanel or JDialog in Swing). The idea with logically grouping GUI-components (as opposed to treating them completely separately) is to to indicate the most severe Problem in the panel (graded by Severity) -- the "lead problem" of the group -- to the user in various ways. Even if the user happens to currently be interacting with another GUI component that has no error in it, the lead problem of the panel/group will be visible to the user.

If there is more than one Problem that is the most severe (they have equal Severity) in the group of UI-components, then the one in the UI-component that has been most recently interacted with will be the lead problem.

The way for the ValidationGroup to show the lead problem in the UI is by using one or more instances of the ValidationUI interface. ValidationUI instances can be added by client code using the addUI(org.netbeans.validation.api.ui.ValidationUI) method. One ValidationUI instance could indicate the lead problem for example by showing a message in some status bar. Another one could disable some OK-button (which could be suitable if the lead problems has Severity.FATAL) etc. All these ValidationUIs are updated whenever the lead problem of the group changes. If the ValidationGroup contains UI-components whose validity depends not only on their own state but on the state of each other as well, they can be said to have validity interdependencies. In such cases not only the state of each component needs to be validated, but the combination of components as well. This is done by passing a GroupValidator object when creating the ValidationGroup. For more on that, see GroupValidator.

Now, to add a GUI-component to the ValidationGroup, client code would wrap it (together with the desired Validators) into a ValidationListener that is then added to the ValidationGroup using the addItem(org.netbeans.validation.api.ui.ValidationItem, boolean) method. Note that this is the generic but perhaps inconvenient case -- the subclass SwingValidationGroup contains a number of add-methods for convenience, to simplify this procedure for common Swing components.

Each ValidationListener listens to suitable GUI-events (often key-press events or mouse-events). When such an event occurs the ValidationListener will perform revalidation and then notify its parent ValidationGroup so that it can reevaluate its lead problem.

Not only ValidationListener:s can be added to ValidationGroup, but so can other ValdiationGroups as well. (This is the reason why ValidationListener and ValidationGroup share a common superclass, ValidationItem, and that this is the type of the argument of ValidationGroup#add.) This is useful when there are two separate panels with their own ValidationGroups, and one of the panels is (perhaps temporarily) to be embedded into the other. Whenever there is a change in one of the added child ValidationGroup's components, it will drive the UI(s) belonging to the parent group, as well as (optionally) its own. (The latter can be disabled by passing true as second parameter to addItem(org.netbeans.validation.api.ui.ValidationItem, boolean) instead of false

The core functionality of the ValidationGroup with added ValidationItem:s works as follows:

  • When an appropriate change in a UI component occurs, a ValidationListener will observe that and make sure the component is validated (by invoking the Validator(s)) and then decorate the UI component if there is a Problem in it. This is unless the ValidationListener is suspended, in which case nothing at all will happen, see ValidationItem.runWithValidationSuspended(Runnable)
  • The ValidationListener will notify its parent ValidationGroup about the validation. If there was a fatal Problem in that UI component, then this will also become the lead problem of the whole group because it is the most recent of the most severe problems in the groups.
  • If not, the most recent of the most severe of the problems of the UI components in the ValidationGroup will be the lead problem. (This does not involve actual revalidation of these components, the problem that occured when the component last triggered validation is assumed to still be there).
  • When the lead problem of the ValidationGroup has been determined, the showProblem method of the ValidationUI:s of the group will be called. This may for example involve disabling an OK-button if the lead problem is fatal (and enabling it if not) and showing an error message. This is unless this ValidationGroup has been added "with disabled UI" to another ValidationGroup, in which case the Problem will not be shown in the ValidationUI.
  • If this ValidationGroup has been added to another one then the parent is notified. The parent ValidationGroup will then check if its lead problem needs to be updated, update its ValidationUI:s accordingly (unless it has a disabled UI) and notify its parent if there is one -- and so on.
Author:
Tim Boudreau
  • Constructor Details

  • Method Details

    • create

      public static ValidationGroup create(ValidationUI... ui)
      Create a new validation group
      Parameters:
      ui - Zero or more initial UIs which will display errors
      Returns:
      A validation group
    • create

      public static ValidationGroup create(GroupValidator additionalGroupValidation, ValidationUI... ui)
      Create a new validation group
      Parameters:
      additionalGroupValidation -
      ui - Zero or more initial UIs which will display errors
      Returns:
      A validation group
    • add

      @SafeVarargs public final <ComponentType, ValueType> void add(ComponentType comp, Validator<ValueType>... validators)
      Type Parameters:
      ComponentType -
      ValueType -
      Parameters:
      comp -
      validators -
    • add

      public final <ComponentType, ValueType> void add(ComponentType comp, Validator<ValueType> validator)
      Type Parameters:
      ComponentType -
      ValueType -
      Parameters:
      comp -
      validator -
    • decorationFor

      protected <T> ValidationUI decorationFor(T component)
    • addUI

      public final void addUI(ValidationUI ui)
      Add a UI which should be called on validation of this group or any components within it.

      This is useful in the case that you have multiple components which are provided separately and each want to respond to validation problems (for example, one UI controlling a dialog's OK button, another controlling display of error text).

      Parameters:
      ui - An implementation of ValidationUI
    • removeUI

      public final void removeUI(ValidationUI ui)
      Remove a delegate UI which is being controlled by this validation item. Will clear the UI from any Problem as well.
      Parameters:
      ui - The UI
    • addItem

      public final void addItem(ValidationItem validationItem, boolean disableUI)
      Adds a ValidationItem (i.e a ValidationListener or another ValidationGroup) to this ValidationGroup.

      The purpose of being able to disable a ValidationUI is so you can compose together reusable panels which have their own ValidationUI, but only let the outer ValidationUI show the lead problem when one is inside another. Typically, without the ability to turn off the inner panel's ValidationUI, when there's a problem in the inner panel the error message is going to be shown twice -- once at the bottom of the dialog and one in the middle of the screen inside the inner panel -- which would look bad.

      Note that the subclass SwingValidationGroup contains a number of add-methods for convenience, to simplify this procedure for common Swing components

      Parameters:
      validationItem - item to add
      disableUI - indicates that the validation UI of the parent panel should not be notified
    • remove

      public final void remove(ValidationItem validationItem)
      Removes a previously added ValidationItem (i.e a ValidationListener or another ValidationGroup) to this ValidationGroup.

      If the ValidationItem to be removed has the current lead problem of the ValidationGroup, the ValidationGroup will remove that and evaluate a new lead problem

      Parameters:
      validationItem - item to remove