2014-03-28 18 views

Antwort

2

Hier meine Lösung ist die Länge eines Textfeldes zu begrenzen. Ich würde keine Lösungen empfehlen, die einen Listener verwenden (auf text -Eigenschaft oder auf length -Eigenschaft), sie verhalten sich nicht in allen Situationen korrekt (für das, was ich gesehen habe). Ich erstelle einen HTML-Eingabetext mit einer maximalen Länge und vergleiche ihn mit meinem Textfeld in JavaFX. Ich hatte das gleiche Verhalten mit Einfügen Operationen (Strg + V), Operationen abbrechen (Strg + Z) in beiden Fällen. Das Ziel hier ist, zu überprüfen, ob der Text gültig ist, BEVOR das Textfeld geändert wird. Wir könnten einen ähnlichen Ansatz für ein numerisches Textfeld verwenden.

import java.util.Objects; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.scene.control.TextField; 

public class LimitedTextField extends TextField { 

    private final IntegerProperty maxLength; 

    public LimitedTextField() { 
     super(); 
     this.maxLength = new SimpleIntegerProperty(-1); 
    } 

    public IntegerProperty maxLengthProperty() { 
     return this.maxLength; 
    } 

    public final Integer getMaxLength() { 
     return this.maxLength.getValue(); 
    } 

    public final void setMaxLength(Integer maxLength) { 
     Objects.requireNonNull(maxLength, "Max length cannot be null, -1 for no limit"); 
     this.maxLength.setValue(maxLength); 
    } 

    @Override 
    public void replaceText(int start, int end, String insertedText) { 
     if (this.getMaxLength() <= 0) { 
      // Default behavior, in case of no max length 
      super.replaceText(start, end, insertedText); 
     } 
     else { 
      // Get the text in the textfield, before the user enters something 
      String currentText = this.getText() == null ? "" : this.getText(); 

      // Compute the text that should normally be in the textfield now 
      String finalText = currentText.substring(0, start) + insertedText + currentText.substring(end); 

      // If the max length is not excedeed 
      int numberOfexceedingCharacters = finalText.length() - this.getMaxLength(); 
      if (numberOfexceedingCharacters <= 0) { 
       // Normal behavior 
       super.replaceText(start, end, insertedText); 
      } 
      else { 
       // Otherwise, cut the the text that was going to be inserted 
       String cutInsertedText = insertedText.substring(
         0, 
         insertedText.length() - numberOfexceedingCharacters 
       ); 

       // And replace this text 
       super.replaceText(start, end, cutInsertedText); 
      } 
     } 
    } 
} 

mit JavaFX 8 und Java Getestet 8u45

8

Sie können die Anzahl der Zeichen nicht direkt begrenzen. Sie können jedoch einen listener zu lengthProperty() dem Textfeld hinzufügen

import javafx.application.Application; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 

public class TextFieldLimit extends Application { 
    private static final int LIMIT = 10; 

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

    @Override 
    public void start(final Stage primaryStage) { 

     final TextField textField = new TextField(); 
     textField.lengthProperty().addListener(new ChangeListener<Number>() { 

      @Override 
      public void changed(ObservableValue<? extends Number> observable, 
        Number oldValue, Number newValue) { 
       if (newValue.intValue() > oldValue.intValue()) { 
        // Check if the new character is greater than LIMIT 
        if (textField.getText().length() >= LIMIT) { 

         // if it's 11th character then just setText to previous 
         // one 
         textField.setText(textField.getText().substring(0, LIMIT)); 
        } 
       } 
      } 
     }); 

     VBox vbox = new VBox(20); 
     vbox.getChildren().add(textField); 

     Scene scene = new Scene(vbox, 400, 300); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 
} 
+4

Ich würde empfehlen 'textField.setText (textField.getText(). Substring (0, LIMIT));'. Andernfalls, wenn der Benutzer Kopieren und Einfügen verwendet, um eine sehr große Zeichenfolge dort zu speichern, wird es wiederholt den Listener aufrufen und den Text ein Zeichen nach dem anderen reduzieren. –

+0

Danke, dass du das unterstrichen hast! Ich habe die Antwort bearbeitet! – ItachiUchiha

+0

Großartig. Danke vielmals. –

0

Dies ist eine bessere Möglichkeit, den Job auf einem generischen Textfeld zu tun:

public static void addTextLimiter(final TextField tf, final int maxLength) { 
    tf.textProperty().addListener(new ChangeListener<String>() { 
     @Override 
     public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) { 
      if (tf.getText().length() > maxLength) { 
       String s = tf.getText().substring(0, maxLength); 
       tf.setText(s); 
      } 
     } 
    }); 
} 

funktioniert perfekt, mit Ausnahme, dass Fehler rückgängig machen.

1

Dies ist eine sehr einfache Lösung, die für mich zu funktionieren scheint.

0

Ich benutze einen einfachen Aufruf zu ChangeListener, wo ich die Bedingung zu Stopps zu testen.

textFild.addListener((observable, oldValue, newValue) -> { 
    if (newValue.length() == MAX_SIZE) { 
     textField.setText(oldValue); 
    } 
}); 
Verwandte Themen