加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

javafx-2 – JavaFX 2.2 FXML Validated TextField

发布时间:2020-12-14 19:24:12 所属栏目:Java 来源:网络整理
导读:我改进了我以前的TextField验证实现,这次使用绑定进行实时验证的真正自定义控件.它可以与F XML一起使用而无需更多的 Java代码. import javafx.beans.binding.BooleanBinding;import javafx.beans.property.BooleanProperty;import javafx.beans.property.Int
我改进了我以前的TextField验证实现,这次使用绑定进行实时验证的真正自定义控件.它可以与F XML一起使用而无需更多的 Java代码.
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.TextField;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.paint.Color;

/**
 * <p>
 * TextField with regex-based real-time input validation.
 * JavaFX 2 and FXML compatible. </p>
 * <p>
 * FXML code example:<div>
 *  {@code <ValidatedTextField fx:id="validatedTextField" minLength="1" maxLength="1" mask="^[0-9]*$" />}
 * </div>
 * </p>
 * 
 * @author 82300009
 */
public final class ValidatedTextField extends TextField {

    private final BooleanProperty invalid = new SimpleBooleanProperty(false);
    private final StringProperty mask;
    private final IntegerProperty minLength;
    private final IntegerProperty maxLength;

    private Effect invalidEffect = new DropShadow(BlurType.GAUSSIAN,Color.RED,4,0.0,0);

    public ValidatedTextField() {
        super();
        this.mask = new SimpleStringProperty(".");
        this.minLength = new SimpleIntegerProperty(-1);
        this.maxLength = new SimpleIntegerProperty(-1);

        bind();
    }

    public ValidatedTextField(String mask,int minLength,int maxLength,boolean nullable) {
        this(mask,minLength,maxLength,nullable,null);
    }

    public ValidatedTextField(String mask,boolean nullable,String string) {
        super(string);
        this.mask = new SimpleStringProperty(mask);
        this.minLength = new SimpleIntegerProperty(minLength);
        this.maxLength = new SimpleIntegerProperty(maxLength);

        bind();
    }

    public ReadOnlyBooleanProperty invalidProperty() {
        return invalid;
    }

    public ReadOnlyStringProperty maskProperty() {
        return mask;
    }

    public ReadOnlyIntegerProperty minLengthProperty() {
        return minLength;
    }

    public ReadOnlyIntegerProperty maxLengthProperty() {
        return maxLength;
    }

    public boolean getInvalid() {
        return invalid.get();
    }

    public String getMask() {
        return mask.get();
    }

    public void setMask(String mask) {
        this.mask.set(mask);
    }

    public int getMinLength() {
        return minLength.get();
    }

    public void setMinLength(int minLength) {
        this.minLength.set(minLength);
    }

    public int getMaxLength() {
        return maxLength.get();
    }

    public void setMaxLength(int maxLength) {
        this.maxLength.set(maxLength);
    }

    public Effect getInvalidEffect() {
        return this.invalidEffect;
    }

    public void setInvalidEffect(Effect effect) {
        this.invalidEffect = effect;
    }

    private void bind() {
        this.invalid.bind(maskCheck().or(minLengthCheck()));

        this.textProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> ov,String t,String t1) {
                if (textProperty().get().length() > maxLength.get()) {
                    setText(t);
                }
            }
        });

        this.invalid.addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> ov,Boolean t,Boolean t1) {
                if (t ^ t1) {
                    if (t1) {
//                        setStyle("-fx-font-weight: bold; -fx-text-fill: red;");
                        setEffect(invalidEffect);
                    } else {
//                        setStyle("-fx-font-weight: normal; -fx-text-fill: inherit;");
                        setEffect(null);
                    }
                }

            }
        });
    }

    private BooleanBinding maskCheck() {
        return new BooleanBinding() {
            {
                super.bind(textProperty(),mask);
            }

            @Override
            protected boolean computeValue() {
                return !textProperty().get().matches(mask.get());
            }
        };
    }

    private BooleanBinding minLengthCheck() {
        return new BooleanBinding() {
            {
                super.bind(textProperty(),minLength);
            }

            @Override
            protected boolean computeValue() {
                return textProperty().get().length() < minLength.get();
            }
        };
    }

    private BooleanBinding maxLengthCheck() {
        return new BooleanBinding() {
            {
                super.bind(textProperty(),maxLength);
            }

            @Override
            protected boolean computeValue() {
                return textProperty().get().length() > maxLength.get();
            }
        };
    }
}

然而,关于“无效”图形效果仍有一个微不足道的观点.
正如你在这里看到的:

this.invalid.addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> ov,Boolean t1) {
                if (t ^ t1) {
                    if (t1) {
//                        setStyle("-fx-font-weight: bold; -fx-text-fill: red;");
                        setEffect(invalidEffect);
                    } else {
//                        setStyle("-fx-font-weight: normal; -fx-text-fill: inherit;");
                        setEffect(null);
                    }
                }

            }
        });

我尝试使用setStyle,但使用-fx-font-weight:inherit;打破代码(不要为什么因为它应该是它的默认值).注入StyleClass不起作用,因为当invalid为false时我无法恢复它.

任何线索?当然可以分离内部监听器并将另一个外部与其他效果连接(f.i.显示绿色勾号而不是改变TextField效果).

如果你介意,你可以自由使用代码:)

解决方法

您始终可以通过从样式列表中删除样式来恢复样式,即
node.getStyleClass().remove("my-style");

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读