9

我想控制对 Javafx TextField 的输入,以便我只能允许数字输入,并且如果超过最大字符数,则不会对文本框进行任何更改。

编辑:根据评论中的建议,我使用了 JavaFX 项目负责人建议的方法。阻止输入字母非常有用。我只需要它来过滤特殊字符。我尝试将过滤器更改为 (text.matchs("[0-9]") 但这不允许输入退格键。

编辑2:想出了一个特殊字符和长度的过滤器。这是我的最终代码。感谢输入的家伙。

这是我创建的 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);
        }
    }
}

注意:我已阅读在 JavaFX 中制作数字 TextField 的推荐方法是什么?这个帖子,这个解决方案对我不起作用。只有在输入数字后才会触发它。这意味着有人可以在框中输入字母文本,并且在他们将焦点从文本字段移开之前,它会允许这样做。此外,他们可以输入大于允许的数字,但验证不会在每次按键时发生,而是在焦点转移(“更改”事件)之后发生。

4

6 回答 6

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();
            }
        }
    };
}    
/*****************************************************************************************/

祝你好运。

于 2014-06-17T02:57:03.370 回答
4

这是我的方法,两个事件过滤器,可能是一个,在我的情况下,我在不同的情况下使用它们,这就是为什么有两个。

这是 maxValueFilter(在西班牙文 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));
于 2013-10-04T11:17:19.377 回答
3

最终解决方案。禁止字母和特殊字符并强制执行字符限制。

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);
        }
    }
}
于 2013-10-07T18:31:56.287 回答
2

我只是设置了“On Key Typed”事件来运行这个小程序:

    @FXML public void processKeyEvent(KeyEvent ev) {
    String c = ev.getCharacter();
    if("1234567890".contains(c)) {}
    else {
        ev.consume();
    }
}

它就像一个冠军!

于 2015-01-10T22:12:42.340 回答
2

我创建了一个可以添加到 Java Builder FX 的自定义文本字段(使用“导入 JAR/FXML 文件...”)。

有了这个 TextField 可以设置

  1. 允许的字符或数字
  2. 是否有空格字符
  3. 如果输入仅为大写(显示的输出为大写)
  4. 和长度。

当然可以改进,但它非常有用。希望这会对某人有所帮助:)

FX 项目 LimitedTextField 可以使用此项目创建“LimitedTextField.jar”文件以导入您的应用程序或 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);
}

再见

于 2015-06-05T20:48:56.777 回答
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]", ""));
            }
        }
    });
}
于 2018-02-26T23:10:46.120 回答