Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> JFormattedTextField и DocumentFilter, можно как-то скрестить? 
V
    Опции темы
carper
Дата 14.12.2006, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 4
Всего: 8



До сих пор использовал JTextField (там проблем нет), теперь дернула нелегкая попытаться использовать
JFormattedTextField для такой задачи:

Надо динамически отслеживать ввод каждого символа в поле, и, в зависимости от некоего расчета,
давать пользователю дальше вводить  строку или нет.

Т.е. мне НЕ надо проверять значения ПОСЛЕ выхода из поля, а именно во время ввода каждого символа.


Покопавшись, я обнаружил, что setDocumentFilter фильтр для JFormattedTextField  не действует (из исходного кода понятно почему).
Задание своего форматера, с перекрыванием getDocumentFilter() и возвратом своего фильтра, осуществляющего нужные мне действия, ничего не дает. 
Может я фильтр неграмотно назначаю?
   
Код

  DecFormatterWithDefaultFilter fltr= new DecFormatterWithDefaultFilter(); //мой фильтр
  setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(fltr))); //назначаем фильтр   нашему наследнику JFormattedTextField

   class DecFormatterWithDefaultFilter extends DecimalFormat {
       .....
        protected DocumentFilter getDocumentFilter()  {
           return  new MySelf_TextFilter();
        }

   }

Что-то теги кода не срабатывают? smile

Не хотелось бы тут приводить тоны путаного кода, поэтому у меня простой вопрос:
Можно ли динамически проверять вводимые символы (ну это-то можно, хотя бы через DocumentListener), но не просто проверять, а предпринимать какие-то изменения в JFormattedTextField, например, подменить один символ другим, или просто запретить его ввод и т.п.?
И, главное, как это сделать грамотно?
PM MAIL   Вверх
w1nd
Дата 14.12.2006, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 23
Всего: 54



А вы не приводите тонны кода, сделайте небольшой пример. Я делал свой DocumentFilter в своем форматёре для JFormattedTextField - все отлично работает.

Это сообщение отредактировал(а) w1nd - 14.12.2006, 23:27


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
carper
Дата 15.12.2006, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 4
Всего: 8



Цитата(w1nd @ 14.12.2006,  23:26)
А вы не приводите тонны кода, сделайте небольшой пример. Я делал свой DocumentFilter в своем форматёре для JFormattedTextField - все отлично работает.

OK.
Попробую, ну вроде как мысль иллюстрирует.

Итак, сперва простейший фильтр.
Код

package ttt;

import java.awt.Toolkit;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

/**
 *  пытается запретить пользователю вводить двойку в строку и все.
 */
public class TestFilter extends  DocumentFilter {
  private AbstractDocument _doc;
  public TestFilter (AbstractDocument docArg) {
    _doc= docArg; //Запомним ссылку на документ
  }
      
      public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
        fb.remove(offset, length); //Здесь ничего не трогаем- удаляйте на здоровье
    }
      
      public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
        String newStr= _doc.getText(0, _doc.getLength());
        newStr= newStr.substring(0,offset) + string+ newStr.substring(offset+1, _doc.getLength());
      /* Проверим строку на корректность, в примере мы запретим вводить туда, ну скажем 
       * цифру 2, (помним, это ПРИМЕР - на практике там не простая проверка) */
        if(isStringCorrect(newStr)) {
          fb.insertString(offset, string, attr);
        } else {
         beep(); 
        }//if
      }
      public void replace(FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
        String newStr= _doc.getText(0, _doc.getLength());
        newStr= newStr.substring(0,offset) + string+ newStr.substring(offset+length, _doc.getLength());
        if(isStringCorrect(newStr)) {
          fb.replace(offset, length, string, attr);
        } else {
         beep(); 
        }//if
        
      }
     
      /**
       * @param stringArg - строка для проверки
       * @return - true, если строка удовлетворяет нашему условию, т.е. не содержит '2'
       */
      protected boolean isStringCorrect(String strToTestArg) {
        return  !strToTestArg.contains("2");
      }
      
      
      private final void beep() {    Toolkit.getDefaultToolkit().beep();  }
        
}




Теперь не менее простой форматтер, скорее всего, уже здесь я допускаю
какую-то глупую ошибку. 
Вроде как я так понял у SUN, что назначение фильтра для JFormattedTextField идет
через переопределение  getDocumentFilter(), но это не работает.  smile

Код

ackage ttt;

