Seagulltown
Seagulltown

Reputation: 31

java JFormattedTextField

I have a JFormattedTextField with a DateFormat. the format is "ddMMyy". This format allows quick input.On focus lost i want the text in the field to change to LocalDate as that is easier to read:

Input: "200295". converting to LocalDate with getValue() gives the LocalDate of 20. February 1995. this is all well and good, to text that is "1995-02-25" (LocalDate.toString()).

When the field loses focus, i want the text displayed in the field to change into the LocalDate.toString() without the actual value of the field to change from 200295/ 20. feb 1995.

Is there any way to make a text overlay the field instead of changing the value/text of it?

sscce of what i have been thinking so far:

main class:

public class FormatDateTest {

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


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


    });
}
}

Frame class:

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);

}
}

Upvotes: 0

Views: 568

Answers (1)

Michael Bar-Sinai
Michael Bar-Sinai

Reputation: 2739

Use a JPanel with a CardLayout. Put two components in it - the input field and the properly formatted one (I assume a JTextField would do). On focus to any of them, bring the formatted field to front (using methods on the CardLayout), and let the user input her data. On focus lost, process the value (remember to deal with errors!) and, if parsing goes well, put the properly formatted value in the JTextField and bring it to the front.

-- UPDATE based on remark --

Lightweight solution: Use a JLabel instead of a JTextField for the formatted part. Just remember to call setFocusable(true).

Even Lighter: Subclass JTextField. Override paintComponent such that: a) When the component is focused, delegate the drawing to super. b) When not focused, paint the properly formatted text yourself.

Upvotes: 1

Related Questions