2017-04-21 2 views
0

Lorsque vous tapez MyTextFieldMaxLength2:
a) marque '1' et cliquez sur le numéro 9 => sera remplacé = '9'. .. ok
b) '12' marque et cliquez sur le numéro 9 => rien ne se passeJavaFX: propre TextField avec un maximum de 2 caractères ... ne peut pas remplacer tous les caractères marqués

Comment puis-je obtenir cela même si tous les deux numéros sont marqués, cela est remplacé par un nouveau numéro?

public class MyTextFieldMaxLength2 extends TextField { 

    public boolean ifCondition_validate(String text) { 
     return (getText().length() < 2 || text.equals("")) && text.matches("[0-9]*"); 
    } 


    @Override 
    public void replaceText(int start, int end, String text) { 
     if (ifCondition_validate(text)) { 
      super.replaceText(start, end, text); 
     }  
    } 

    @Override 
    public void replaceSelection(String text) { 
     if (ifCondition_validate(text)) { 
      super.replaceSelection(text); 
     } 
    } 
} 

Répondre

1

Vous pouvez le faire facilement en définissant un TextFormatter sur un champ de texte standard, au lieu de champ de texte subclassing:

TextField textField = new TextField(); 

UnaryOperator<TextFormatter.Change> filter = c -> { 
    String proposedText = c.getControlNewText(); 
    if (proposedText.matches("[0-9]{0,2}")) { 
     return c ; 
    } else { 
     return null ; 
    } 
}; 
textField.setTextFormatter(new TextFormatter<String>(filter)); 
+0

Tout d'abord, merci pour la solution. Je travaille sur une grande application graphique, en utilisant SceneBuilder. J'aime le concept de propres classes TextField avec des propriétés spéciales à construire, puis uniformément sur pour utiliser SceneBuilder. J'espérais qu'il y avait une solution au problème directement dans le MyTextFieldMaxLength2-class , de sorte que la fonctionnalité peut être regroupée proprement dans les classes TextField dérivées. Je vais attendre encore quelques jours peut-être que quelqu'un a une idée. Dans l'autre cas, je prends votre solution. Merci encore. – Sten

+0

@Sten pourquoi n'utilisez-vous pas simplement cette solution dans une sous-classe de champ de texte? –

+0

J'ai abandonné mon idée en utilisant la sous-classe TextField. Je reste avec votre approche directe et n'ai que la méthode de filtrage statique reconstruite. Je dois donc utiliser les méthodes de filtrage, par ex. "filter_onlyMax2Numbers", "filter_only0xOr1xComma" seulement une fois et peut ensuite les utiliser n'importe où dans l'application. C'est comme ça que ça fonctionne très bien. Je vous remercie. – Sten

0

désolé mais dans la sous-classe le limiteur ne fonctionne pas. Je fais quelque chose de mal. J'ai essayé de l'implémenter.

public class MyTextFieldOnlyNumbersAndMaxLength2_v2 extends TextField {  
    private TextField textField = new TextField(); 

    public MyTextFieldOnlyNumbersAndMaxLength2_v2() { 
     super(); 
     textField.setTextFormatter(new TextFormatter<String>(filter)); 
    } 

    UnaryOperator<TextFormatter.Change> filter = c -> { 
     String proposedText = c.getControlNewText(); 
     if (proposedText.matches("[0-9]{0,2}")) { 
      return c ; 
     } else { 
      return null ; 
     } 
    }; 
} 

//for test: 
public class Main extends Application { 
    @Override 
    public void start(Stage stage) { 
     VBox vbox = new VBox(); 
     MyTextFieldOnlyNumbersAndMaxLength2_v2 myTextField = new MyTextFieldOnlyNumbersAndMaxLength2_v2(); 

     myTextField.setOnAction(e -> { 
      System.out.println("input: " + myTextField.getText()); 
     }); 

     vbox.getChildren().add(myTextField); 
     stage.setScene(new Scene(vbox, 500, 200)); 
     stage.show(); 
    } 

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