import java.text.DecimalFormat;
import javax.swing.text.AbstractDocument;
import javax.swing.text.DocumentFilter;

/**
 * Все, что нам надо от этого класса, так это попытаться хоть как-то
 * впихнуть фильтр для ДИНАМИЧЕСКОЙ проверки вводимого значения, т.е.
 * пользователь вводит двойку, а она не вводится и раздается гудок динамика.
 */
public class TestDecimalFormatter extends DecimalFormat {
    private static final long serialVersionUID= 1L;
    private TestFilter _testFilter; 
     
    public TestDecimalFormatter(AbstractDocument docArg) {
     super();
     _testFilter= new TestFilter(docArg); 
        //Задаем поведение отличное от стандартного, чтобы убедиться, что сам форматер
    //вообще используется - и убеждаемся, что таки да, т.е. цифры начинают группироваться по 4, а
        //не по 3, как это задано по-умолчанию
     this.setGroupingSize(4); 
    }
     
     /**
      * Собственно на это метод у меня и была вся надежда. :(
      */
   protected DocumentFilter getDocumentFilter() {
      return _testFilter;
   }

 }




Собственно поле, отличающееся от стандартного только попыткой задать свой форматтер,
сама попытка срабатывает, т.е. можно в форматторе, скажем задать другой разделитель групп и это
будет учтено, а вот фильтр вообще не работает!

Код

package ttt;

import java.text.Format;
import javax.swing.JFormattedTextField;
import javax.swing.text.AbstractDocument;
import javax.swing.text.DefaultFormatterFactory;
import javax.swing.text.NumberFormatter;


//Для этого-то поля и впихнем свой фильтр
public class TestJFormattedTextField  extends JFormattedTextField {
  private static final long serialVersionUID= 1L;
      
  //Конструкторы ничем не отличаются от таковых в JFormattedTextField
    public TestJFormattedTextField () {
      super(); 
      init();
    }
    
    public TestJFormattedTextField (Object value) {
      super(value);    init();
    }
    
    public TestJFormattedTextField(AbstractFormatterFactory factory, Object currentValue) {
      super(factory, currentValue);    init();
    }
     
    public TestJFormattedTextField (Format format) {
        super(format);    init();
    }

    private void init() {
        TestDecimalFormatter df= new TestDecimalFormatter((AbstractDocument) this.getDocument());
        setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(df)));
    }
}    




Класс для тестирования всего получившегося:
Код

package ttt;

import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.text.AbstractDocument;


public class TestGUI extends JFrame {
  private static final long serialVersionUID= 1L;
  public static void main(String[] arg) {
    TestGUI testGUI= new TestGUI();
    Container pane= testGUI.getContentPane();
        pane.setLayout(new FlowLayout());
        
    //Первым добавим обычное JTextField чтобы проверить, что наш фильтр
        //вообще работает - и он таки работает отлично.
        JTextField fieldGood= new JTextField("114343434",9);
        AbstractDocument doc1 = (AbstractDocument)fieldGood.getDocument();
        doc1.setDocumentFilter(new TestFilter(doc1));
        pane.add(new JLabel("It works fine"));
        pane.add(fieldGood);
        
        //Теперь добавим наше JFormattedTextField и убедимся, что фильтр не работает
        TestJFormattedTextField fieldBad= new TestJFormattedTextField();
        fieldBad.setColumns(25);
        pane.add(new JLabel("It does not look at any my filter!"));
        pane.add(fieldBad);
        testGUI.setDefaultCloseOperation(EXIT_ON_CLOSE);
        testGUI.setVisible(true);
        testGUI.pack();
  }
  
}


PM MAIL   Вверх
carper
Дата 15.12.2006, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 227
Регистрация: 2.3.2005

Репутация: 4
Всего: 8



Все, на будущее  если не выспаться и назвать форматтером формат, то формат форматтером от этого не станет.

Прошу прощение за дурацкую ошибку.
PM MAIL   Вверх
w1nd
Дата 16.12.2006, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вертилятор
***


Профиль
Группа: Завсегдатай
Сообщений: 1077
Регистрация: 22.3.2006
Где: Москва

Репутация: 23
Всего: 54



Цитата(carper @ 15.12.2006,  16:42)
Все, на будущее  если не выспаться и назвать форматтером формат, то формат форматтером от этого не станет.

Прошу прощение за дурацкую ошибку.

Хороший способ понять что-либо - попытаться объяснить другому smile 


--------------------
user posted imageuser posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.1105 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.