All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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