जावाएफएक्स में संख्यात्मक टेक्स्टफिल्ड बनाने के लिए अनुशंसित तरीका क्या है?


85

मुझे टेक्स्ट टेक्स्ट से लेकर पूर्णांक तक इनपुट को प्रतिबंधित करना होगा। कोई सुझाव?


3
नोट: textProperty को सुनना गलत है ! यह सबसे अच्छा था जो एक TextFormatter (fx8u40 या तो के बाद से) होने से पहले किया जा सकता था। तब से, बुनियादी नियम लागू होता है: सामान्य तौर पर इस पद्धति में मनाया मूल्य को संशोधित करने के लिए बुरा अभ्यास माना जाता है और एक टेक्स्टफॉर्म का उपयोग करना एकमात्र स्वीकार्य समाधान है।
क्लियोपेट्रा

जवाबों:


118

बहुत पुराना धागा, लेकिन ऐसा लगता है कि यदि गैर-संख्यात्मक वर्णों को चिपकाया जाता है, तो उसे बाहर निकाल दिया जाता है।

// force the field to be numeric only
textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, 
        String newValue) {
        if (!newValue.matches("\\d*")) {
            textField.setText(newValue.replaceAll("[^\\d]", ""));
        }
    }
});

3
अद्भुत काम करता है। ध्यान दें कि यदि आप कुछ वर्ण सहेजना चाहते हैं, तो इसके बजाय \\D+(या सिर्फ \\D) का उपयोग कर सकते हैं [^\\d]
ricky3350

5
यहां तक ​​कि सरल पाठ को पुरानेवैल्यू पर वापस सेट करना है। इस तरह आपको रेगेक्स रिप्लेसमेंट के साथ गड़बड़ नहीं करनी है (जो दुर्भाग्य से मेरे लिए काम नहीं किया)।
जियस्टरफ्यूरज ००

@ geisterfurz007 हालांकि यह पेस्ट किए गए पाठ से गैर-संख्यात्मक को अलग करने का विकल्प देता है।
इवान नोल्स

10
तारीख से बाहर, नीचे TextFormatter जवाब देखें।
gerardw

3
भी संभवतः सिर्फ इस्तेमाल कर सकते हैं Integer.parseInt(newValue)और उपयोग tryऔर catchपर एक त्रुटि को पहचाननाNumberFormatException
पिक्सेल

43

अद्यतन अप्रैल 2016

यह उत्तर कुछ साल पहले बनाया गया था और मूल उत्तर अब काफी हद तक अप्रचलित है।

जावा 8u40 के बाद से, जावा में एक TextFormatter है जो आमतौर पर JavaFX TextFields पर संख्यात्मक जैसे विशिष्ट स्वरूपों के इनपुट को लागू करने के लिए सबसे अच्छा है:

इस प्रश्न के अन्य उत्तर भी देखें जिसमें विशेष रूप से TextFormatter का उल्लेख है।


मूल उत्तर

इस जिस्ट में इसके कुछ उदाहरण हैं , मैंने नीचे के एक उदाहरण की नकल की है:

// helper text field subclass which restricts text input to a given range of natural int numbers
// and exposes the current numeric int value of the edit box as a value property.
class IntField extends TextField {
  final private IntegerProperty value;
  final private int minValue;
  final private int maxValue;

  // expose an integer value property for the text field.
  public int  getValue()                 { return value.getValue(); }
  public void setValue(int newValue)     { value.setValue(newValue); }
  public IntegerProperty valueProperty() { return value; }

  IntField(int minValue, int maxValue, int initialValue) {
    if (minValue > maxValue) 
      throw new IllegalArgumentException(
        "IntField min value " + minValue + " greater than max value " + maxValue
      );
    if (maxValue < minValue) 
      throw new IllegalArgumentException(
        "IntField max value " + minValue + " less than min value " + maxValue
      );
    if (!((minValue <= initialValue) && (initialValue <= maxValue))) 
      throw new IllegalArgumentException(
        "IntField initialValue " + initialValue + " not between " + minValue + " and " + maxValue
      );

    // initialize the field values.
    this.minValue = minValue;
    this.maxValue = maxValue;
    value = new SimpleIntegerProperty(initialValue);
    setText(initialValue + "");

    final IntField intField = this;

    // make sure the value property is clamped to the required range
    // and update the field's text to be in sync with the value.
    value.addListener(new ChangeListener<Number>() {
      @Override public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
        if (newValue == null) {
          intField.setText("");
        } else {
          if (newValue.intValue() < intField.minValue) {
            value.setValue(intField.minValue);
            return;
          }

          if (newValue.intValue() > intField.maxValue) {
            value.setValue(intField.maxValue);
            return;
          }

          if (newValue.intValue() == 0 && (textProperty().get() == null || "".equals(textProperty().get()))) {
            // no action required, text property is already blank, we don't need to set it to 0.
          } else {
            intField.setText(newValue.toString());
          }
        }
      }
    });

