JavaFX:文本字段的红色边框

时间:2014-06-15 16:19:22

标签: text javafx field border

我有一个带有文字字段的表单,如果点击“保存”,我想给它们一个红色边框,例如没有在必填字段中输入任何内容,“生日”字段的字母,......

我的档案: EditController.java,error.css

我已经尝试过:

tfFirstName.getStyleClass().add("error");

,如果他们输入有效的内容,请删除它:

tfFirstName.getStyleClass().remove("error");

并在css中:

.text-field.error {  
 -fx-border-color: red ;  
 -fx-border-width: 2px ;  
}

但它没有改变任何东西。

令人惊讶的是,

tfFirstName.setStyle("-fx-border-color: red ; -fx-border-width: 2px ;");

(以及一个空字符串来摆脱它)工作得很好,但如果我想稍后再添加更多内容,它就不是“漂亮”。

有谁知道如何修复CSS?

4 个答案:

答案 0 :(得分:16)

尝试

.text-field.error {
  -fx-text-box-border: red ;
  -fx-focus-color: red ;
}

第一个在没有聚焦时设置边框颜色,第二个在聚焦时设置。

在样式表text-field-red-border.css中使用此示例,以下示例有效:

import java.util.Collections;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class ValidatingTextFieldExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        GridPane root = new GridPane();
        TextField nameTF = new TextField();
        TextField emailTF = new TextField();

        root.add(new Label("Name:"), 0, 0);
        root.add(nameTF, 1, 0);
        root.add(new Label("Email:"), 0, 1);
        root.add(emailTF, 1, 1);

        setUpValidation(nameTF);
        setUpValidation(emailTF);

        Scene scene = new Scene(root, 250, 150);
        scene.getStylesheets().add(getClass().getResource("text-field-red-border.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void setUpValidation(final TextField tf) { 
        tf.textProperty().addListener(new ChangeListener<String>() {

            @Override
            public void changed(ObservableValue<? extends String> observable,
                    String oldValue, String newValue) {
                validate(tf);
            }

        });

        validate(tf);
    }

    private void validate(TextField tf) {
        ObservableList<String> styleClass = tf.getStyleClass();
        if (tf.getText().trim().length()==0) {
            if (! styleClass.contains("error")) {
                styleClass.add("error");
            }
        } else {
            // remove all occurrences:
            styleClass.removeAll(Collections.singleton("error"));                    
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

顺便说一句,如果您使用的是JavaFX 8,请直接设置类来支持伪类,因为它更干净(您不需要所有丑陋的代码检查,您只需添加样式类一次和/或删除所有实例它的效率更高。设置和取消设置伪类:

final PseudoClass errorClass = PseudoClass.getPseudoClass("error");

tfFirstName.pseudoClassStateChanged(errorClass, true); // or false to unset it

那么css应该是

.text-field:error {
  -fx-text-box-border: red ;
  -fx-focus-color: red ;
}

(请注意冒号而不是-text-fielderror之间的。)

答案 1 :(得分:5)

使用javafx8 moderna样式时,您可以使用此css使边框类似于“焦点上”蓝色边框:

.text-input.error {
    -fx-focus-color: #d35244;
    -fx-faint-focus-color: #d3524422;

    -fx-highlight-fill: -fx-accent;
    -fx-highlight-text-fill: white;
    -fx-background-color:
        -fx-focus-color,
        -fx-control-inner-background,
        -fx-faint-focus-color,
        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);
    -fx-background-insets: -0.2, 1, -1.4, 3;
    -fx-background-radius: 3, 2, 4, 0;
    -fx-prompt-text-fill: transparent;
}

将css添加为classpath资源并使用以下命令加载:

scene.getStylesheets().add(
    getClass().getClassLoader().getResource(<your css resource path>).toString());

然后使用以下方法将其应用于文本字段:

// add error class (red border)
textField.getStyleClass().add("error");
// remove error class (red border)
textField.getStyleClass().remove("error");

答案 2 :(得分:1)

James_D的上述解决方案完美无缺(但不适用于JAVAFX 8.0)。詹姆斯已经提到了JAVAFX 8.0的代码更改,我只是尝试了它,它就像一个魅力。这是JAVAFX 8.0的更改版本,只是因为有人需要快速参考。所有信用都要转到JAMES_D

import java.util.Collections;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class ValidatingTextFieldExample extends Application {
private final PseudoClass errorClass = PseudoClass.getPseudoClass("error");
@Override
public void start(Stage primaryStage) {
    GridPane root = new GridPane();
    TextField nameTF = new TextField();
    TextField emailTF = new TextField();

    root.add(new Label("Name:"), 0, 0);
    root.add(nameTF, 1, 0);
    root.add(new Label("Email:"), 0, 1);
    root.add(emailTF, 1, 1);

    setUpValidation(nameTF);
    setUpValidation(emailTF);

    Scene scene = new Scene(root, 250, 150);
    scene.getStylesheets().add(getClass().getResource("text-field-red-border.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.show();
}

private void setUpValidation(final TextField tf) { 
    tf.textProperty().addListener(new ChangeListener<String>() {

        @Override
        public void changed(ObservableValue<? extends String> observable,
                String oldValue, String newValue) {
            validate(tf);
        }

    });

    validate(tf);
}

private void validate(TextField tf) {
    ObservableList<String> styleClass = tf.getStyleClass();
    if (tf.getText().trim().length()==0) {
        tf.pseudoClassStateChanged(errorClass, true);
    }
    else{
        tf.pseudoClassStateChanged(errorClass, false);
    }

}

public static void main(String[] args) {
    launch(args);
}

}

答案 3 :(得分:0)

有了它,它现在可以很好地工作(它甚至不需要&#34; setUpValidation&#34;):

public void initialize(URL arg0, ResourceBundle arg1) {
    removeRed(tfFirstName);
    removeRed(tfLastName);
}

public void OKButtonClicked() {
    try{
        //also: call validation class here
        removeRed(tfFirstName);
        removeRed(tfLastName);
    } catch(ValidationException e) {
        setRed(tfFirstName);
        setRed(tfLastName);
    }

}

private void setRed(TextField tf) {
    ObservableList<String> styleClass = tf.getStyleClass();

    if(!styleClass.contains("tferror")) {
        styleClass.add("tferror");
    }
}


private void removeRed(TextField tf) {
    ObservableList<String> styleClass = tf.getStyleClass();
    styleClass.removeAll(Collections.singleton("tferror"));
}

在css中,我添加了以下内容(不幸的是,它没有用&#34更改边框宽度; -fx-border-width:2px&#34;不再):

.tferror {  
     -fx-text-box-border: red ;
     -fx-focus-color: red ;   
}