2017-01-06 4 views
1

je dois limiter l'intervalle de la propriété de texte d'un champ texteJavaFX: TextField max et la valeur min par auditeur

int maxLength = 64; 
    int minLength = 0; 
    txtSeuil.textProperty().addListener((v, oldValue, newValue) -> { 
     if (!newValue.matches("\\d*")) { 
      txtSeuil.setText(newValue.replaceAll("[^\\d*{1,2}]", "")); 
      if (txtSeuil.getText().length() > maxLength || txtSeuil.getText().length() < minLength) { 
       String s = txtSeuil.getText().substring(0, maxLength); 
       txtSeuil.setText(s); 
      } 
     } 

    }); 

le champ n'accepte des chiffres, mais un nombre, non seulement les valeurs d'intervalle

Répondre

1

Si je comprends correctement, vous essayez d'implémenter un champ de nombre qui autorise uniquement les valeurs dans l'intervalle [0, 64]. Selon this answer, TextFormatter est la manière recommandée d'accomplir une telle fonctionnalité. Jetez un oeil à ce MWE qui devrait résoudre votre problème:

public class RestrictedNumberFieldDemo extends Application { 

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

    @Override 
    public void start(Stage primaryStage) { 
     TextField numField = new TextField(); 
     numField.setTextFormatter(new TextFormatter<Integer>(change -> { 
      // Deletion should always be possible. 
      if (change.isDeleted()) { 
       return change; 
      } 

      // How would the text look like after the change? 
      String txt = change.getControlNewText(); 

      // There shouldn't be leading zeros. 
      if (txt.matches("0\\d+")) { 
       return null; 
      } 

      // Try parsing and check if the result is in [0, 64]. 
      try { 
       int n = Integer.parseInt(txt); 
       return 0 <= n && n <= 64 ? change : null; 
      } catch (NumberFormatException e) { 
       return null; 
      } 
     })); 

     primaryStage.setScene(new Scene(numField)); 
     primaryStage.show(); 
    } 

} 
2

Pour résoudre votre problème, vous pouvez mettre en œuvre personnalisé Filter pour TextFormatter. Cela permettra d'entrer des nombres seulement et de restreindre la longueur de la chaîne. Voici snippet qui montre comment il peut: travaux

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.stage.Stage; 

public class Main5 extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     TextField textField = new TextField(); 
     textField.setTextFormatter(new TextFormatter<Integer>(change -> { 
      if (!change.getText().isEmpty()) { 
       return change.getText().matches("\\d+") && change.getControlNewText().length() <= 5 ? change : null; 
      } 

      return change; 
     })); 

     primaryStage.setScene(new Scene(textField)); 
     primaryStage.show(); 
    } 
} 
+0

grâce, il travaille pour la longueur mais je fait une erreur sur le code, valeurmin et maxValue que je veux ne sont pas pour la valeur de longueur, mais vor la valeur du texte, alors comment puis-je résoudre ce problème? – devhicham

+0

@devhicham Qu'entendez-vous par "valeur de texte"? Seuls les numéros de 0 à 64? – beatngu13

+0

@ beatngu13 oui s'il vous plaît, je veux que le champ n'accepte que les numéros d'intervalle de 0 à 64 – devhicham

0

Votre problème est:

Le contrôle de longueur ne se fait pas, si les matchs regex. Mais le texte peut être une séquence de chiffres et être long.

Vous devez effectuer ces vérifications indépendamment les unes des autres.

De même, dans certains cas, vous définissez une nouvelle valeur qui déclenche à nouveau les mêmes vérifications. Bien sûr, ils entraîneront les String étant évaluée comme une entrée valide, mais vous pouvez éviter de vérifier à nouveau par l'introduction d'un champ dans la ChangeListener que les magasins, si l'auditeur est actuellement en cours d'exécution:

txtSeuil.textProperty().addListener(new ChangeListener<String>() { 

    private boolean validating = false; 

    @Override 
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
     if (!validating) { 
      validating = true; 
      String newText = newValue; 
      boolean modify = false; 
      if (!newValue.matches("\\d*")) { 
       newText = newValue.replaceAll("[^\\d*{1,2}]", ""); 
       modify = true; 
      } 
      if (newText.length() > maxLength || newText.length() < minLength) { 
       newText = newText.substring(0, maxLength); 
       modify = true; 
      } 
      if (modify) { 
       txtSeuil.setText(newText); 
      } 
      validating = false; 
     } 
    } 
});