我想控制输入到Javafx TextField中,这样我就只允许输入数字,这样如果超出了最大字符数,那么就不会对文本框进行任何更改。
编辑:根据评论中的建议,我使用了JavaFX项目负责人建议的方法。它可以很好地阻止输入字母。我只是需要它来过滤特殊字符。我尝试将过滤器更改为(text.matchs(“[0-9]”),但不允许输入退格。
edit2:找出特殊字符和长度的过滤器。这是我的最终代码。感谢输入人员。
这是我创建的TextField类:
import javafx.scene.control.TextField;
public class AttributeTextField extends TextField{
public AttributeTextField() {
setMinWidth(25);
setMaxWidth(25);
}
public void replaceText(int start, int end, String text) {
String oldValue = getText();
if (!text.matches("[a-z]") && !text.matches("[\\\\!\"#$%&()*+,./:;<=>?@\\[\\]^_{|}~]+")) {
super.replaceText(start, end, text);
}
if (getText().length() > 2 ) {
setText(oldValue);
}
}
public void replaceSelection(String text) {
String oldValue = getText();
if (!text.matches("[a-z]") && !text.matches("[\\\\!\"#$%&()*+,./:;<=>?@\\[\\]^_{|}~]+")) {
super.replaceSelection(text);
}
if (getText().length() > 2 ) {
setText(oldValue);
}
}
}
注意:我已阅读此帖子What is the recommended way to make a numeric TextField in JavaFX?,此解决方案对我不起作用。它只会在输入数字后被触发。这意味着某人可以在框中键入字母文本,并允许它直到他们将焦点移离文本字段。此外,他们可以输入大于允许数量的数字,但验证不会发生在每个按键上,而是在焦点转移后('更改'事件)。
答案 0 :(得分:8)
最好的方法是:
@FXML
private TextField txt_Numeric;
@FXML
private TextField txt_Letters;
@Override
public void initialize(URL url, ResourceBundle rb) {
/* add Event Filter to your TextFields **************************************************/
txt_Numeric.addEventFilter(KeyEvent.KEY_TYPED , numeric_Validation(10));
txt_Letters.addEventFilter(KeyEvent.KEY_TYPED , letter_Validation(10));
}
/* Numeric Validation Limit the characters to maxLengh AND to ONLY DigitS *************************************/
public EventHandler<KeyEvent> numeric_Validation(final Integer max_Lengh) {
return new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent e) {
TextField txt_TextField = (TextField) e.getSource();
if (txt_TextField.getText().length() >= max_Lengh) {
e.consume();
}
if(e.getCharacter().matches("[0-9.]")){
if(txt_TextField.getText().contains(".") && e.getCharacter().matches("[.]")){
e.consume();
}else if(txt_TextField.getText().length() == 0 && e.getCharacter().matches("[.]")){
e.consume();
}
}else{
e.consume();
}
}
};
}
/*****************************************************************************************/
/* Letters Validation Limit the characters to maxLengh AND to ONLY Letters *************************************/
public EventHandler<KeyEvent> letter_Validation(final Integer max_Lengh) {
return new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent e) {
TextField txt_TextField = (TextField) e.getSource();
if (txt_TextField.getText().length() >= max_Lengh) {
e.consume();
}
if(e.getCharacter().matches("[A-Za-z]")){
}else{
e.consume();
}
}
};
}
/*****************************************************************************************/
祝你好运。
答案 1 :(得分:4)
这是我的aproach,两个事件过滤器,可能是一个,在我的情况下,我在不同的情况下使用它们,这就是为什么有两个。
这是maxValueFilter(在spanglish xD中),这是一个类:
public class FilterMaxValue implements EventHandler<KeyEvent> {
private int maxVal;
public FilterMaxValue (int i) {
this.maxVal= i;
}
public void handle(KeyEvent arg0) {
TextField tx = (TextField) arg0.getSource();
String chara = arg0.getCharacter();
if (tx.getText().equals(""))
return;
Double valor;
if (chara.equals(".")) {
valor = Double.parseDouble(tx.getText() + chara + "0");
} else {
try {
valor = Double.parseDouble(tx.getText() + chara);
} catch (NumberFormatException e) {
//The other filter will prevent this from hapening
return;
}
}
if (valor > maxVal) {
arg0.consume();
}
}
}
另一个事件过滤器(过滤字符),这个是一个方法:
public static EventHandler<KeyEvent> numFilter() {
EventHandler<KeyEvent> aux = new EventHandler<KeyEvent>() {
public void handle(KeyEvent keyEvent) {
if (!"0123456789".contains(keyEvent.getCharacter())) {
keyEvent.consume();
}
}
};
return aux;
}
在您的情况下使用将是:
field.addEventFilter(KeyEvent.KEY_TYPED,
numFilter());
field.addEventFilter(KeyEvent.KEY_TYPED, new FiltroValorMaximo(
99));
答案 2 :(得分:2)
最终解决方案。不允许使用字母和特殊字符并强制执行字符限制。
import javafx.scene.control.TextField;
public class AttributeTextField extends TextField{
public AttributeTextField() {
setMinWidth(25);
setMaxWidth(25);
}
public void replaceText(int start, int end, String text) {
String oldValue = getText();
if (!text.matches("[A-Za-z]") && !text.matches("[\\\\!\"#$%&()*+,./:;<=>?@\\[\\]^_{|}~]+")) {
super.replaceText(start, end, text);
}
if (getText().length() > 2 ) {
setText(oldValue);
}
}
public void replaceSelection(String text) {
String oldValue = getText();
if (!text.matches("[A-Za-z]") && !text.matches("[\\\\!\"#$%&()*+,./:;<=>?@\\[\\]^_{|}~]+")) {
super.replaceSelection(text);
}
if (getText().length() > 2 ) {
setText(oldValue);
}
}
}
答案 3 :(得分:2)
我只是设置'On Key Typed'事件来运行这个小程序:
@FXML public void processKeyEvent(KeyEvent ev) {
String c = ev.getCharacter();
if("1234567890".contains(c)) {}
else {
ev.consume();
}
}
它就像一个冠军!
答案 4 :(得分:2)
我创建了一个可以添加到Java Builder FX的自定义Textfield(使用&#39;导入JAR / FXML文件...&#39;)。
可以设置此TextField
当然可以改进,但它非常有用。 希望这会有所帮助:)
FX Project LimitedTextField 有了这个项目就可以创建出来的'LimitedTextField.jar&#39;要在您的应用程序或java builder FX中导入的文件。
CustomControlExample.java
package limitedtextfield;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class CustomControlExample extends Application {
@Override
public void start(Stage stage) throws Exception {
LimitedTextField customControl = new LimitedTextField();
customControl.setText("Hello!");
stage.setScene(new Scene(customControl));
stage.setTitle("Custom Control");
stage.setWidth(300);
stage.setHeight(200);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
custom_control.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox>
<limitedtextfield.LimitedTextField text="Hello World!"/>
</HBox>
LimitedTextField.java
package limitedtextfield;
import javafx.scene.control.TextField;
public class LimitedTextField extends TextField
{
private String characters;
private int max;
private boolean capital = false;
private boolean space = true;
static public final String CharactersNumbers = "[qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890èéòàùì ]";
static public final String Characters = "[qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNMèéòàùì ]";
static public final String Numbers = "[1234567890 ]";
static public final String NumbersPoint = "[1234567890. ]";
public LimitedTextField(String l){
super();
characters = l;
max=0;
}
public LimitedTextField(){
super();
characters = "";
max=0;
}
public LimitedTextField(String l, int max){
super();
characters = l;
this.max=max;
//System.out.println("Costruttore");
}
public LimitedTextField(int max){
super();
characters = "";
this.max=max;
}
@Override
public void replaceText(int start, int end, String text)
{
if(!characters.equals("")){
if (validateCh(text))
{
text = check(text);
super.replaceText(start, end, text);
if(max>0)
verifyLengh();
}
}else{
text = check(text);
super.replaceText(start, end, text);
if(max>0)
verifyLengh();
}
}
@Override
public void replaceSelection(String text)
{
if(!characters.equals("")){
if (validateCh(text))
{
text = check(text);
super.replaceSelection(text);
if(max>0)
verifyLengh();
}
}else{
text = check(text);
super.replaceSelection(text);
if(max>0)
verifyLengh();
}
}
private boolean validateCh(String text)
{
/*
[abc] Find any of the characters between the brackets
[0-9] Find any of the digits between the brackets
(x|y) Find any of the alternatives separated with |
*/
return ("".equals(text) || text.matches(characters));
}
private void verifyLengh() {
if (getText().length() > max) {
setText(getText().substring(0, max));//use this line if you want to delete the newer characters inserted
//setText(getText().substring(getText().length()-max, getText().length()));//use this line if you want to delete the older characters inserted
positionCaret(max);//set the cursor position
}
}
private String check(String text){
if(capital)
text = text.toUpperCase();
if(!space)
text = text.replace(" ", "");
return text;
}
public void setLimitCharachters(String s){
this.characters = s;
}
public String getLimitCharachters(){
return characters;
}
public void setMaxLenght(int s){
this.max= s;
}
public int getMaxLenght(){
return max;
}
public boolean getCapital(){
return this.capital;
}
public void setCapital(boolean t){
this.capital = t;
}
public boolean getSpace(){
return this.space;
}
public void setSpace(boolean t){
this.space = t;
}
}
使用示例:
MyFxmlApplication.fxml
...
<?import limitedtextfield.*?>
...
<HBox alignment="CENTER_LEFT" spacing="5.0">
<children>
<Label text="Name:" />
<LimitedTextField fx:id="A_Name_S" />
</children>
<FlowPane.margin>
<Insets right="5.0" />
</FlowPane.margin>
</HBox>
...
MyFxmlApplicationController.fxml
...
import limitedtextfield.LimitedTextField;
@FXML
private LimitedTextField A_Name_S;
...
@Override
public void initialize(URL url, ResourceBundle rb) {
A_Name_S.setSpace(false);
A_Name_S.setCapital(true);
A_Name_S.setMaxLenght(20);
A_Name_S.setLimitCharachters(LimitedTextField.Characters);
}
再见
答案 5 :(得分:0)
尝试此解决方案在控制器中添加此功能,您必须将其添加到文本字段的keyPressed Action上。
@FXML
void verifnum(KeyEvent event) {
txt.textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue,
String newValue) {
if (!newValue.matches("\\d*")) {
txt.setText(newValue.replaceAll("[^\\d]", ""));
}
}
});
}