Java JFormattedTextField

У меня есть JFormattedTextField с DateFormat. формат "ддММгг". Этот формат обеспечивает быстрый ввод. При потере фокуса я хочу, чтобы текст в поле изменился на LocalDate, так как его легче читать:

Ввод: "200295". преобразование в LocalDate с помощью getValue() дает LocalDate от 20 февраля 1995 года. Это все хорошо, для текста "1995-02-25" (LocalDate.toString()).

Когда поле теряет фокус, я хочу, чтобы текст, отображаемый в поле, изменился на LocalDate.toString() без изменения фактического значения поля с 200295/20 февраля 1995 года.

Есть ли способ наложить текст на поле вместо изменения его значения/текста?

sscce того, что я думал до сих пор:

основной класс:

public class FormatDateTest {

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


        public void run() {
            new TheFrame();
        }


    });
}
}

Класс кадра:

public class TheFrame extends JFrame{

JPanel panel;
JPanel textPanel;

JFormattedTextField dateField;
JButton button;
JTextArea textArea;

DateFormat format;

public TheFrame() {

    button = new JButton("click");

    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {

            //temporarily crates a date to be converted.
            Date date = (Date) dateField.getValue();
            LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            // sends the different values of the textarea
            textArea.append("The value: " + dateField.getValue() + "\n");
            textArea.append("the Date: " + date.toString() + "\n");
            textArea.append("the LocalDate: " + localDate.toString() + "\n");


        }
    });


    //Sets the text to the localDate for prettyness
    button.addFocusListener(new FocusListener() {

        @Override
        public void focusLost(FocusEvent arg0) {
            Date date = (Date) dateField.getValue();
            LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            dateField.setText(localDate.toString());
        }

        @Override
        public void focusGained(FocusEvent arg0) {
            dateField.setText("");

        }
    });


    textArea = new JTextArea();

    panel = new JPanel();
    textPanel = new JPanel();

    panel.setLayout(new BorderLayout());
    textPanel.setLayout(new BorderLayout());

    //datefield and format
    format = new SimpleDateFormat("ddMMyy");
    dateField = new JFormattedTextField(format);


    textPanel.add(textArea,BorderLayout.CENTER);
    panel.add(dateField,BorderLayout.NORTH);
    panel.add(button, BorderLayout.CENTER);
    add(panel,BorderLayout.NORTH);
    add(textPanel,BorderLayout.CENTER);

    pack();
    setSize(400, 300);
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

}
}

person Seagulltown    schedule 30.08.2015    source источник


Ответы (1)


Используйте JPanel с CardLayout. Поместите в него два компонента - поле ввода и правильно отформатированное (я предполагаю, что JTextField подойдет). При фокусе на любом из них выведите отформатированное поле на передний план (используя методы CardLayout) и позвольте пользователю вводить свои данные. При потере фокуса обработайте значение (не забывайте об ошибках!) и, если синтаксический анализ пройдет успешно, поместите правильно отформатированное значение в JTextField и выведите его на передний план.

-- ОБНОВЛЕНИЕ на основе замечания --

Простое решение: используйте JLabel вместо JTextField для отформатированной части. Только не забудьте позвонить setFocusable(true).

Еще легче: подкласс JTextField. Переопределите paintComponent таким образом, чтобы: a) Когда компонент был сфокусирован, делегируйте рисование super. б) Когда вы не сфокусированы, нарисуйте правильно отформатированный текст самостоятельно.

person Michael Bar-Sinai    schedule 30.08.2015
comment
Это был бы экстремальный обходной путь, так как на панели гораздо больше полей, для которых я хотел бы это. - person Seagulltown; 31.08.2015
comment
Он работает достаточно хорошо, пока пользователь не вернется к текстовому полю. Проблема сводится к следующему: в focusGained возвращаем строку LocalDate обратно к формату ввода (ddMMyy) и устанавливаем ее как текст. - person Seagulltown; 01.09.2015
comment
Добавлены более легкие решения. - person Michael Bar-Sinai; 01.09.2015
comment
@Seagulltown - это сработает, но вы сказали, что вместо того, чтобы изменить его значение / текст .... - person Michael Bar-Sinai; 01.09.2015
comment
Я попробую ваше обновленное решение завтра. звучит многообещающе. - person Seagulltown; 01.09.2015