0

我想实现这个验证器:

http://dev-fjord.blogspot.com/2012/11/javafx-field-validation.html

我创建TextField了我想用来验证端口号的:

TextField pwBox = new TextField();

        ErrorValidator<String> idValidator = new ErrorValidator<>(pwBox.textProperty(), new ITypeValidator<String>()
        {
            @Override
            public ErrorValidator.State validate(String typeToValidate)
            {
                // Whatever validation code is required
                int occurences = countOccurences(typeToValidate, '!');
                if (occurences == 0)
                {
                    return State.VALID;
                }
                else if (occurences < 3)
                {
                    return State.WARNING;
                }
                else
                {
                    return State.ERROR;
                }
            }
        }, ErrorValidator.State.VALID);

        Text idErrorLabel = null;
        idValidator.addStyleTargets(idErrorLabel, pwBox);

        idValidator.stateProperty().addListener(new ChangeListener<State>()
        {
            @Override
            public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue)
            {
                switch (newValue)
                {
                    case ERROR:
                        idErrorLabel.setText("Too many Exclamation Marks!!!");
                        break;
                    case WARNING:
                        idErrorLabel.setText("Be careful not to use too many Exclamation Marks!!!");
                        break;
                }
            }
        });

        grid.add(pwBox, 1, 2);

验证器:

import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;

/**
 * Class for giving visual feedback about the validation state of {@link ObservableValue}s.
 *
 * @param <T> The type that is validated
 */
public class ErrorValidator<T>
{
    private static final String BASE_STYLE = "validated";

    public static enum State
    {
        VALID("validation_valid"), WARNING("validation_warning"), ERROR("validation_error");

        public final String style;

        private State(String style)
        {
            this.style = style;
        }
    }

    private final List<Node> styleTargets = new ArrayList<>();
    private ObjectProperty<State> state = new SimpleObjectProperty<>(State.VALID);

    /**
     * Initializes this {@link ErrorValidator} with a state that can be different from the actual validation result.
     *
     * @param property
     * @param validator
     * @param initState
     */
    public ErrorValidator(final ObservableValue<? extends T> property, final ITypeValidator<? super T> validator, State initState)
    {
        //Preconditions.checkNotNull(initState, "The state may not be null!");
        state.set(initState);

        property.addListener(new ChangeListener<T>()
        {
            @Override
            public void changed(ObservableValue<? extends T> observable, T oldValue, T newValue)
            {
                setState(validator.validate(newValue));
            }
        });
    }

    /**
     * Initializes this {@link ErrorValidator} with a state depending on the current validation result.
     *
     * @param property
     * @param validator
     */
    public ErrorValidator(final ObservableValue<? extends T> property, final ITypeValidator<? super T> validator)
    {
        this(property, validator, validator.validate(property.getValue()));
    }

    private void setState(State newState)
    {
        if (state.get() == newState)
        {
            return;
        }
        //Preconditions.checkNotNull(newState, "The state may not be null!");

        for (Node node : styleTargets)
        {
            node.getStyleClass().remove(state.get().style);
            node.getStyleClass().add(newState.style);
        }

        this.state.set(newState);
    }

    /**
     * Adds a new {@link Node} that should receive styleclasses depending of the validation state of this validator.
     *
     * @param node
     */
    public void addStyleTarget(Node node)
    {
        styleTargets.add(node);
        node.getStyleClass().add(state.get().style);
        node.getStyleClass().add(BASE_STYLE);
    }

    /**
     * Adds new {@link Node}s that should receive styleclasses depending of the validation state of this validator.
     *
     * @param nodes
     */
    public void addStyleTargets(Node... nodes)
    {
        for (Node node : nodes)
        {
            addStyleTarget(node);
        }
    }

    public ReadOnlyObjectProperty<State> stateProperty()
    {
        return state;
    }
}

界面:

public interface ITypeValidator<T>
{
    ErrorValidator.State validate(T typeToValidate);
}

由于某种原因,当我启动应用程序并使用验证器打开包含输入字段的窗口时,该窗口未打开。我有一个找不到的 Java 代码错误。Netbeans 中没有错误消息。你能帮我找出问题吗?

4

1 回答 1

2

快速尝试一下,这条线

    node.getStyleClass().add(state.get().style);

addStyleTarget(Node node)抛出一个NullPointerException。但也许这是因为我不完全了解您的主要应用程序类。

于 2013-11-09T14:12:45.313 回答