2016-11-07 6 views
7

मैं UnaryOperator साथ JavaFX 8.संख्यात्मक TextField और/या UnaryOperator

समाधान TextFormatter का उपयोग करके पूर्णांकों के लिए सांख्यिक TextField बनाने के लिए कोशिश कर रहा हूँ:

UnaryOperator<Change> integerFilter = change -> { 
    String input = change.getText(); 
    if (input.matches("[0-9]*")) { 
     return change; 
    } 
    return null; 
}; 

myNumericField.setTextFormatter(new TextFormatter<String>(integerFilter)); 

IntegerStringConverter साथ समाधान:

myNumericField.setTextFormatter(new TextFormatter<>(new IntegerStringConverter())); 

दोनों समाधानों में अपनी समस्या है। यूनरीऑपरेटर के साथ, मैं केवल 0 से 9 अंकों के इरादे से अंक दर्ज कर सकता हूं, लेकिन मुझे "-512" जैसे नकारात्मक मानों को भी दर्ज करना होगा, जहां साइन केवल पहली स्थिति में ही अनुमति है। इसके अलावा मुझे "00016" जैसी संख्याएं नहीं चाहिए जो अभी भी संभव है।

इंटीजरस्ट्रिंग कनवर्टर विधि बेहतर तरीके से काम करती है: "-16-123" जैसे प्रत्येक अमान्य नंबर को स्वीकार नहीं किया जाता है और "12312" जैसे नंबर "123" में परिवर्तित हो जाते हैं। लेकिन रूपांतरण केवल तभी होता है जब पाठ को चालू किया जाता है (प्रवेश दबाकर) या जब टेक्स्टफिल्ड अपना ध्यान खो देता है।

क्या टेक्स्टफिल्ड के मान को हर बार इंटीजरस्ट्रिंग कनवर्टर के साथ दूसरी विधि के रूपांतरण को लागू करने का कोई तरीका है?

उत्तर

13

कनवर्टर फ़िल्टर के लिए अलग है: कनवर्टर निर्दिष्ट करता है कि पाठ को किसी मान में कैसे परिवर्तित किया जाए, और फ़िल्टर फ़िल्टर उपयोगकर्ता को बदल सकता है। ऐसा लगता है कि आप दोनों चाहते हैं, लेकिन आप फ़िल्टर को अनुमति देने वाले परिवर्तनों को अधिक सटीक रूप से फ़िल्टर करना चाहते हैं।

यदि परिवर्तन स्वीकार किया गया तो मुझे आमतौर पर पाठ के नए मूल्य की जांच करना सबसे आसान लगता है। आप वैकल्पिक रूप से - चाहते हैं, इसके बाद 1-9 इसके बाद किसी भी संख्या के अंकों के साथ। खाली स्ट्रिंग को अनुमति देना महत्वपूर्ण है, अन्यथा उपयोगकर्ता सबकुछ हटाने में सक्षम नहीं होगा।

तो आप शायद की तरह

UnaryOperator<Change> integerFilter = change -> { 
    String newText = change.getControlNewText(); 
    if (newText.matches("-?([1-9][0-9]*)?")) { 
     return change; 
    } 
    return null; 
}; 

myNumericField.setTextFormatter(
    new TextFormatter<Integer>(new IntegerStringConverter(), 0, integerFilter)); 

तुम भी फिल्टर करने के लिए और अधिक कार्यक्षमता जोड़ सकते हैं यह एक समझदारी भरा तरीका में, उदाहरण के लिए - की प्रक्रिया बताने के लिए कुछ चाहिए

