JavaFX:文本字段的红色边框

问题描述:

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

I have a form with text fields and I want to give them a red border if I click on "save" but e.g. nothing was input in required fields, letters for the "birthday" field,... .

我的文件:
EditController.java,error.css

My files: EditController.java, error.css

我已经尝试过:

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

,若要输入有效内容,请将其删除:

, to remove it if they enter something valid:

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

和css:

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

但它没有改变任何东西。

But it didn't change anything.

令人惊讶的是,

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

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

(and an empty string to get rid of it) works just fine but it isn't "pretty" if I want to add more to it later.

有谁知道如何解决这个问题?

Does anyone know how to fix the css?

尝试

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

第一个设置未聚焦的边框颜色,第二个设置时是焦点。

The first sets the border color when it's not focussed, the second when it is focussed.

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

With this in the stylesheet text-field-red-border.css, the following example works:

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,喜欢伪类而不是直接设置类,因为它更干净(你不需要所有丑陋的代码检查,你只需要添加一次样式类和/或删除所有出现的类)并且效率更高。要设置和取消设置伪类,请执行以下操作:

By the way, if you are using JavaFX 8, favor pseudoclasses over setting the class directly, as it's cleaner (you don't need all the ugly code checking that you only add the style class once and/or remove all occurrences of it) and more efficient. To set and unset the pseudoclass do:

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-field 和错误。)

(Note the colon instead of the . between -text-field and error.)