Получите JFormattedText действительное значение как можно скорее

Я хочу, чтобы текстовое поле позволяло пользователю вводить дату по определенному шаблону, и я хочу, чтобы эта дата возвращалась, как только она будет напечатана и действительна, то есть не дожидаясь, пока пользователь нажмет клавишу возврата в текстовом поле, чтобы обработать ее. Также я добавляю визуальные подсказки, является ли введенная дата правильной (изменение цвета фона текстового поля).

Вот пример SSC-не-правильный

package gui.date;

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

public class DateEditor extends JFormattedTextField
{

    public DateEditor()
    {
        this(null, null);
    }

    public DateEditor(Date d)
    {
        this(d, null);
    }

    public DateEditor(Date d, String pattern)
    {
        super(new SimpleDateFormat(pattern));
        setValue(d);
        setFocusLostBehavior(JFormattedTextField.PERSIST);

        final Color origBgdColor = getBackground();
        final Color wrongInputColor = new Color(0.8f, .0f, .0f);
        final Color missingInputColor = new Color(1f, 1f, .65f);
        if(d == null)
        {
            setColumns(10);
            setBackground(missingInputColor);
        }
        addCaretListener(new CaretListener()
        {

            @Override
            public void caretUpdate(CaretEvent e)
            {
                if(isEditValid())
                {
                    try
                    {
                        setBackground(origBgdColor);
                        commitEdit();
                    }
                    catch(ParseException ex)
                    {
                        ex.printStackTrace();
                    }
                }
                else
                {
                    try
                    {
                        String text = getText();
                        if(text.isEmpty())
                            setBackground(missingInputColor);
                        else
                            setBackground(wrongInputColor);
                    }
                    catch(NullPointerException ex)
                    {
                        setBackground(missingInputColor);
                    }
                }
            }
        });
    }

    public Date getDate()
    {
        return (Date)getValue();
    }

    public void setDate(Date d)
    {
        setValue(d);
    }

    public static void main(String args[])
    {
        SwingUtilities.invokeLater(new Runnable()
        {

            @Override
            public void run()
            {
                final Date[] date = new Date[] { null }; // the date entered by the user should be filled here as soon as it is a valid date
                final String pattern = "dd/MM/YYYY";
                final SimpleDateFormat fm = new SimpleDateFormat(pattern);

                JButton b = new JButton(new AbstractAction("Print value")
                {

                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        try
                        {
                            System.out.println(fm.format(date[0]));
                        }
                        catch(NullPointerException ex)
                        {
                            System.out.println("No date set yet");
                        }
                    }
                });
                final DateEditor d = new DateEditor(null, pattern);
                d.addPropertyChangeListener("value", new PropertyChangeListener()
                {

                    @Override
                    public void propertyChange(PropertyChangeEvent evt)
                    {
                        if(evt.getSource().equals(d))
                        {
                            date[0] = d.getDate();
                        }
                    }
                });
                final JFrame f = new JFrame(getClass().getName());
                Container c = f.getContentPane();
                c.setLayout(new FlowLayout());
                c.add(b);
                c.add(d);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

Если вы попробуете это, вы увидите несколько ошибок: 1/ Заданный шаблон, кажется, не применяется FormattedText, так что введенная действительная дата может быть преобразована в другую дату, когда я нажимаю ввод

2/ ParseException продолжает вызываться при вызове commitEdit в CaretListener, несмотря на то, что я сначала проверяю isEditValid()!

Спасибо за вашу помощь.

0 ответов

Другие вопросы по тегам