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


Answers

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

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 ।

Question

मुझे इनपुट को टेक्स्टफिल्ड में पूर्णांक में प्रतिबंधित करने की आवश्यकता है। कोई सलाह?




जावाएफएक्स के हालिया अपडेट में, आपको 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) {
    }
}

कैरेट स्थिति भी सेट करना एक अच्छा विचार है।




इस सरल कोड को आजमाएं यह काम करेगा।

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;
    }
}));



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

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);
            }
        }
    });
}



    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 होने) में प्रवेश करने की अनुमति देता है।




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 );



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

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);
    }
});



यह कोड अपना टेक्स्टफिल्ल्ड केवल संख्या स्वीकार करें

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));
            }
        }
    });



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

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);

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




जावा एसई 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 से सबसे बड़े सकारात्मक पूर्णांक से)।

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






Related