    // restrict key input to numerals.
    this.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() {
      @Override public void handle(KeyEvent keyEvent) {
        if(intField.minValue<0) {
                if (!"-0123456789".contains(keyEvent.getCharacter())) {
                    keyEvent.consume();
                }
            }
            else {
                if (!"0123456789".contains(keyEvent.getCharacter())) {
                    keyEvent.consume();
                }
            }
      }
    });

    // ensure any entered values lie inside the required range.
    this.textProperty().addListener(new ChangeListener<String>() {
      @Override public void changed(ObservableValue<? extends String> observableValue, String oldValue, String newValue) {
        if (newValue == null || "".equals(newValue) || (intField.minValue<0 && "-".equals(newValue))) {
          value.setValue(0);
          return;
        }

        final int intValue = Integer.parseInt(newValue);

        if (intField.minValue > intValue || intValue > intField.maxValue) {
          textProperty().setValue(oldValue);
        }

        value.set(Integer.parseInt(textProperty().get()));
      }
    });
  }
}

41

मुझे पता है कि यह एक पुराना धागा है, लेकिन भविष्य के पाठकों के लिए यहां एक और समाधान है जो मुझे काफी सहज लगा।

public class NumberTextField extends TextField
{

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

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

    private boolean validate(String text)
    {
        return text.matches("[0-9]*");
    }
}

संपादित करें: आपके सुझाए गए सुधारों के लिए none_ और SCBoy को धन्यवाद ।


1
क्या किसी को पता है कि दशमलव संख्या (जैसे 123.456) के लिए क्या रेगेक्स का उपयोग करना है? मान्य (पाठ) फ़ंक्शन पैरामीटर "टेक्स्ट" का मान अंतिम उपयोगकर्ता-संपादित वर्ण है, पाठ क्षेत्र में संपूर्ण स्ट्रिंग नहीं है, इसलिए रेगेक्स सही तरीके से मेल नहीं खा सकता है। उदाहरण के लिए: मैं इस आदेश का उपयोग कर रहा तरह तो text.matches("\\d+"); और मैं पाठ क्षेत्र में कोई भी वर्ण नहीं हटा सकते हैं
mils

1
@mils यहाँ और यहाँ देखो ।
वेल्लोटिस

1
मुझे लगता है कि यह एक अच्छा समाधान है, लेकिन मैं एक बात बदलूंगा। Text.matches लिखने के बजाय ("[0-9] *") मैं पैटर्न के लिए चर बनाऊंगा और इसे संकलित करूंगा। आपके कोड पैटर्न में हर बार संकलित किया जाता है जब कोई व्यक्ति किसी क्षेत्र में चरित्र लिखता है, और यह सीपीयू और मेमोरी के लिए महंगा है। इसलिए मैं वैरिएबल जोड़ूंगा: निजी स्थिर पैटर्न पूर्णांकपट्ट = पैटर्न.कॉमपाइल ("[0-9] *"); और मान्य निकाय को इसके साथ बदलें: पूर्णांकपट्टेनमंचर (पाठ) .matches ();
पी। जोको

38

JavaFX 8u40 से शुरू करते हुए, आप टेक्स्ट फ़ील्ड पर TextFormatter ऑब्जेक्ट सेट कर सकते हैं:

UnaryOperator<Change> filter = change -> {
    String text = change.getText();

    if (text.matches("[0-9]*")) {
        return change;
    }

    return null;
};
TextFormatter<String> textFormatter = new TextFormatter<>(filter);
fieldNport = new TextField();
fieldNport.setTextFormatter(textFormatter);

यह सबक्लासिंग और डुप्लिकेट परिवर्तन घटनाओं से बचता है जो आपको तब मिलेगा जब आप टेक्स्ट प्रॉपर्टी में एक श्रोता को जोड़ेंगे और उस श्रोता में टेक्स्ट को संशोधित करेंगे।


30

TextInputएक है TextFormatterजो प्रारूप, परिवर्तित करने के लिए इस्तेमाल किया जा सकता और वह पाठ जो इनपुट हो सकता है के प्रकार सीमित करते हैं।

TextFormatterएक फिल्टर जो इनपुट अस्वीकार करने के लिए इस्तेमाल किया जा सकता है। हमें किसी भी चीज़ को अस्वीकार करने के लिए इसे सेट करने की आवश्यकता है जो एक वैध पूर्णांक नहीं है। इसका एक कनवर्टर भी है जिसे हमें स्ट्रिंग मान को पूर्णांक मान में बदलने के लिए सेट करना होगा जिसे हम बाद में बाँध सकते हैं।

एक पुन: प्रयोज्य फ़िल्टर बनाने की सुविधा देता है:

public class IntegerFilter implements UnaryOperator<TextFormatter.Change> {
    private final static Pattern DIGIT_PATTERN = Pattern.compile("\\d*");

    @Override
    public Change apply(TextFormatter.Change aT) {
        return DIGIT_PATTERN.matcher(aT.getText()).matches() ? aT : null;
    }
}

फ़िल्टर तीन चीजों में से एक कर सकता है, यह इसे स्वीकार करने के लिए अनमॉडिफाइड परिवर्तन को वापस कर सकता है जैसा कि यह है, यह परिवर्तन को किसी तरह से बदल सकता है जो फिट बैठता है या यह nullसभी एक साथ परिवर्तन को अस्वीकार करने के लिए वापस आ सकता है ।

हम IntegerStringConverterएक कनवर्टर के रूप में मानक का उपयोग करेंगे।

हमारे पास यह सब एक साथ रखना:

TextField textField = ...;

TextFormatter<Integer> formatter = new TextFormatter<>(
    new IntegerStringConverter(), // Standard converter form JavaFX
    defaultValue, 
    new IntegerFilter());
formatter.valueProperty().bindBidirectional(myIntegerProperty);

textField.setTextFormatter(formatter);

यदि आप चाहते हैं कि एक पुन: प्रयोज्य फ़िल्टर की आवश्यकता न हो तो आप इस फैंसी वन-लाइनर की जगह कर सकते हैं:

TextFormatter<Integer> formatter = new TextFormatter<>(
    new IntegerStringConverter(), 
    defaultValue,  
    c -> Pattern.matches("\\d*", c.getText()) ? c : null );

21

मुझे अपवाद पसंद नहीं हैं, इसलिए मैंने matchesस्ट्रिंग-क्लास से फ़ंक्शन का उपयोग किया

text.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, 
        String newValue) {
        if (newValue.matches("\\d*")) {
            int value = Integer.parseInt(newValue);
        } else {
            text.setText(oldValue);
        }
    }
});

1
कभी-कभी आपके पास एक अपवाद होता है, क्योंकि न्युबर बहुत बड़ा हो सकता है।
schlagi123

1
युक्ति: रेगेक्स "\\ d +" को "\\ d *" में बदलें। यह आपको पाठ इनपुट फ़ील्ड से सभी वर्णों को निकालने की अनुमति देगा (फ़ील्ड को खाली करने के लिए बैकस्पेस / डिलीट का उपयोग करें)।
गुरू

1
वापस पुराने मूल्य पर सेट करने के बाद कैरट पोजीशन सेट करना न भूलें:textField.positionCaret(textField.getLength());
hsson

यदि स्थिति हो तो मुट्ठी बदलें: if (newValue.matches("\\d*") && newValue.getText().length < 5) यदि आप इस मामले में इनपुट को 4 अंकों तक सीमित करना चाहते हैं।
कैप्पुकिनो 90

@ Cappuccino90 आपको कथनों को स्विच करना चाहिए क्योंकि लंबाई की जाँच प्रत्येक हिट पर एक
रेगीक्स को

9

जावा एसई 8u40 से शुरू , इस तरह की आवश्यकता के लिए आप कीबोर्ड के एरो / डाउन एरो कीज या अप एरो / डाउन एरो प्रदान किए गए बटन का उपयोग करके एक वैध पूर्णांक को सुरक्षित रूप से चुनने के लिए " पूर्णांक " का उपयोग कर सकते हैं Spinner

आप अनुमत मानों को सीमित करने के लिए एक मिनट , एक अधिकतम और एक प्रारंभिक मूल्य भी परिभाषित कर सकते हैं और प्रति कदम वेतन वृद्धि या वेतन वृद्धि की राशि।

उदाहरण के लिए

// Creates an integer spinner with 1 as min, 10 as max and 2 as initial value
Spinner<Integer> spinner1 = new Spinner<>(1, 10, 2);
// Creates an integer spinner with 0 as min, 100 as max and 10 as initial 
// value and 10 as amount to increment or decrement by, per step
Spinner<Integer> spinner2 = new Spinner<>(0, 100, 10, 10);

एक " पूर्णांक " स्पिनर और एक " डबल " स्पिनर के साथ परिणाम का उदाहरण

यहाँ छवि विवरण दर्ज करें

एक स्पिनर एक एकल लाइन पाठ क्षेत्र नियंत्रण उपयोगकर्ता इस तरह के मूल्यों का एक आदेश दिया अनुक्रम से एक नंबर या किसी वस्तु मान का चयन करने देता है। स्पिनर आमतौर पर अनुक्रम के तत्वों के माध्यम से कदम रखने के लिए छोटे तीर बटन की एक जोड़ी प्रदान करते हैं। कीबोर्ड का एरो / डाउन एरो कीज़ भी तत्वों के माध्यम से चक्रित होता है। उपयोगकर्ता को स्पिनर में सीधे (कानूनी) मान टाइप करने की अनुमति दी जा सकती है। यद्यपि कॉम्बो बॉक्स समान कार्यक्षमता प्रदान करते हैं, स्पिनरों को कभी-कभी पसंद किया जाता है क्योंकि उन्हें एक ड्रॉप-डाउन सूची की आवश्यकता नहीं होती है जो महत्वपूर्ण डेटा को अस्पष्ट कर सकते हैं, और इसलिए भी कि वे अधिकतम मूल्य से न्यूनतम मूल्य तक लपेटने जैसी सुविधाओं के लिए अनुमति देते हैं (जैसे,) सबसे बड़े सकारात्मक पूर्णांक से 0)।

स्पिनर नियंत्रण के बारे में अधिक जानकारी


लोगों को स्पिनर को पाठ प्रविष्टि या खोए हुए फोकस पर मान्य नहीं करना चाहिए
ज्यामितीय

7

यदि आप जावा 1.8 लैम्ब्डा का उपयोग करते हैं तो पहले से मौजूद उत्तर और भी छोटा हो सकता है

textfield.textProperty().addListener((observable, oldValue, newValue) -> {
    if (newValue.matches("\\d*")) return;
    textfield.setText(newValue.replaceAll("[^\\d]", ""));
});

6
TextField text = new TextField();

text.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable,
            String oldValue, String newValue) {
        try {
            Integer.parseInt(newValue);
            if (newValue.endsWith("f") || newValue.endsWith("d")) {
                manualPriceInput.setText(newValue.substring(0, newValue.length()-1));
            }
        } catch (ParseException e) {
            text.setText(oldValue);
        }
    }
});

ifखंड 0.5d या 0.7f की तरह संभाल आदानों जो सही ढंग से Int.parseInt (द्वारा पार्स कर रहे हैं) के लिए महत्वपूर्ण है, लेकिन पाठ क्षेत्र में प्रकट नहीं करना चाहिए।


9
Woot? जब से 0.5d सही ढंग से Integer.parseInt () द्वारा पार्स किया गया है ?! यह एक java.lang.NumberFormatException फेंकता है: इनपुट स्ट्रिंग के लिए: "0.5d" (जैसा कि अपेक्षित है, क्योंकि यह इंटेगर नहीं है)
बुर्खर्ड

4

इस सरल कोड की कोशिश करो यह काम करेगा।

