Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Ввод времени


Автор: Connie 1.12.2008, 11:42
Мне в программе нужно поле для ввода времени, примерно такое
[hh:mm] поискал в сети и не нашел ничего такого. Полно компонентов для ввода даты и времени, а такого простого нет. Т.е. мне нужен editor для ячейки таблицы, рендер я уже сделал.

Есть мысль как самому такой написать. В этом нет ничего сложного. Но смущает то, что подобное уже должно быть реализовано. 

Киньте пожалуйста ссылкой.

Если нет, то напишу и выложу.

Думаю его сделать так: 
внизу панелька, на ней три элемента: первый JFormattedTextField с InputVerifier'ом, потом JLabel(":"), потом еще один JFormattedTextField с InputVerifier'ом на вход long от Time или Time, ну и на выход тоже самое.

Вроде такая простая, очевидная вещь, а я найти не могу :(

Автор: Connie 1.12.2008, 15:38
сделал след образом, коряво как то 

Это класс для ввода
Код

public class TimeFormatter extends JFormattedTextField{
    private Time time;
    public TimeFormatter(JFormattedTextField.AbstractFormatter formatter){
        super(formatter);
    }
    
    
    @Override
    public Object getValue(){
        String st = this.getText();
        String [] strs;
        if (st.length()==0) st = "00:00";
        strs = st.split(":");
        int h = Integer.parseInt(strs[0]);
        int m = Integer.parseInt(strs[1]);
        time =  new Time(h,m,0);
        return time;
    }
}


Это InputVerifier
Код

public class TimeVerifier extends InputVerifier {
     public boolean verify(JComponent input) {
         if (input instanceof JFormattedTextField) {
             JFormattedTextField ftf = (JFormattedTextField)input;
             //TimeFormatter.AbstractFormatter formatter = ftf.getFormatter();
             
             String [] strs = ftf.getText().split(":");
             int h = Integer.parseInt(strs[0]);
             int m = Integer.parseInt(strs[1]);
             if (h>23) return false;
             if (m>59) return false;
             
          }
          return true;
      }
     @Override 
     public boolean shouldYieldFocus(JComponent input) {
          return verify(input);
      }
  }


А вот так добавляем новое поле
Код

MaskFormatter formatter = null;
        try{
            formatter = new MaskFormatter("##:##");
        } catch (Exception e){formatter = new MaskFormatter();};
        
        formatter.setValidCharacters("0123456789");
        formatter.setPlaceholderCharacter('0');
        
        TimeFormatter        fld = new TimeFormatter(formatter);
        fld.setInputVerifier(new TimeVerifier())

Автор: fixxer 2.12.2008, 12:34
А почему бы просто не cделать new JFormattedTextField(new SimpleDateFormat("HH:mm")) ?

Автор: LSD 2.12.2008, 13:33
Ну или не использовать JSpinner.

Автор: Connie 2.12.2008, 17:28
fixxer, 
Цитата
А почему бы просто не cделать new JFormattedTextField(new SimpleDateFormat("HH:mm")) ? 

в этом случае все отображается красиво, но ввод не очень, дело в том, тогда пользователь попадая в такое поле теряет формат, т.е. может ввести так: 1456::::45654::: бла бла бла, конечно это не будет принято, но лучше такого просто не допускать
Этим лучше maskFormatter, но тогда возвращаемся к моему варианту.


LSD, а можно по подробнее, что Вы имели ввиду, я в джава не силен :(

Автор: fixxer 2.12.2008, 18:08
Тогда хотя бы для валидации и преобразования используйте SimpleDateFormat. А не этот ахтунг с рукопашным разбором строки.

Автор: LSD 2.12.2008, 18:48
http://java.sun.com/docs/books/tutorial/uiswing/components/spinner.html

Автор: Connie 7.12.2008, 18:52
Переделал след. образом, стало красивее, но остался один вопрос
Код

public class TimeTextField extends JFormattedTextField{
    //private Time time;
    SimpleDateFormat format;//=new SimpleDateFormat("HH:mm");

    private final static long ZERO = -10800000;
    private final static long EIGHT_O_CLOCK = 18000000;

    public TimeTextField(JFormattedTextField.AbstractFormatter formatter){
        super(formatter);
        
    }


    @Override
    public Object getValue(){
        String st = this.getText();
        if (format==null){
            format = new SimpleDateFormat("HH:mm");
            format.setLenient(false);
        }
        Date dt;
        try{
            dt = format.parse(st);
        } catch (ParseException ex){
            dt = new Date(ZERO);
        }
        return new Time(dt.getTime());
        //return dt;// так не работает
    }
    @Override
    public void setValue(Object time){//get Time
        //this.time = (Date)time;
        if (format==null){
            format = new SimpleDateFormat("HH:mm");
            format.setLenient(false);
        }
        //String buf = ;

        this.setText(format.format((Date)time));
    }
}
 Вот если в этом классе заменить Time на Date из пакета java.util.Date, то работать перестает, поле появляется, но без маски и ввести ничего не удается, в чем причина, я так и не понял. Исключений не герерируется, 

Вот так проверяю
Код

public class TimeVerifier extends InputVerifier {
     public boolean verify(JComponent input) {
         if (input instanceof JFormattedTextField) {
             JFormattedTextField ftf = (JFormattedTextField)input;
             //TimeFormatter.AbstractFormatter formatter = ftf.getFormatter();
             String st = ftf.getText();
             SimpleDateFormat format = new SimpleDateFormat("HH:mm");
             format.setLenient(false);//Это нужно, что бы нельзя было ввести 77:88 иначе просто пересчитывалось
             try{
                format.parse(st);
             } catch (ParseException ex){
                return false;
             }
             
          }
          return true;
      }
     @Override
     public boolean shouldYieldFocus(JComponent input) {
          return verify(input);
      }
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)