
com.pekinsoft.validation.ui.GroupValidator Maven / Gradle / Ivy
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License. When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/
package com.pekinsoft.validation.ui;
import com.pekinsoft.validation.Problems;
/**
* Encapsulates validation of the *combination of several* UI
* components within a {@link ValidationGroup}.
*
* UI-components whose validity depends not only on their own state
* but on the state of each other as well, can be said to have
* validity interdependencies. In such cases not only the state of
* each component needs to be validated as a singular, but the
* combination of components needs to be validated as well.
*
* The following items outline what needs to be done to achieve this.
*
*
*
* - The UI components with interdependencies need to be added to
* the same `ValidationGroup`
*
* - This `ValidationGroup` needs to be prepared at creation time
* with an instance of {@code GroupValidator}.
*
* - In this {@code GroupValidator}, the method {@link
* #performGroupValidation(com.pekinsoft.validation.Problems) }
* needs to be overridden to perform the custom interdependency
* validation.
*
*
*
* When a UI component is changed (either programmatically or by
* having been interacted with by the user) the following will happen:
*
*
*
* - As usual, the UI component will be revalidated using its
* connected validators.
*
* - Now, only if there is no fatal {@link com.pekinsoft.validation.Problem}
* in any of the UI components within the `ValidationGroup`, the validation in
* the {@code GroupValidator} will be invoked as well.
*
* - If it turns out that the latter yields a `Problem` more
* severe (i.e strictly worse) than any other `Problem` in the
* `ValidationGroup`, then this `Problem` will become the
* lead problem in the group.
*
* - The lead problem of the group (whichever it may be) is shown
* as usual in the {@link ValidationUI}(s) of the `ValidationGroup`.
*
* - If the lead `Problem` happens to be the one caused by the
* {@code GroupValidator}, then the default behavior is that this
* `Problem` will cause all UI components within the
* ValidationGroup to be decorated. This behavior can however be
* disabled by passing {@code false} to the constructor {@link
* #GroupValidator(boolean) }
*
*
*
* The following code example illustrates how this class can be
* used.
*
// Given three text fields, aField, bField and cField, this class validates
// that the sum of the numbers in them equals a number given in a combo box.
class SumValidation extends GroupValidator {
SumValidation() {
// The boolean specifies whether a Problem generated by the
// GroupValidator should cause the UI-components in the
// ValidationGroup to be decorated or not
super(true);
}
@Override
protected void performGroupValidation(Problems problems) {
try {
int desiredSum = Integer.parseInt(sumComboBox.getModel().getSelectedItem().toString());
int val1 = Integer.parseInt(aField.getText());
int val2 = Integer.parseInt(bField.getText());
int val3 = Integer.parseInt(cField.getText());
int sum = val1 + val2 + val3;
if (sum != desiredSum) {
problems.add( new Problem (val1 + "+" + val2 + "+" + val3 +
" equals " + sum + ", not " + desiredSum, Severity.FATAL));
} else if (val1 == desiredSum || val2 == desiredSum || val3 == desiredSum) {
problems.add( new Problem ("Hey...that's cheating!",
Severity.WARNING) );
}
} catch (NumberFormatException e) {
//do nothing, the other validators would have taken care of the bad entry
}
}
}
// The GroupValidator can be used as follows:
// Create ValidationGroup that will contain UI component with validity
// interdependencies. Pass a GroupValidator -- SumValidation -- to the
// ValidationGroup creator.
SwingValidationGroup bunch = SwingValidationGroup.create(new SumValidation());
// Create a Validator that can be reused for individual validation of
// the three text fields
Validator<String> fieldValidator =
StringValidators.trimString(StringValidators.REQUIRE_NON_EMPTY_STRING,
StringValidators.NO_WHITESPACE,
StringValidators.REQUIRE_VALID_NUMBER,
StringValidators.REQUIRE_VALID_INTEGER,
StringValidators.REQUIRE_NON_NEGATIVE_NUMBER);
bunch.add(aField, fieldValidator);
bunch.add(bField, fieldValidator);
bunch.add(cField, fieldValidator);
// Add the combo box as well so that the additional group
// validation is triggered whenever the combo box is interacted with. Note
// that there are no validators added for the combo box alone. Also, ValidationUI.NoOp.get()
// is passed, so that the combo box will not be decorated when there's a problem.
bunch.add(SwingValidationListenerFactory.createJComboBoxValidationListener(sumComboBox, ValidationUI.NoOp.get()));
*
*
*
* @author Hugo Heden
*/
public abstract class GroupValidator {
private final boolean shallShowProblemInChildrenUIs;
private boolean isCurrentlyLeadingProblem = false;
/**
* Default constructor, calls {@code this(true)}
*/
protected GroupValidator() {
this( true );
}
/**
* @param shallShowProblemInChildrenUIs specifies whether a
* Problem generated by the {@code GroupValidator} (if it happens
* to be the lead `Problem`) should cause the UI-components
* in the `ValidationGroup` to be decorated (showing the
* `Problem`) or not
*/
protected GroupValidator(boolean shallShowProblemInChildrenUIs ) {
this.shallShowProblemInChildrenUIs = shallShowProblemInChildrenUIs;
}
final boolean isCurrentlyLeadingProblem() {
return isCurrentlyLeadingProblem;
}
final void setIsCurrentlyLeadingProblem(boolean isCurrentlyLeadingProblem) {
this.isCurrentlyLeadingProblem = isCurrentlyLeadingProblem;
}
final boolean shallShowProblemInChildrenUIs() {
return shallShowProblemInChildrenUIs;
}
/**
* Validate the state of the combination of the UI components
* within the ValidationGroup. If invalid
* this method shall add one or more `Problem`s to
* the passed list.
*
* @param problems A list of problems.
*/
protected abstract void performGroupValidation(Problems problems);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy