web-dev-qa-db-fra.com

JavaFX: bordure rouge pour le champ de texte

J'ai un formulaire avec des champs de texte et je veux leur donner une bordure rouge si je clique sur "enregistrer" mais par exemple rien n'a été entré dans les champs obligatoires, les lettres pour le champ "anniversaire", ....

Mes fichiers: EditController.Java, error.css

J'ai déjà essayé:

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

, pour le supprimer s'ils saisissent quelque chose de valide:

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

et dans le css:

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

Mais cela n'a rien changé.

Étonnamment,

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

(et une chaîne vide pour s'en débarrasser) fonctionne très bien mais ce n'est pas "joli" si je veux en ajouter plus tard.

Est-ce que quelqu'un sait comment réparer le CSS?

13
Neph

Avec cela, cela fonctionne parfaitement bien (il n'a même pas besoin de "setUpValidation"):

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"));
}

Et dans le CSS, j'ai ajouté ce qui suit (malheureusement, cela n'a plus changé la largeur de la bordure avec "-fx-border-width: 2px"):

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

Essayer

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

La première définit la couleur de la bordure lorsqu'elle n'est pas mise au point, la seconde lorsqu'elle est mise au point.

Avec cela dans la feuille de style text-field-red-border.css, l'exemple suivant fonctionne:

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);
    }
}

Soit dit en passant, si vous utilisez JavaFX 8, privilégiez les pseudoclasses plutôt que de définir directement la classe, car c'est plus propre (vous n'avez pas besoin de tout le code laid vérifiant que vous n'ajoutez la classe de style qu'une seule fois et/ou supprimez toutes ses occurrences) et plus efficace. Pour définir et désactiver la pseudoclasse, procédez comme suit:

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

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

Ensuite, le CSS doit être

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

(Notez les deux points au lieu du. Entre -text-field et error.)

23
James_D

Lorsque vous utilisez le style javafx8 moderna, vous pouvez utiliser ce CSS pour rendre la bordure similaire à la bordure bleue `` au point '':

.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;
}

ajoutez le css en tant que ressource de chemin de classe et chargez-le en utilisant:

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

puis appliquez-le aux champs de texte en utilisant:

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

La solution mentionnée ci-dessus par James_D fonctionne parfaitement bien (mais pas pour JAVAFX 8.0). James a déjà mentionné les changements de code pour JAVAFX 8.0, je viens de l'essayer et cela fonctionne comme un charme. Voici la version modifiée de JAVAFX 8.0, au cas où quelqu'un aurait besoin d'une référence rapide.Tout le crédit va à 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);
}

}

1
ATHER