DecimalFormat format = new DecimalFormat( "#.0" );
TextField field = new TextField();
field.setTextFormatter( new TextFormatter<>(c ->
{
    if ( c.getControlNewText().isEmpty() )
    {
        return c;
    }

    ParsePosition parsePosition = new ParsePosition( 0 );
    Object object = format.parse( c.getControlNewText(), parsePosition );

    if ( object == null || parsePosition.getIndex() <          c.getControlNewText().length() )
    {
        return null;
    }
    else
    {
        return c;
    }
}));

3

यदि आप एक ही श्रोता को एक से अधिक TextField पर लागू करना चाहते हैं, तो इसका सबसे सरल उपाय है:

TextField txtMinPrice, txtMaxPrice = new TextField();

ChangeListener<String> forceNumberListener = (observable, oldValue, newValue) -> {
    if (!newValue.matches("\\d*"))
      ((StringProperty) observable).set(oldValue);
};

txtMinPrice.textProperty().addListener(forceNumberListener);
txtMaxPrice.textProperty().addListener(forceNumberListener);

3

यह एक मेरे लिए काम किया।

public void RestrictNumbersOnly(TextField tf){
    tf.textProperty().addListener(new ChangeListener<String>() {
        @Override
        public void changed(ObservableValue<? extends String> observable, String oldValue, 
            String newValue) {
            if (!newValue.matches("|[-\\+]?|[-\\+]?\\d+\\.?|[-\\+]?\\d+\\.?\\d+")){
                tf.setText(oldValue);
            }
        }
    });
}

3

मैं TextFormatterजावाएफ़एक्स 8 से इवान नोल्स उत्तर के संयोजन से अपने विचार के साथ मदद करना चाहता हूं

textField.setTextFormatter(new TextFormatter<>(c -> {
    if (!c.getControlNewText().matches("\\d*")) 
        return null;
    else
        return c;
    }
));

इसलिए सौभाग्य;) शांत और कोड जावा रखें


2

यहाँ एक सरल वर्ग कि हैंडल पर कुछ बुनियादी सत्यापन है TextField, का उपयोग कर TextFormatterJavaFX 8u40 में पेश

संपादित करें:

(फ़्लर्न की टिप्पणी के संबंध में जोड़ा गया कोड)

import java.text.DecimalFormatSymbols;
import java.util.regex.Pattern;

import javafx.beans.NamedArg;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;

public class TextFieldValidator {

    private static final String CURRENCY_SYMBOL   = DecimalFormatSymbols.getInstance().getCurrencySymbol();
    private static final char   DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();

    private final Pattern       INPUT_PATTERN;

    public TextFieldValidator(@NamedArg("modus") ValidationModus modus, @NamedArg("countOf") int countOf) {
        this(modus.createPattern(countOf));
    }

    public TextFieldValidator(@NamedArg("regex") String regex) {
        this(Pattern.compile(regex));
    }

    public TextFieldValidator(Pattern inputPattern) {
        INPUT_PATTERN = inputPattern;
    }

    public static TextFieldValidator maxFractionDigits(int countOf) {
        return new TextFieldValidator(maxFractionPattern(countOf));
    }

    public static TextFieldValidator maxIntegers(int countOf) {
        return new TextFieldValidator(maxIntegerPattern(countOf));
    }

    public static TextFieldValidator integersOnly() {
        return new TextFieldValidator(integersOnlyPattern());
    }

    public TextFormatter<Object> getFormatter() {
        return new TextFormatter<>(this::validateChange);
    }

    private Change validateChange(Change c) {
        if (validate(c.getControlNewText())) {
            return c;
        }
        return null;
    }

    public boolean validate(String input) {
        return INPUT_PATTERN.matcher(input).matches();
    }

    private static Pattern maxFractionPattern(int countOf) {
        return Pattern.compile("\\d*(\\" + DECIMAL_SEPARATOR + "\\d{0," + countOf + "})?");
    }

    private static Pattern maxCurrencyFractionPattern(int countOf) {
        return Pattern.compile("^\\" + CURRENCY_SYMBOL + "?\\s?\\d*(\\" + DECIMAL_SEPARATOR + "\\d{0," + countOf + "})?\\s?\\" +
                CURRENCY_SYMBOL + "?");
    }

    private static Pattern maxIntegerPattern(int countOf) {
        return Pattern.compile("\\d{0," + countOf + "}");
    }