UnaryOperator<Change> integerFilter = change -> { 
    String newText = change.getControlNewText(); 
    // if proposed change results in a valid value, return change as-is: 
    if (newText.matches("-?([1-9][0-9]*)?")) { 
     return change; 
    } else if ("-".equals(change.getText())) { 

     // if user types or pastes a "-" in middle of current text, 
     // toggle sign of value: 

     if (change.getControlText().startsWith("-")) { 
      // if we currently start with a "-", remove first character: 
      change.setText(""); 
      change.setRange(0, 1); 
      // since we're deleting a character instead of adding one, 
      // the caret position needs to move back one, instead of 
      // moving forward one, so we modify the proposed change to 
      // move the caret two places earlier than the proposed change: 
      change.setCaretPosition(change.getCaretPosition()-2); 
      change.setAnchor(change.getAnchor()-2); 
     } else { 
      // otherwise just insert at the beginning of the text: 
      change.setRange(0, 0); 
     } 
     return change ; 
    } 
    // invalid change, veto it by returning null: 
    return null; 
}; 

यह किसी भी बिंदु पर उपयोगकर्ता प्रेस - करने देगा और यह पूर्णांक के हस्ताक्षर टॉगल करेगा।

SSCCE: नंबर समूह पर `` की

import java.util.function.UnaryOperator; 

import javafx.application.Application; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.control.TextFormatter.Change; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.util.StringConverter; 
import javafx.util.converter.IntegerStringConverter; 

public class IntegerFieldExample extends Application { 

    @Override 
    public void start(Stage primaryStage) { 
     TextField integerField = new TextField(); 
     UnaryOperator<Change> integerFilter = change -> { 
      String newText = change.getControlNewText(); 
      if (newText.matches("-?([1-9][0-9]*)?")) { 
       return change; 
      } else if ("-".equals(change.getText())) { 
       if (change.getControlText().startsWith("-")) { 
        change.setText(""); 
        change.setRange(0, 1); 
        change.setCaretPosition(change.getCaretPosition()-2); 
        change.setAnchor(change.getAnchor()-2); 
        return change ; 
       } else { 
        change.setRange(0, 0); 
        return change ; 
       } 
      } 
      return null; 
     }; 

     // modified version of standard converter that evaluates an empty string 
     // as zero instead of null: 
     StringConverter<Integer> converter = new IntegerStringConverter() { 
      @Override 
      public Integer fromString(String s) { 
       if (s.isEmpty()) return 0 ; 
       return super.fromString(s); 
      } 
     }; 

     TextFormatter<Integer> textFormatter = 
       new TextFormatter<Integer>(converter, 0, integerFilter); 
     integerField.setTextFormatter(textFormatter); 

     // demo listener: 
     textFormatter.valueProperty().addListener((obs, oldValue, newValue) -> System.out.println(newValue)); 

     VBox root = new VBox(5, integerField, new Button("Click Me")); 
     root.setAlignment(Pos.CENTER); 
     Scene scene = new Scene(root, 300, 120); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

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

स्मार्ट उपयोग! '-? ([1-9]? | [1-9] [0-9] *) के बारे में सोच रहा था, लेकिन यह बहुत साफ है! – flakes

+1

मैं वास्तव में आपके प्रयास की सराहना करता हूं, आपका समाधान पूरी तरह से काम करता है! – ShadowEagle

1
TextField txtpoint = new TextField(); 
    txtpoint.textProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
      if (!newValue.isEmpty()) { 
       try { 
        long pointI = Integer.parseInt(newValue); 
        txtpoint.setText(String.valueOf(pointI)); 
       } catch (Exception e) { 
        txtpoint.clear(); 
        txtpoint.setText(getNumber(oldValue)); 
       } 
      } 
     } 
    }); 


private String getNumber(String value) { 
    String n = ""; 
    try { 
     return String.valueOf(Integer.parseInt(value)); 
    } catch (Exception e) { 
     String[] array = value.split(""); 
     for (String tab : array) { 
      try { 
       System.out.println(tab); 
       n = n.concat(String.valueOf(Integer.parseInt(String.valueOf(tab)))); 
      } catch (Exception ex) { 
       System.out.println("not nomber"); 
      } 
     } 
     return n; 
    } 
} 
+1

स्टैक ओवरफ़्लो पर स्पष्टीकरण/उपयोग निर्देश के कुछ शब्द आमतौर पर स्वागत करते हैं। – mkl

संबंधित मुद्दे