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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Калькулятор выражения в JFormattedTextField, Получение результата в getValue() 
:(
    Опции темы
Connie
Дата 15.11.2008, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Необходимо позволять пользователю вводить выражение, примерно так:
125+63-89,6

Потом вычислять результат.

Я реализовал это в InputVerifier'е
Код

public boolean verify(JComponent input) {
             if (input instanceof JFormattedTextField) {
             JFormattedTextField ftf = (JFormattedTextField)input;
             JFormattedTextField.AbstractFormatter formatter = ftf.getFormatter();
             if (formatter != null) {
                 String text = ftf.getText();
                 //Если calc - true то нужно делать вычисление
                 //Если false то это обычное поле и мы просто проверяем число,
                 //что бы оно не было отрицательным
                 if (calc) { text = Calc(text,formatter); 
                    try{
                    ftf.setValue(((Number)formatter.stringToValue(text)).floatValue());
                    }catch (ParseException pe) {}
                      //ftf.setText(text);
                 }
                 try {
                      float vl = ((Number)formatter.stringToValue(text)).floatValue();
                      if (vl<0.0f) ftf.setText(formatter.valueToString(0.0f));
                      return true;
                  } catch (ParseException pe) {
                      return false;
                  }
              }
          }
          return true;
  }

Функцию Calc приводить не буду, она работает.

Выглядит это так
user posted image
После того как нажимаем TAB или нажимаем мышкой на Ok все работает, в JFormattedTextField подставляется вычисленное значение, но это и правильно, т.к. фокус покидает это поле, либо переходит к другому полю ввода, либо на какую либо кнопку.

Однако я хотел бы использовать эту возможность и в таблице.

Для ввода числа я написал FloatEditor для float чисел в таблице
Код

public class FloatEditor extends AbstractCellEditor
implements TableCellEditor, PropertyChangeListener {
    
    private JFormattedTextField fld;
    private static final String VALUE_CHANGED = "value";
    
    public FloatEditor(ProgramSettings settings){ 
        super();
        
        fld = new JFormattedTextField(new DecimalFormat("0.0"));
        fld.setFont(settings.getFont(fld.getFont()));//тут меняем размер шрифта
        
        fld.setHorizontalAlignment(JFormattedTextField.RIGHT);
        fld.setFocusLostBehavior(JFormattedTextField.PERSIST);
        fld.setBorder(BorderFactory.createEmptyBorder());
        
        fld.setInputVerifier(new PositiveFloatVerifier(true));//вот тут устанавливаем проверку ввода
        //fld.addFocusListener(new MyFocusListener());
        fld.addMouseListener(new MyMouseAdapter());//выделение всей ясейки при попадании в нее фокуса
           
        fld.addPropertyChangeListener(VALUE_CHANGED, this);
    }
    
    public Object getCellEditorValue(){
        //fld.setText(fld.getText());  
        //System.out.println("this1 "+fld.getValue());
        return fld.getValue();
    }   
   
    public Component getTableCellEditorComponent(JTable table,
                                      Object value,
                                      boolean isSelected,
                                      int row,
                                      int column){
        System.out.println("this "+value);
        fld.setValue(((Number)value).doubleValue());
        fld.selectAll();
        
        return fld;
    }
    
    public void propertyChange(PropertyChangeEvent e) {
        //Установили новое значение, т.е. нажали Enter        
       if (e.getPropertyName().equals(VALUE_CHANGED)){
             //JFormattedTextField ftf = (JFormattedTextField)e.getSource();
             
             //ftf.setValue(ftf.getValue());
            // if (ftf.getInputVerifier().verify(ftf)) {//doSomeThing();
                fireEditingStopped();
             //}
       }
    } 

Так вот проблема в следующем, в таблице написать можно
user posted image
И если мышкой перевести фокус в другое место программы, то значение будет вычислено, и оно будет записано в таблицу
Код

@Override
  public void setValueAt(Object value, int row, int col){
      if (col==1){
        System.out.println(""+value);
        ProductInMenu prod = (ProductInMenu)products.get(row);
        prod.setWeight(((Number)value).floatValue());
        mgr.updateProd(prod);
      
        fireTableRowsUpdated(row,row);
      }
  }

Это код модели таблицы

А вот если нажать Enter находясь в таблице, то в ячейку будет записано только первая часть выражения, т.е. написав там 85+63 и нажав Enter в таблицу будет записано только 85.

Вот как то так.

Может как то передавать фокус после нажатия enter, а потом его возвращать назад?


Похожее поведени, точнее оно и связано с этим у InputVerifier'а 
Если находясь в JFormattedTextField нажимать enter, то корректировки значения не происходит, хотя обратобка начинается, т.е. событие propertyChanged возбуждается, а вот если покинуть это поле, т.е. оно потеряет фокус, то и propertyChanged  произойдет и InputVerifier сработает.

Это сообщение отредактировал(а) Connie - 15.11.2008, 16:22
PM MAIL WWW   Вверх
Connie
Дата 15.11.2008, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Спросишь и мозги проясняются smile

сделал так, вычисления из строки выделил в отдельный класс Calculator

В FloatEditor изменил работу функции
Код

public void propertyChange(PropertyChangeEvent e) {
        //Установили новое значение, т.е. нажали Enter        
       if (e.getPropertyName().equals(VALUE_CHANGED)){
             JFormattedTextField ftf = (JFormattedTextField)e.getSource();
             ftf.setText(calculator.Calc(ftf.getText(), ftf.getFormatter()));
             try{
                    ftf.setValue(((Number)ftf.getFormatter()
                            .stringToValue(ftf.getText())).floatValue());
             }catch (ParseException pe) {}
             System.out.println("Text data "+ftf.getText());
             System.out.println("Number data "+ftf.getValue());
             
             
             //ftf.setValue(ftf.getValue());
            // if (ftf.getInputVerifier().verify(ftf)) {//doSomeThing();
                fireEditingStopped();
             //}
       }
    } 

PM MAIL WWW   Вверх
Connie
Дата 16.11.2008, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Приведу и класс Calculator, может кому сгодиться
Код

import javax.swing.JFormattedTextField;
import java.text.ParseException;
import java.text.DecimalFormatSymbols;

public class Calculator {
    private DecimalFormatSymbols symbols;
    
    public Calculator(){
        symbols = new DecimalFormatSymbols();
    }
public String Calc(String textIn, 
              JFormattedTextField.AbstractFormatter formatter){
          String res = textIn;
          textIn = textIn.trim();
          if (textIn.length()>1){
            if (checkCorrect(textIn)){
                textIn = checkOneComma(textIn,symbols.getDecimalSeparator());
                textIn = checkOneComma(textIn,'+');
                textIn = checkOneComma(textIn,'-');
                float sum = 0;
                String buf = "0";
                float sign = 1;
                int i = 0;
                float vl = 0;
                while (i<textIn.length())
                {
                    if ((textIn.charAt(i)!='+')&&(textIn.charAt(i)!='-'))
                        buf = buf + textIn.charAt(i);
                    else
                    {
                        vl = 0;
                        try {
                            vl = ((Number)formatter.stringToValue(buf)).floatValue();
                        } catch (ParseException pe) {}
                        
                        sum = sum + sign *  vl;
                        buf = "0";
                        switch (textIn.charAt(i))
                        {   
                            case '+': sign = 1; break;
                            case '-': sign = -1;
                        }
                    }
                    i++;
                }
                if (buf.length()>1)
                {
                    vl = 0;
                    try {
                        vl = ((Number)formatter.stringToValue(buf)).floatValue();
                    } catch (ParseException pe) {}
                    sum = sum + sign * vl;
                }
                System.out.println("Sum:"+sum);
                try{
                    return formatter.valueToString(sum);
                } catch (ParseException pe) {}
                
            }
          }
          return res;//если не получается обработка, то возвращаем то, что взяли
  }
      
  public String checkOneComma(String InStr, char ch)
  {
        if (InStr.length()==0) return "0";
        boolean conj = false;
        int i=0;
        StringBuilder stBl = new StringBuilder(InStr);
        while (i<stBl.length() )
        { 
                if (stBl.charAt(i)==ch){
                  if (conj) 
                  { stBl = stBl.deleteCharAt(i); i--; }
                  else conj = true;
                } else { conj=false;}
                i++;
        }
        if ((stBl.length()==1)&&(conj)) stBl = new StringBuilder("0");
        return stBl.toString();
  }
    
  public boolean checkCorrect(String StrToCheck )
  {
        int i=0;
                
        StringBuilder stBl = new StringBuilder(StrToCheck);
        while (i<stBl.length() && stBl.length()>0)
        {
            char ch = stBl.charAt(i);    
            if ( ( ch>='0' && ch<='9')||
                (ch==symbols.getDecimalSeparator())||
                (ch=='+')||(ch=='-'))  i++;
                else stBl = stBl.deleteCharAt(i);
        }

        //String t = stBl.toString();
        
        if (stBl.length()==0)  return false;
        else return true;
  }
}

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

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

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


 




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


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

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