    private static Pattern integersOnlyPattern() {
        return Pattern.compile("\\d*");
    }

    public enum ValidationModus {

        MAX_CURRENCY_FRACTION_DIGITS {
            @Override
            public Pattern createPattern(int countOf) {
                return maxCurrencyFractionPattern(countOf);
            }
        },

        MAX_FRACTION_DIGITS {
            @Override
            public Pattern createPattern(int countOf) {
                return maxFractionPattern(countOf);
            }
        },
        MAX_INTEGERS {
            @Override
            public Pattern createPattern(int countOf) {
                return maxIntegerPattern(countOf);
            }
        },

        INTEGERS_ONLY {
            @Override
            public Pattern createPattern(int countOf) {
                return integersOnlyPattern();
            }
        };

        public abstract Pattern createPattern(int countOf);
    }

}

आप इसे इस तरह से उपयोग कर सकते हैं:

textField.setTextFormatter(new TextFieldValidator(ValidationModus.INTEGERS_ONLY).getFormatter());

या आप इसे एक fxml फ़ाइल में झटपट कर सकते हैं, और इसे एक गुण के अनुसार customTextField पर लागू कर सकते हैं।

app.fxml:

<fx:define>
    <TextFieldValidator fx:id="validator" modus="INTEGERS_ONLY"/>
</fx:define>

CustomTextField.class:

public class CustomTextField {

private TextField textField;

public CustomTextField(@NamedArg("validator") TextFieldValidator validator) {
        this();
        textField.setTextFormatter(validator.getFormatter());
    }
}

जीथब पर कोड


2

यही है वह जो मेरे द्वारा उपयोग किया जाता है:

private TextField textField;
textField.textProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        if(!newValue.matches("[0-9]*")){
            textField.setText(oldValue);
        }

    }
});

लंबोदर नोटेशन में भी यही होगा:

private TextField textField;
textField.textProperty().addListener((observable, oldValue, newValue) -> {
    if(!newValue.matches("[0-9]*")){
        textField.setText(oldValue);
    }
});

2

यह विधि TextField को सभी प्रसंस्करण (कॉपी / पेस्ट / पूर्ववत सुरक्षित) खत्म करने देती है। कक्षाओं को विस्तारित करने की आवश्यकता नहीं होती है और आपको हर बदलाव के बाद नए पाठ के साथ क्या करना है, यह तय करने की अनुमति देता है (इसे तर्क में धकेलने के लिए, या पिछले मूल्य पर वापस जाएं, या इसे संशोधित करने के लिए भी)।

  // fired by every text property change
textField.textProperty().addListener(
  (observable, oldValue, newValue) -> {
    // Your validation rules, anything you like
      // (! note 1 !) make sure that empty string (newValue.equals("")) 
      //   or initial text is always valid
      //   to prevent inifinity cycle
    // do whatever you want with newValue

    // If newValue is not valid for your rules
    ((StringProperty)observable).setValue(oldValue);
      // (! note 2 !) do not bind textProperty (textProperty().bind(someProperty))
      //   to anything in your code.  TextProperty implementation
      //   of StringProperty in TextFieldControl
      //   will throw RuntimeException in this case on setValue(string) call.
      //   Or catch and handle this exception.

    // If you want to change something in text
      // When it is valid for you with some changes that can be automated.
      // For example change it to upper case
    ((StringProperty)observable).setValue(newValue.toUpperCase());
  }
);

अपने मामले के लिए बस इस तर्क को अंदर जोड़ें। अच्छी तरह से काम।

   if (newValue.equals("")) return; 
   try {
     Integer i = Integer.valueOf(newValue);
     // do what you want with this i
   } catch (Exception e) {
     ((StringProperty)observable).setValue(oldValue);
   }

0

Mmmm। मैं हफ्तों पहले उस समस्या में भाग गया था। चूंकि एपीआई इसे प्राप्त करने के लिए एक नियंत्रण प्रदान नहीं करता है,
आप अपने स्वयं के उपयोग करना चाह सकते हैं।
मैंने कुछ इस तरह इस्तेमाल किया:

