2017-01-06 2 views
1

мне нужно ограничить интервал текстового свойства текстового поляJavaFX: TextField макс и мин значения от слушателя

int maxLength = 64; 
    int minLength = 0; 
    txtSeuil.textProperty().addListener((v, oldValue, newValue) -> { 
     if (!newValue.matches("\\d*")) { 
      txtSeuil.setText(newValue.replaceAll("[^\\d*{1,2}]", "")); 
      if (txtSeuil.getText().length() > maxLength || txtSeuil.getText().length() < minLength) { 
       String s = txtSeuil.getText().substring(0, maxLength); 
       txtSeuil.setText(s); 
      } 
     } 

    }); 

поле совершает принимают только номера, но и любое число, а не только интервал значений

ответ

1

Если я понял правильно, вы пытаетесь реализовать числовое поле, которое допускает только значения в интервале [0, 64]. Согласно this answer, TextFormatter - это рекомендуемый способ достижения такой функциональности. Посмотрите на это MWE, который должен решить проблему:

public class RestrictedNumberFieldDemo extends Application { 

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

    @Override 
    public void start(Stage primaryStage) { 
     TextField numField = new TextField(); 
     numField.setTextFormatter(new TextFormatter<Integer>(change -> { 
      // Deletion should always be possible. 
      if (change.isDeleted()) { 
       return change; 
      } 

      // How would the text look like after the change? 
      String txt = change.getControlNewText(); 

      // There shouldn't be leading zeros. 
      if (txt.matches("0\\d+")) { 
       return null; 
      } 

      // Try parsing and check if the result is in [0, 64]. 
      try { 
       int n = Integer.parseInt(txt); 
       return 0 <= n && n <= 64 ? change : null; 
      } catch (NumberFormatException e) { 
       return null; 
      } 
     })); 

     primaryStage.setScene(new Scene(numField)); 
     primaryStage.show(); 
    } 

} 
2

Для решения вашей проблемы вы можете реализовать пользовательские Filter для TextFormatter. Это позволит вводить только числа и ограничивать длину строки. Вот фрагмент кода, который показывает, как он может работать:

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.stage.Stage; 

public class Main5 extends Application { 
    @Override 
    public void start(Stage primaryStage) throws Exception { 
     TextField textField = new TextField(); 
     textField.setTextFormatter(new TextFormatter<Integer>(change -> { 
      if (!change.getText().isEmpty()) { 
       return change.getText().matches("\\d+") && change.getControlNewText().length() <= 5 ? change : null; 
      } 

      return change; 
     })); 

     primaryStage.setScene(new Scene(textField)); 
     primaryStage.show(); 
    } 
} 
+0

спасибо, она работает на длине, но я сделал ошибку на коде, MinValue и MaxValue, что я хочу, не для значения длины, но VOR текстовое значение, так как я могу это исправить? – devhicham

+0

@devhicham Что вы подразумеваете под «текстовой стоимостью»? Только цифры от 0 до 64? – beatngu13

+0

@ beatngu13 да пожалуйста, я хочу, чтобы поле принимало только эти интервальные номера от 0 до 64 – devhicham

0

Ваша проблема:

Проверка длины не будет сделано, если регулярное выражение соответствует. Но текст может быть последовательностью цифр и быть длинным.

Вам необходимо выполнить эти проверки независимо друг от друга.

Также вы устанавливаете новое значение в некоторых случаях, которое снова запускает те же проверки. Конечно, они будут приводить к String будучи вычисляется как действительный вход, но вы могли бы предотвратить проверку снова путем введения поля в ChangeListener, которая хранит ли в настоящее время выполняется слушатель:

txtSeuil.textProperty().addListener(new ChangeListener<String>() { 

    private boolean validating = false; 

    @Override 
    public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { 
     if (!validating) { 
      validating = true; 
      String newText = newValue; 
      boolean modify = false; 
      if (!newValue.matches("\\d*")) { 
       newText = newValue.replaceAll("[^\\d*{1,2}]", ""); 
       modify = true; 
      } 
      if (newText.length() > maxLength || newText.length() < minLength) { 
       newText = newText.substring(0, maxLength); 
       modify = true; 
      } 
      if (modify) { 
       txtSeuil.setText(newText); 
      } 
      validating = false; 
     } 
    } 
}); 
Смежные вопросы