2015-03-01 2 views
1

У меня есть JTextField, для которого я переопределил документ, так что я могу помешать пользователю ввести некоторые символы. Как это работает мой расширение документа получает Regex в своем конструкторе, затем проверяет все, что вводит пользователь против Regex:JTextField с приложением regex не будет принимать значение до тех пор, пока не будет применен документ

public class ValidDocument extends PlainDocument 
{ 
    private String regex; 

    public ValidDocument(String regex) 
    { 
     this.regex = regex; 
    } 

    @Override 
    public void insertString(int offs, String str, AttributeSet a) 
    { 
     if(str == null) return; 

     try 
     { 
      if((this.getText(0, getLength()) + str).matches(regex)) 
       super.insertString(offs, str, a); 
     } 
     catch(BadLocationException ble) 
     { 
      System.out.println("Came across a BadLocationException"); 
     } 
    } 
} 

у меня была проблема однако, когда JTextField, что я хотел, чтобы отобразить только один действительный поплавок/double numbers in не отображает его начальное значение. Код, который я использовал, приведен ниже:

float value = 25.0f; 
JTextField textField = new JTextField("" + value); 
textField.setDocument(new ValidDocument("^(\\-)?\\d*(\\.)?\\d*$")); 

Так отображается JTextField, но начального значения не было. Я попытался ввести 25.0 в поле, и он согласился с тем, что я изначально ожидал. После немного начинки, я попытался добавить:

textField.setText("" + value); 

И это отобразило значение. Мне пришло в голову, что он может принять все, что я пытался поставить в SetText(), так что я добавил буквенные символы к нему:

textField.setText("as" + value); 

Как я и подозревал, он включал буквенные символы, даже если Regex должен был предотвратить что. Поэтому я считаю, что при использовании этой функции документ обходит.

Может ли кто-нибудь пролить свет на то, почему применение ValidDocument в моем JTextField удаляет текст, который я разместил в конструкторе текстового поля? У меня есть другие JTextFields с менее ограничительным Regex, которые все еще отображают значение, заданное в конструкторе. И почему это будет переопределять значение, переданное в конструктор, но не тот, который передается в setText()?

+0

запрещает пользователю вводить некоторые символы. == DocumentFilter – mKorbel

+0

, где JTextField, который я хотел отображать только действительные числа float/double, не отображал его начальное значение. ==, а затем, чтобы проанализировать вход пользователей в Float/Double, вопрос в том, зачем беспокоиться с простым JTextField, не является JFormattedTextField лучше, чем ... (для стандартного ввода) – mKorbel

+0

Хм ... Теперь я посмотрю на JFormattedTextField. Спасибо за направление – Stevo

ответ

1

Не используйте PlainDocument, используйте DocumentFilter, это то, для чего оно предназначено. Метод, который вы пытаетесь использовать уже устарели в течение более чем 10 лет, к примеру ...

public class PatternFilter extends DocumentFilter { 

    // Useful for every kind of input validation ! 
    // this is the insert pattern 
    // The pattern must contain all subpatterns so we can enter characters into a text component ! 
    private Pattern pattern; 

    public PatternFilter(String pat) { 
     pattern = Pattern.compile(pat); 
    } 

    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) 
      throws BadLocationException { 

     String newStr = fb.getDocument().getText(0, fb.getDocument().getLength()) + string; 
     Matcher m = pattern.matcher(newStr); 
     if (m.matches()) { 
      super.insertString(fb, offset, string, attr); 
     } else { 
     } 
    } 

    public void replace(FilterBypass fb, int offset, 
         int length, String string, AttributeSet attr) throws 
      BadLocationException { 

     if (length > 0) fb.remove(offset, length); 
     insertString(fb, offset, string, attr); 
    } 
} 

Который приходит от этого DocumentFilter Examples

Взгляните на Implementing a Document Filter для более подробной информации

Если вам не нужна фильтрация в реальном времени, другим вариантом будет использование JFormattedTextField или JSpinner. См. How to Use Formatted Text Fields и How to Use Spinners для получения более подробной информации.

+0

Хахаха, я только правильно использовал Свинг в прошлом году, но мне все же удается подобрать привычку, которая полностью устарела! Фильтрация в реальном времени идеальна, поэтому в итоге этот метод прошел.На самом деле я не помню, почему я решил, что способ, которым я пользовался, - это путь, или как я на самом деле пришел к такому выводу, но приятно знать, что есть более простые способы делать вещи. – Stevo

+0

@Stevo Я просто проверил тест, используя фильтр сверху с вашим регулярным выражением, и, похоже, он работает правильно для меня ... – MadProgrammer

+0

Фантастично, большое вам спасибо за это! – Stevo

Смежные вопросы