public class IntegerBox extends TextBox {
    public-init var value : Integer = 0;
    protected function apply() {
        try {
            value = Integer.parseInt(text);
        } catch (e : NumberFormatException) {}
        text = "{value}";
    }
    override var focused = false on replace {apply()};
    override var action = function () {apply()}
}

यह उसी तरह से उपयोग किया जाता है जो एक सामान्य है TextBox,
लेकिन इसमें एक valueविशेषता भी है जो दर्ज किए गए पूर्णांक को संग्रहीत करता है।
जब नियंत्रण फोकस खो देता है, तो यह मान को मान्य करता है और इसे वापस लौटाता है (यदि यह मान्य नहीं है)।


2
यह कौनसी भाषा है?
चुपके रब्बी


0

इस कोड को अपना टेक्स्ट बनाएं केवल नंबर स्वीकार करें

textField.lengthProperty().addListener((observable, oldValue, newValue) -> {
        if(newValue.intValue() > oldValue.intValue()){
            char c = textField.getText().charAt(oldValue.intValue());
            /** Check if the new character is the number or other's */
            if( c > '9' || c < '0'){
                /** if it's not number then just setText to previous one */
                textField.setText(textField.getText().substring(0,textField.getText().length()-1));
            }
        }
    });

0

यदि आप कॉपी / पेस्ट करने की कोशिश करते हैं तो भी यह कोड मेरे लिए ठीक काम करता है।

myTextField.textProperty().addListener((observable, oldValue, newValue) -> {
    if (!newValue.matches("\\d*")) {
        myTextField.setText(oldValue);

    }
});

-1

JavaFX के हालिया अपडेट में, आपको इस तरह से Platform.runLater पद्धति में नया पाठ सेट करना होगा:

    private void set_normal_number(TextField textField, String oldValue, String newValue) {
    try {
        int p = textField.getCaretPosition();
        if (!newValue.matches("\\d*")) {
            Platform.runLater(() -> {
                textField.setText(newValue.replaceAll("[^\\d]", ""));
                textField.positionCaret(p);
            });
        }
    } catch (Exception e) {
    }
}

कैरेट पोजिशन भी सेट करना एक अच्छा विचार है।


1
आपके उत्तर के लिए धन्यवाद! क्या आप थोड़ा समझा सकते हैं कि Platform.runLaterइसकी आवश्यकता क्यों है?
ट्यूरिंगक्स

JavaT के हालिया संस्करण में @TuringTux, यदि आप Platform.runLater
bdshahab का

-1

मैं इवान नोल्स उत्तर में सुधार करना चाहूंगा: https://stackoverflow.com/a/30796829/2628125

मेरे मामले में मैंने UI घटक भाग के लिए संचालकों के साथ कक्षा की थी। प्रारंभ:

this.dataText.textProperty().addListener((observable, oldValue, newValue) -> this.numericSanitization(observable, oldValue, newValue));

और संख्याकरण विधि:

private synchronized void numericSanitization(ObservableValue<? extends String> observable, String oldValue, String newValue) {
    final String allowedPattern = "\\d*";

    if (!newValue.matches(allowedPattern)) {
        this.dataText.setText(oldValue);
    }
}

Javafx में संभावित रेंडर लॉक इश्यू को रोकने के लिए कीवर्ड सिंक्रोनाइज़ किया गया है, यदि सेटटेक्स्ट को पुराने समाप्त होने से पहले कॉल किया जाएगा। यदि आप वास्तव में तेजी से गलत वर्ण टाइप करना शुरू कर देंगे तो पुन: पेश करना आसान है।

एक और फायदा यह है कि आप मैच करने के लिए केवल एक पैटर्न रखते हैं और सिर्फ रोलबैक करते हैं। यह बेहतर है क्योंकि आप अलग-अलग सैनिटाइजेशन पैटर्न के समाधान को आसानी से रोक सकते हैं।


-1
rate_text.textProperty().addListener(new ChangeListener<String>() {

    @Override
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
        String s="";
        for(char c : newValue.toCharArray()){
            if(((int)c >= 48 && (int)c <= 57 || (int)c == 46)){
                s+=c;
            }
        }
        rate_text.setText(s);
    }
});

यह ठीक काम करता है क्योंकि यह आपको केवल पूर्णांक मान और दशमलव मान (ASCII कोड 46 होने) दर्ज करने की अनुमति देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.